Version 6.4.0.3, tag libreoffice-6.4.0.3
[LibreOffice.git] / ucb / source / sorter / sortresult.cxx
blob6069808ccff92e77d9a8cdcf948fa648380ee9a8
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 .
21 #include <vector>
22 #include "sortresult.hxx"
23 #include <com/sun/star/sdbc/DataType.hpp>
24 #include <com/sun/star/sdbc/SQLException.hpp>
25 #include <com/sun/star/sdbc/XResultSetMetaDataSupplier.hpp>
26 #include <com/sun/star/ucb/ListActionType.hpp>
27 #include <com/sun/star/ucb/XAnyCompare.hpp>
28 #include <cppuhelper/implbase.hxx>
29 #include <cppuhelper/interfacecontainer.hxx>
30 #include <comphelper/interfacecontainer2.hxx>
31 #include <cppuhelper/supportsservice.hxx>
32 #include <osl/diagnose.h>
33 #include <memory>
35 using namespace com::sun::star::beans;
36 using namespace com::sun::star::container;
37 using namespace com::sun::star::io;
38 using namespace com::sun::star::lang;
39 using namespace com::sun::star::sdbc;
40 using namespace com::sun::star::ucb;
41 using namespace com::sun::star::uno;
42 using namespace com::sun::star::util;
43 using namespace comphelper;
44 using namespace cppu;
47 // The mutex to synchronize access to containers.
48 static osl::Mutex& getContainerMutex()
50 static osl::Mutex ourMutex;
52 return ourMutex;
56 struct SortInfo
58 bool mbUseOwnCompare;
59 bool mbAscending;
60 bool mbCaseSensitive;
61 sal_Int32 mnColumn;
62 sal_Int32 mnType;
63 SortInfo* mpNext;
64 Reference < XAnyCompare > mxCompareFunction;
68 struct SortListData
70 bool mbModified;
71 sal_IntPtr mnCurPos;
72 sal_IntPtr const mnOldPos;
74 explicit SortListData( sal_IntPtr nPos );
78 // class SRSPropertySetInfo.
81 class SRSPropertySetInfo : public cppu::WeakImplHelper <
82 XPropertySetInfo >
84 Property maProps[2];
86 private:
88 public:
89 SRSPropertySetInfo();
91 // XPropertySetInfo
92 virtual Sequence< Property > SAL_CALL getProperties() override;
93 virtual Property SAL_CALL getPropertyByName( const OUString& aName ) override;
94 virtual sal_Bool SAL_CALL hasPropertyByName( const OUString& Name ) override;
97 typedef OMultiTypeInterfaceContainerHelperVar<OUString>
98 PropertyChangeListenerContainer_Impl;
100 class PropertyChangeListeners_Impl : public PropertyChangeListenerContainer_Impl
102 public:
103 PropertyChangeListeners_Impl()
104 : PropertyChangeListenerContainer_Impl( getContainerMutex() ) {}
108 SortedResultSet::SortedResultSet( Reference< XResultSet > const & aResult )
110 mpDisposeEventListeners = nullptr;
111 mpPropChangeListeners = nullptr;
112 mpVetoChangeListeners = nullptr;
114 mxOriginal = aResult;
115 mpSortInfo = nullptr;
116 mnLastSort = 0;
117 mnCurEntry = 0;
118 mnCount = 0;
119 mbIsCopy = false;
123 SortedResultSet::~SortedResultSet()
125 mxOriginal.clear();
126 mxOther.clear();
128 if ( !mbIsCopy )
130 SortInfo *pInfo = mpSortInfo;
131 while ( pInfo )
133 mpSortInfo = pInfo->mpNext;
134 delete pInfo;
135 pInfo = mpSortInfo;
139 mpSortInfo = nullptr;
141 mpPropSetInfo.clear();
145 // XServiceInfo methods.
147 OUString SAL_CALL SortedResultSet::getImplementationName()
149 return "com.sun.star.comp.ucb.SortedResultSet";
152 sal_Bool SAL_CALL SortedResultSet::supportsService( const OUString& ServiceName )
154 return cppu::supportsService( this, ServiceName );
157 css::uno::Sequence< OUString > SAL_CALL SortedResultSet::getSupportedServiceNames()
159 return { RESULTSET_SERVICE_NAME };
163 // XComponent methods.
165 void SAL_CALL SortedResultSet::dispose()
167 osl::Guard< osl::Mutex > aGuard( maMutex );
169 if ( mpDisposeEventListeners && mpDisposeEventListeners->getLength() )
171 EventObject aEvt;
172 aEvt.Source = static_cast< XComponent * >( this );
173 mpDisposeEventListeners->disposeAndClear( aEvt );
176 if ( mpPropChangeListeners )
178 EventObject aEvt;
179 aEvt.Source = static_cast< XPropertySet * >( this );
180 mpPropChangeListeners->disposeAndClear( aEvt );
183 if ( mpVetoChangeListeners )
185 EventObject aEvt;
186 aEvt.Source = static_cast< XPropertySet * >( this );
187 mpVetoChangeListeners->disposeAndClear( aEvt );
190 mxOriginal.clear();
191 mxOther.clear();
195 void SAL_CALL SortedResultSet::addEventListener(
196 const Reference< XEventListener >& Listener )
198 osl::Guard< osl::Mutex > aGuard( maMutex );
200 if ( !mpDisposeEventListeners )
201 mpDisposeEventListeners =
202 new OInterfaceContainerHelper2( getContainerMutex() );
204 mpDisposeEventListeners->addInterface( Listener );
208 void SAL_CALL SortedResultSet::removeEventListener(
209 const Reference< XEventListener >& Listener )
211 osl::Guard< osl::Mutex > aGuard( maMutex );
213 if ( mpDisposeEventListeners )
214 mpDisposeEventListeners->removeInterface( Listener );
218 // XContentAccess methods.
221 OUString SAL_CALL
222 SortedResultSet::queryContentIdentifierString()
224 osl::Guard< osl::Mutex > aGuard( maMutex );
225 return Reference< XContentAccess >::query(mxOriginal)->queryContentIdentifierString();
229 Reference< XContentIdentifier > SAL_CALL
230 SortedResultSet::queryContentIdentifier()
232 osl::Guard< osl::Mutex > aGuard( maMutex );
233 return Reference< XContentAccess >::query(mxOriginal)->queryContentIdentifier();
237 Reference< XContent > SAL_CALL
238 SortedResultSet::queryContent()
240 osl::Guard< osl::Mutex > aGuard( maMutex );
241 return Reference< XContentAccess >::query(mxOriginal)->queryContent();
245 // XResultSet methods.
247 sal_Bool SAL_CALL SortedResultSet::next()
249 osl::Guard< osl::Mutex > aGuard( maMutex );
251 mnCurEntry++;
253 if ( mnCurEntry > 0 )
255 if ( mnCurEntry <= mnCount )
257 sal_Int32 nIndex = maS2O[ mnCurEntry ];
258 return mxOriginal->absolute( nIndex );
260 else
262 mnCurEntry = mnCount + 1;
265 return false;
269 sal_Bool SAL_CALL SortedResultSet::isBeforeFirst()
271 if ( mnCurEntry )
272 return false;
273 else
274 return true;
278 sal_Bool SAL_CALL SortedResultSet::isAfterLast()
280 if ( mnCurEntry > mnCount )
281 return true;
282 else
283 return false;
287 sal_Bool SAL_CALL SortedResultSet::isFirst()
289 if ( mnCurEntry == 1 )
290 return true;
291 else
292 return false;
296 sal_Bool SAL_CALL SortedResultSet::isLast()
298 if ( mnCurEntry == mnCount )
299 return true;
300 else
301 return false;
305 void SAL_CALL SortedResultSet::beforeFirst()
307 osl::Guard< osl::Mutex > aGuard( maMutex );
308 mnCurEntry = 0;
309 mxOriginal->beforeFirst();
313 void SAL_CALL SortedResultSet::afterLast()
315 osl::Guard< osl::Mutex > aGuard( maMutex );
316 mnCurEntry = mnCount+1;
317 mxOriginal->afterLast();
321 sal_Bool SAL_CALL SortedResultSet::first()
323 osl::Guard< osl::Mutex > aGuard( maMutex );
325 if ( mnCount )
327 mnCurEntry = 1;
328 sal_Int32 nIndex = maS2O[ mnCurEntry ];
329 return mxOriginal->absolute( nIndex );
331 else
333 mnCurEntry = 0;
334 return false;
339 sal_Bool SAL_CALL SortedResultSet::last()
341 osl::Guard< osl::Mutex > aGuard( maMutex );
343 if ( mnCount )
345 mnCurEntry = mnCount;
346 sal_Int32 nIndex = maS2O[ mnCurEntry ];
347 return mxOriginal->absolute( nIndex );
349 else
351 mnCurEntry = 0;
352 return false;
357 sal_Int32 SAL_CALL SortedResultSet::getRow()
359 return mnCurEntry;
364 moves the cursor to the given row number in the result set.
365 <p>If the row number is positive, the cursor moves to the given row
366 number with respect to the beginning of the result set. The first
367 row is row 1, the second is row 2, and so on.
368 <p>If the given row number is negative, the cursor moves to an
369 absolute row position with respect to the end of the result set.
370 For example, calling <code>moveToPosition(-1)</code> positions the
371 cursor on the last row, <code>moveToPosition(-2)</code> indicates the
372 next-to-last row, and so on.
373 <p>An attempt to position the cursor beyond the first/last row in the
374 result set leaves the cursor before/after the first/last row,
375 respectively.
376 <p>Note: Calling <code>moveToPosition(1)</code> is the same
377 as calling <code>moveToFirst()</code>. Calling
378 <code>moveToPosition(-1)</code> is the same as calling
379 <code>moveToLast()</code>.
380 @param row
381 is the number of rows to move. Could be negative.
382 @returns
383 <TRUE/> if the cursor is on a row; <FALSE/> otherwise
384 @throws SQLException
385 if a database access error occurs or if row is 0, or the result set
386 type is FORWARD_ONLY.
388 sal_Bool SAL_CALL SortedResultSet::absolute( sal_Int32 row )
390 osl::Guard< osl::Mutex > aGuard( maMutex );
392 sal_Int32 nIndex;
394 if ( row > 0 )
396 if ( row <= mnCount )
398 mnCurEntry = row;
399 nIndex = maS2O[ mnCurEntry ];
400 return mxOriginal->absolute( nIndex );
402 else
404 mnCurEntry = mnCount + 1;
405 return false;
408 else if ( row == 0 )
410 throw SQLException();
412 else
414 if ( mnCount + row + 1 > 0 )
416 mnCurEntry = mnCount + row + 1;
417 nIndex = maS2O[ mnCurEntry ];
418 return mxOriginal->absolute( nIndex );
420 else
422 mnCurEntry = 0;
423 return false;
430 moves the cursor a relative number of rows, either positive or negative.
432 Attempting to move beyond the first/last row in the result set positions
433 the cursor before/after the first/last row. Calling
434 <code>moveRelative(0)</code> is valid, but does not change the cursor
435 position.
436 <p>Note: Calling <code>moveRelative(1)</code> is different from calling
437 <code>moveNext()</code> because is makes sense to call
438 <code>moveNext()</code> when there is no current row, for example,
439 when the cursor is positioned before the first row or after the last
440 row of the result set.
441 @param rows
442 is the number of rows to move. Could be negative.
443 @returns
444 <TRUE/> if the cursor is on a valid row; <FALSE/> if it is off
445 the result set.
446 @throws SQLException
447 if a database access error occurs or if there is no
448 current row, or the result set type is FORWARD_ONLY.
450 sal_Bool SAL_CALL SortedResultSet::relative( sal_Int32 rows )
452 osl::Guard< osl::Mutex > aGuard( maMutex );
454 if ( ( mnCurEntry <= 0 ) || ( mnCurEntry > mnCount ) )
456 throw SQLException();
459 if ( rows == 0 )
460 return true;
462 sal_Int32 nTmp = mnCurEntry + rows;
464 if ( nTmp <= 0 )
466 mnCurEntry = 0;
467 return false;
469 else if ( nTmp > mnCount )
471 mnCurEntry = mnCount + 1;
472 return false;
474 else
476 mnCurEntry = nTmp;
477 nTmp = maS2O[ mnCurEntry ];
478 return mxOriginal->absolute( nTmp );
484 moves the cursor to the previous row in the result set.
485 <p>Note: <code>previous()</code> is not the same as
486 <code>relative(-1)</code> because it makes sense to call
487 <code>previous()</code> when there is no current row.
488 @returns <TRUE/> if the cursor is on a valid row; <FALSE/> if it is off
489 the result set.
490 @throws SQLException
491 if a database access error occurs or the result set type
492 is FORWARD_ONLY.
494 sal_Bool SAL_CALL SortedResultSet::previous()
496 osl::Guard< osl::Mutex > aGuard( maMutex );
498 mnCurEntry -= 1;
500 if ( mnCurEntry > 0 )
502 if ( mnCurEntry <= mnCount )
504 sal_Int32 nIndex = maS2O[ mnCurEntry ];
505 return mxOriginal->absolute( nIndex );
508 else
509 mnCurEntry = 0;
511 return false;
515 void SAL_CALL SortedResultSet::refreshRow()
517 osl::Guard< osl::Mutex > aGuard( maMutex );
519 if ( ( mnCurEntry <= 0 ) || ( mnCurEntry > mnCount ) )
521 throw SQLException();
524 mxOriginal->refreshRow();
528 sal_Bool SAL_CALL SortedResultSet::rowUpdated()
530 osl::Guard< osl::Mutex > aGuard( maMutex );
532 if ( ( mnCurEntry <= 0 ) || ( mnCurEntry > mnCount ) )
534 throw SQLException();
537 return mxOriginal->rowUpdated();
541 sal_Bool SAL_CALL SortedResultSet::rowInserted()
543 osl::Guard< osl::Mutex > aGuard( maMutex );
545 if ( ( mnCurEntry <= 0 ) || ( mnCurEntry > mnCount ) )
547 throw SQLException();
550 return mxOriginal->rowInserted();
554 sal_Bool SAL_CALL SortedResultSet::rowDeleted()
556 osl::Guard< osl::Mutex > aGuard( maMutex );
558 if ( ( mnCurEntry <= 0 ) || ( mnCurEntry > mnCount ) )
560 throw SQLException();
563 return mxOriginal->rowDeleted();
567 Reference< XInterface > SAL_CALL SortedResultSet::getStatement()
569 osl::Guard< osl::Mutex > aGuard( maMutex );
571 if ( ( mnCurEntry <= 0 ) || ( mnCurEntry > mnCount ) )
573 throw SQLException();
576 return mxOriginal->getStatement();
580 // XRow methods.
583 sal_Bool SAL_CALL SortedResultSet::wasNull()
585 osl::Guard< osl::Mutex > aGuard( maMutex );
586 return Reference< XRow >::query(mxOriginal)->wasNull();
590 OUString SAL_CALL SortedResultSet::getString( sal_Int32 columnIndex )
592 osl::Guard< osl::Mutex > aGuard( maMutex );
593 return Reference< XRow >::query(mxOriginal)->getString( columnIndex );
597 sal_Bool SAL_CALL SortedResultSet::getBoolean( sal_Int32 columnIndex )
599 osl::Guard< osl::Mutex > aGuard( maMutex );
600 return Reference< XRow >::query(mxOriginal)->getBoolean( columnIndex );
604 sal_Int8 SAL_CALL SortedResultSet::getByte( sal_Int32 columnIndex )
606 osl::Guard< osl::Mutex > aGuard( maMutex );
607 return Reference< XRow >::query(mxOriginal)->getByte( columnIndex );
611 sal_Int16 SAL_CALL SortedResultSet::getShort( sal_Int32 columnIndex )
613 osl::Guard< osl::Mutex > aGuard( maMutex );
614 return Reference< XRow >::query(mxOriginal)->getShort( columnIndex );
618 sal_Int32 SAL_CALL SortedResultSet::getInt( sal_Int32 columnIndex )
620 osl::Guard< osl::Mutex > aGuard( maMutex );
621 return Reference< XRow >::query(mxOriginal)->getInt( columnIndex );
624 sal_Int64 SAL_CALL SortedResultSet::getLong( sal_Int32 columnIndex )
626 osl::Guard< osl::Mutex > aGuard( maMutex );
627 return Reference< XRow >::query(mxOriginal)->getLong( columnIndex );
631 float SAL_CALL SortedResultSet::getFloat( sal_Int32 columnIndex )
633 osl::Guard< osl::Mutex > aGuard( maMutex );
634 return Reference< XRow >::query(mxOriginal)->getFloat( columnIndex );
638 double SAL_CALL SortedResultSet::getDouble( sal_Int32 columnIndex )
640 osl::Guard< osl::Mutex > aGuard( maMutex );
641 return Reference< XRow >::query(mxOriginal)->getDouble( columnIndex );
645 Sequence< sal_Int8 > SAL_CALL SortedResultSet::getBytes( sal_Int32 columnIndex )
647 osl::Guard< osl::Mutex > aGuard( maMutex );
648 return Reference< XRow >::query(mxOriginal)->getBytes( columnIndex );
652 Date SAL_CALL SortedResultSet::getDate( sal_Int32 columnIndex )
654 osl::Guard< osl::Mutex > aGuard( maMutex );
655 return Reference< XRow >::query(mxOriginal)->getDate( columnIndex );
659 Time SAL_CALL SortedResultSet::getTime( sal_Int32 columnIndex )
661 osl::Guard< osl::Mutex > aGuard( maMutex );
662 return Reference< XRow >::query(mxOriginal)->getTime( columnIndex );
666 DateTime SAL_CALL SortedResultSet::getTimestamp( sal_Int32 columnIndex )
668 osl::Guard< osl::Mutex > aGuard( maMutex );
669 return Reference< XRow >::query(mxOriginal)->getTimestamp( columnIndex );
673 Reference< XInputStream > SAL_CALL
674 SortedResultSet::getBinaryStream( sal_Int32 columnIndex )
676 osl::Guard< osl::Mutex > aGuard( maMutex );
677 return Reference< XRow >::query(mxOriginal)->getBinaryStream( columnIndex );
681 Reference< XInputStream > SAL_CALL
682 SortedResultSet::getCharacterStream( sal_Int32 columnIndex )
684 osl::Guard< osl::Mutex > aGuard( maMutex );
685 return Reference< XRow >::query(mxOriginal)->getCharacterStream( columnIndex );
689 Any SAL_CALL SortedResultSet::getObject( sal_Int32 columnIndex,
690 const Reference< XNameAccess >& typeMap )
692 osl::Guard< osl::Mutex > aGuard( maMutex );
693 return Reference< XRow >::query(mxOriginal)->getObject( columnIndex,
694 typeMap);
698 Reference< XRef > SAL_CALL SortedResultSet::getRef( sal_Int32 columnIndex )
700 osl::Guard< osl::Mutex > aGuard( maMutex );
701 return Reference< XRow >::query(mxOriginal)->getRef( columnIndex );
705 Reference< XBlob > SAL_CALL SortedResultSet::getBlob( sal_Int32 columnIndex )
707 osl::Guard< osl::Mutex > aGuard( maMutex );
708 return Reference< XRow >::query(mxOriginal)->getBlob( columnIndex );
712 Reference< XClob > SAL_CALL SortedResultSet::getClob( sal_Int32 columnIndex )
714 osl::Guard< osl::Mutex > aGuard( maMutex );
715 return Reference< XRow >::query(mxOriginal)->getClob( columnIndex );
719 Reference< XArray > SAL_CALL SortedResultSet::getArray( sal_Int32 columnIndex )
721 osl::Guard< osl::Mutex > aGuard( maMutex );
722 return Reference< XRow >::query(mxOriginal)->getArray( columnIndex );
726 // XCloseable methods.
729 void SAL_CALL SortedResultSet::close()
731 osl::Guard< osl::Mutex > aGuard( maMutex );
732 Reference< XCloseable >::query(mxOriginal)->close();
736 // XResultSetMetaDataSupplier methods.
739 Reference< XResultSetMetaData > SAL_CALL SortedResultSet::getMetaData()
741 osl::Guard< osl::Mutex > aGuard( maMutex );
742 return Reference< XResultSetMetaDataSupplier >::query(mxOriginal)->getMetaData();
746 // XPropertySet methods.
749 Reference< XPropertySetInfo > SAL_CALL
750 SortedResultSet::getPropertySetInfo()
752 osl::Guard< osl::Mutex > aGuard( maMutex );
754 if ( !mpPropSetInfo.is() )
756 mpPropSetInfo = new SRSPropertySetInfo();
759 return Reference< XPropertySetInfo >( mpPropSetInfo.get() );
763 void SAL_CALL SortedResultSet::setPropertyValue(
764 const OUString& PropertyName,
765 const Any& )
767 osl::Guard< osl::Mutex > aGuard( maMutex );
769 if ( PropertyName == "RowCount" || PropertyName == "IsRowCountFinal" )
770 throw IllegalArgumentException();
771 else
772 throw UnknownPropertyException(PropertyName);
776 Any SAL_CALL SortedResultSet::getPropertyValue( const OUString& PropertyName )
778 osl::Guard< osl::Mutex > aGuard( maMutex );
780 Any aRet;
782 if ( PropertyName == "RowCount" )
784 aRet <<= maS2O.Count();
786 else if ( PropertyName == "IsRowCountFinal" )
788 bool bOrgFinal = false;
789 Any aOrgRet;
791 aRet <<= false;
793 aOrgRet = Reference< XPropertySet >::query(mxOriginal)->
794 getPropertyValue( PropertyName );
795 aOrgRet >>= bOrgFinal;
797 if ( bOrgFinal )
799 aOrgRet = Reference< XPropertySet >::query(mxOriginal)->
800 getPropertyValue("RowCount");
801 sal_uInt32 nOrgCount = 0;
802 aOrgRet >>= nOrgCount;
803 if ( nOrgCount == maS2O.Count() )
804 aRet <<= true;
807 else
808 throw UnknownPropertyException(PropertyName);
810 return aRet;
814 void SAL_CALL SortedResultSet::addPropertyChangeListener(
815 const OUString& PropertyName,
816 const Reference< XPropertyChangeListener >& Listener )
818 osl::Guard< osl::Mutex > aGuard( maMutex );
820 if ( !mpPropChangeListeners )
821 mpPropChangeListeners.reset(
822 new PropertyChangeListeners_Impl() );
824 mpPropChangeListeners->addInterface( PropertyName, Listener );
828 void SAL_CALL SortedResultSet::removePropertyChangeListener(
829 const OUString& PropertyName,
830 const Reference< XPropertyChangeListener >& Listener )
832 osl::Guard< osl::Mutex > aGuard( maMutex );
834 if ( mpPropChangeListeners )
835 mpPropChangeListeners->removeInterface( PropertyName, Listener );
839 void SAL_CALL SortedResultSet::addVetoableChangeListener(
840 const OUString& PropertyName,
841 const Reference< XVetoableChangeListener >& Listener )
843 osl::Guard< osl::Mutex > aGuard( maMutex );
845 if ( !mpVetoChangeListeners )
846 mpVetoChangeListeners.reset(
847 new PropertyChangeListeners_Impl() );
849 mpVetoChangeListeners->addInterface( PropertyName, Listener );
853 void SAL_CALL SortedResultSet::removeVetoableChangeListener(
854 const OUString& PropertyName,
855 const Reference< XVetoableChangeListener >& Listener )
857 osl::Guard< osl::Mutex > aGuard( maMutex );
859 if ( mpVetoChangeListeners )
860 mpVetoChangeListeners->removeInterface( PropertyName, Listener );
864 // private methods
866 sal_IntPtr SortedResultSet::CompareImpl( const Reference < XResultSet >& xResultOne,
867 const Reference < XResultSet >& xResultTwo,
868 sal_IntPtr nIndexOne, sal_IntPtr nIndexTwo,
869 SortInfo const * pSortInfo )
871 Reference < XRow > xRowOne( xResultOne, UNO_QUERY );
872 Reference < XRow > xRowTwo( xResultTwo, UNO_QUERY );
874 sal_IntPtr nCompare = 0;
875 sal_Int32 nColumn = pSortInfo->mnColumn;
877 switch ( pSortInfo->mnType )
879 case DataType::BIT :
880 case DataType::TINYINT :
881 case DataType::SMALLINT :
882 case DataType::INTEGER :
884 sal_Int32 aOne = 0;
885 sal_Int32 aTwo = 0;
887 if ( xResultOne->absolute( nIndexOne ) )
888 aOne = xRowOne->getInt( nColumn );
889 if ( xResultTwo->absolute( nIndexTwo ) )
890 aTwo = xRowTwo->getInt( nColumn );
892 if ( aOne < aTwo )
893 nCompare = -1;
894 else if ( aOne == aTwo )
895 nCompare = 0;
896 else
897 nCompare = 1;
899 break;
901 case DataType::BIGINT :
903 sal_Int64 aOne = 0;
904 sal_Int64 aTwo = 0;
906 if ( xResultOne->absolute( nIndexOne ) )
907 aOne = xRowOne->getLong( nColumn );
908 if ( xResultTwo->absolute( nIndexTwo ) )
909 aTwo = xRowTwo->getLong( nColumn );
911 if ( aOne < aTwo )
912 nCompare = -1;
913 else if ( aOne == aTwo )
914 nCompare = 0;
915 else
916 nCompare = 1;
918 break;
920 case DataType::CHAR :
921 case DataType::VARCHAR :
922 case DataType::LONGVARCHAR :
924 OUString aOne, aTwo;
926 if ( xResultOne->absolute( nIndexOne ) )
927 aOne = xRowOne->getString( nColumn );
928 if ( xResultTwo->absolute( nIndexTwo ) )
929 aTwo = xRowTwo->getString( nColumn );
931 if ( ! pSortInfo->mbCaseSensitive )
933 aOne = aOne.toAsciiLowerCase();
934 aTwo = aTwo.toAsciiLowerCase();
937 nCompare = aOne.compareTo( aTwo );
938 break;
940 case DataType::DATE :
942 Date aOne, aTwo;
943 sal_Int32 nTmp;
945 if ( xResultOne->absolute( nIndexOne ) )
946 aOne = xRowOne->getDate( nColumn );
947 if ( xResultTwo->absolute( nIndexTwo ) )
948 aTwo = xRowTwo->getDate( nColumn );
950 nTmp = static_cast<sal_Int32>(aTwo.Year) - static_cast<sal_Int32>(aOne.Year);
951 if ( !nTmp ) {
952 nTmp = static_cast<sal_Int32>(aTwo.Month) - static_cast<sal_Int32>(aOne.Month);
953 if ( !nTmp )
954 nTmp = static_cast<sal_Int32>(aTwo.Day) - static_cast<sal_Int32>(aOne.Day);
957 if ( nTmp < 0 )
958 nCompare = -1;
959 else if ( nTmp == 0 )
960 nCompare = 0;
961 else
962 nCompare = 1;
964 break;
966 case DataType::TIME :
968 Time aOne, aTwo;
969 sal_Int32 nTmp;
971 if ( xResultOne->absolute( nIndexOne ) )
972 aOne = xRowOne->getTime( nColumn );
973 if ( xResultTwo->absolute( nIndexTwo ) )
974 aTwo = xRowTwo->getTime( nColumn );
976 nTmp = static_cast<sal_Int32>(aTwo.Hours) - static_cast<sal_Int32>(aOne.Hours);
977 if ( !nTmp )
978 nTmp = static_cast<sal_Int32>(aTwo.Minutes) - static_cast<sal_Int32>(aOne.Minutes);
979 if ( !nTmp )
980 nTmp = static_cast<sal_Int32>(aTwo.Seconds) - static_cast<sal_Int32>(aOne.Seconds);
981 if ( !nTmp )
982 nTmp = static_cast<sal_Int32>(aTwo.NanoSeconds)
983 - static_cast<sal_Int32>(aOne.NanoSeconds);
985 if ( nTmp < 0 )
986 nCompare = -1;
987 else if ( nTmp == 0 )
988 nCompare = 0;
989 else
990 nCompare = 1;
992 break;
994 case DataType::TIMESTAMP :
996 DateTime aOne, aTwo;
997 sal_Int32 nTmp;
999 if ( xResultOne->absolute( nIndexOne ) )
1000 aOne = xRowOne->getTimestamp( nColumn );
1001 if ( xResultTwo->absolute( nIndexTwo ) )
1002 aTwo = xRowTwo->getTimestamp( nColumn );
1004 nTmp = static_cast<sal_Int32>(aTwo.Year) - static_cast<sal_Int32>(aOne.Year);
1005 if ( !nTmp )
1006 nTmp = static_cast<sal_Int32>(aTwo.Month) - static_cast<sal_Int32>(aOne.Month);
1007 if ( !nTmp )
1008 nTmp = static_cast<sal_Int32>(aTwo.Day) - static_cast<sal_Int32>(aOne.Day);
1009 if ( !nTmp )
1010 nTmp = static_cast<sal_Int32>(aTwo.Hours) - static_cast<sal_Int32>(aOne.Hours);
1011 if ( !nTmp )
1012 nTmp = static_cast<sal_Int32>(aTwo.Minutes) - static_cast<sal_Int32>(aOne.Minutes);
1013 if ( !nTmp )
1014 nTmp = static_cast<sal_Int32>(aTwo.Seconds) - static_cast<sal_Int32>(aOne.Seconds);
1015 if ( !nTmp )
1016 nTmp = static_cast<sal_Int32>(aTwo.NanoSeconds)
1017 - static_cast<sal_Int32>(aOne.NanoSeconds);
1019 if ( nTmp < 0 )
1020 nCompare = -1;
1021 else if ( nTmp == 0 )
1022 nCompare = 0;
1023 else
1024 nCompare = 1;
1026 break;
1028 case DataType::REAL :
1030 float aOne = 0;
1031 float aTwo = 0;
1033 if ( xResultOne->absolute( nIndexOne ) )
1034 aOne = xRowOne->getFloat( nColumn );
1035 if ( xResultTwo->absolute( nIndexTwo ) )
1036 aTwo = xRowTwo->getFloat( nColumn );
1038 if ( aOne < aTwo )
1039 nCompare = -1;
1040 else if ( aOne == aTwo )
1041 nCompare = 0;
1042 else
1043 nCompare = 1;
1045 break;
1047 case DataType::FLOAT :
1048 case DataType::DOUBLE :
1050 double aOne = 0;
1051 double aTwo = 0;
1053 if ( xResultOne->absolute( nIndexOne ) )
1054 aOne = xRowOne->getDouble( nColumn );
1055 if ( xResultTwo->absolute( nIndexTwo ) )
1056 aTwo = xRowTwo->getDouble( nColumn );
1058 if ( aOne < aTwo )
1059 nCompare = -1;
1060 else if ( aOne == aTwo )
1061 nCompare = 0;
1062 else
1063 nCompare = 1;
1065 break;
1067 default:
1069 OSL_FAIL( "DataType not supported for compare!" );
1073 return nCompare;
1077 sal_IntPtr SortedResultSet::CompareImpl( const Reference < XResultSet >& xResultOne,
1078 const Reference < XResultSet >& xResultTwo,
1079 sal_IntPtr nIndexOne, sal_IntPtr nIndexTwo )
1081 sal_IntPtr nCompare = 0;
1082 SortInfo* pInfo = mpSortInfo;
1084 while ( !nCompare && pInfo )
1086 if ( pInfo->mbUseOwnCompare )
1088 nCompare = CompareImpl( xResultOne, xResultTwo,
1089 nIndexOne, nIndexTwo, pInfo );
1091 else
1093 Any aOne, aTwo;
1095 Reference < XRow > xRowOne =
1096 Reference< XRow >::query( xResultOne );
1097 Reference < XRow > xRowTwo =
1098 Reference< XRow >::query( xResultTwo );
1100 if ( xResultOne->absolute( nIndexOne ) )
1101 aOne = xRowOne->getObject( pInfo->mnColumn, nullptr );
1102 if ( xResultTwo->absolute( nIndexTwo ) )
1103 aTwo = xRowTwo->getObject( pInfo->mnColumn, nullptr );
1105 nCompare = pInfo->mxCompareFunction->compare( aOne, aTwo );
1108 if ( ! pInfo->mbAscending )
1109 nCompare = - nCompare;
1111 pInfo = pInfo->mpNext;
1114 return nCompare;
1118 sal_IntPtr SortedResultSet::Compare( SortListData const *pOne,
1119 SortListData const *pTwo )
1121 sal_IntPtr nIndexOne;
1122 sal_IntPtr nIndexTwo;
1124 Reference < XResultSet > xResultOne;
1125 Reference < XResultSet > xResultTwo;
1127 if ( pOne->mbModified )
1129 xResultOne = mxOther;
1130 nIndexOne = pOne->mnOldPos;
1132 else
1134 xResultOne = mxOriginal;
1135 nIndexOne = pOne->mnCurPos;
1138 if ( pTwo->mbModified )
1140 xResultTwo = mxOther;
1141 nIndexTwo = pTwo->mnOldPos;
1143 else
1145 xResultTwo = mxOriginal;
1146 nIndexTwo = pTwo->mnCurPos;
1149 sal_IntPtr nCompare;
1150 nCompare = CompareImpl( xResultOne, xResultTwo,
1151 nIndexOne, nIndexTwo );
1152 return nCompare;
1156 sal_IntPtr SortedResultSet::FindPos( SortListData const *pEntry,
1157 sal_IntPtr _nStart, sal_IntPtr _nEnd )
1159 if ( _nStart > _nEnd )
1160 return _nStart + 1;
1162 sal_IntPtr nStart = _nStart;
1163 sal_IntPtr nEnd = _nEnd;
1164 sal_IntPtr nMid = 0, nCompare = 0;
1167 while ( nStart <= nEnd )
1169 nMid = ( nEnd - nStart ) / 2 + nStart;
1170 SortListData *pMid = maS2O.GetData( nMid );
1171 nCompare = Compare( pEntry, pMid );
1173 if ( !nCompare )
1174 nCompare = (pEntry != pMid) ? ((pEntry < pMid) ? -1 : 1) : 0;
1176 if ( nCompare < 0 ) // pEntry < pMid
1177 nEnd = nMid - 1;
1178 else
1179 nStart = nMid + 1;
1182 if ( nCompare < 0 ) // pEntry < pMid
1183 return nMid;
1184 else
1185 return nMid+1;
1189 void SortedResultSet::PropertyChanged( const PropertyChangeEvent& rEvt )
1191 osl::Guard< osl::Mutex > aGuard( maMutex );
1193 if ( !mpPropChangeListeners )
1194 return;
1196 // Notify listeners interested especially in the changed property.
1197 OInterfaceContainerHelper* pPropsContainer =
1198 mpPropChangeListeners->getContainer( rEvt.PropertyName );
1199 if ( pPropsContainer )
1201 OInterfaceIteratorHelper aIter( *pPropsContainer );
1202 while ( aIter.hasMoreElements() )
1204 Reference< XPropertyChangeListener > xListener(
1205 aIter.next(), UNO_QUERY );
1206 if ( xListener.is() )
1207 xListener->propertyChange( rEvt );
1211 // Notify listeners interested in all properties.
1212 pPropsContainer = mpPropChangeListeners->getContainer( OUString() );
1213 if ( pPropsContainer )
1215 OInterfaceIteratorHelper aIter( *pPropsContainer );
1216 while ( aIter.hasMoreElements() )
1218 Reference< XPropertyChangeListener > xListener(
1219 aIter.next(), UNO_QUERY );
1220 if ( xListener.is() )
1221 xListener->propertyChange( rEvt );
1227 // public methods
1230 void SortedResultSet::CopyData( SortedResultSet *pSource )
1232 const SortedEntryList& rSrcS2O = pSource->maS2O;
1234 sal_IntPtr i, nCount;
1236 maS2O.Clear();
1237 m_O2S.clear();
1238 m_ModList.clear();
1240 maS2O.Insert( nullptr, 0 );
1241 m_O2S.push_back(0);
1243 nCount = rSrcS2O.Count();
1245 for ( i=1; i<nCount; i++ )
1247 maS2O.Insert( std::unique_ptr<SortListData>(new SortListData( rSrcS2O[ i ] )), i );
1248 m_O2S.push_back(pSource->m_O2S[i]);
1251 mnLastSort = maS2O.Count();
1252 mxOther = pSource->mxOriginal;
1254 if ( !mpSortInfo )
1256 mpSortInfo = pSource->mpSortInfo;
1257 mbIsCopy = true;
1262 void SortedResultSet::Initialize(
1263 const Sequence < NumberedSortingInfo > &xSortInfo,
1264 const Reference< XAnyCompareFactory > &xCompFactory )
1266 BuildSortInfo( mxOriginal, xSortInfo, xCompFactory );
1267 // Insert dummy at pos 0
1268 maS2O.Insert( std::unique_ptr<SortListData>(new SortListData( 0 )), 0 );
1270 sal_IntPtr nIndex = 1;
1272 // now fetch all the elements from the original result set,
1273 // get there new position in the sorted result set and insert
1274 // an entry in the sorted to original mapping list
1275 try {
1276 while ( mxOriginal->absolute( nIndex ) )
1278 std::unique_ptr<SortListData> pData(new SortListData( nIndex ));
1279 sal_IntPtr nPos = FindPos( pData.get(), 1, nIndex-1 );
1281 maS2O.Insert( std::move(pData), nPos );
1283 nIndex++;
1286 catch (const SQLException&)
1288 OSL_FAIL( "SortedResultSet::Initialize() : Got unexpected SQLException" );
1291 // when we have fetched all the elements, we can create the
1292 // original to sorted mapping list from the s2o list
1293 m_O2S.clear();
1294 m_O2S.push_back(0);
1296 // insert some dummy entries first and replace then
1297 // the entries with the right ones
1298 size_t i;
1300 for ( i=1; i<maS2O.Count(); i++ )
1301 m_O2S.push_back(0);
1302 for ( i=1; i<maS2O.Count(); i++ )
1303 m_O2S[maS2O[i]] = i;
1305 mnCount = maS2O.Count() - 1;
1309 void SortedResultSet::CheckProperties( sal_IntPtr nOldCount, bool bWasFinal )
1311 osl::Guard< osl::Mutex > aGuard( maMutex );
1313 if ( !mpPropChangeListeners )
1314 return;
1316 try {
1317 // check for propertyChangeEvents
1318 if ( nOldCount != GetCount() )
1320 bool bIsFinal = false;
1321 PropertyChangeEvent aEvt;
1323 aEvt.PropertyName = "RowCount";
1324 aEvt.Further = false;
1325 aEvt.PropertyHandle = -1;
1326 aEvt.OldValue <<= nOldCount;
1327 aEvt.NewValue <<= GetCount();
1329 PropertyChanged( aEvt );
1331 OUString aName = "IsRowCountFinal";
1332 Any aRet = getPropertyValue( aName );
1333 if ( (aRet >>= bIsFinal) && bIsFinal != bWasFinal )
1335 aEvt.PropertyName = aName;
1336 aEvt.Further = false;
1337 aEvt.PropertyHandle = -1;
1338 aEvt.OldValue <<= bWasFinal;
1339 aEvt.NewValue <<= bIsFinal;
1340 PropertyChanged( aEvt );
1344 catch (const UnknownPropertyException&) {}
1345 catch (const WrappedTargetException&) {}
1349 void SortedResultSet::InsertNew( sal_IntPtr nPos, sal_IntPtr nCount )
1351 // for all entries in the msS20-list, which are >= nPos, increase by nCount
1352 sal_IntPtr i, nEnd;
1354 nEnd = maS2O.Count();
1355 for ( i=1; i<=nEnd; i++ )
1357 SortListData *pData = maS2O.GetData( i );
1358 if ( pData->mnCurPos >= nPos )
1360 pData->mnCurPos += nCount;
1364 // and append the new entries at the end of the maS20-list or insert at the
1365 // position nPos in the maS2O-list
1366 for ( i=0; i<nCount; i++ )
1368 nEnd += 1;
1369 std::unique_ptr<SortListData> pData(new SortListData( nEnd ));
1371 maS2O.Insert( std::move(pData), nEnd ); // Insert( Value, Position )
1372 m_O2S.insert(m_O2S.begin() + nPos + i, nEnd);
1375 mnCount += nCount;
1379 void SortedResultSet::Remove( sal_IntPtr nPos, sal_IntPtr nCount, EventList *pEvents )
1381 sal_uInt32 i;
1382 sal_IntPtr nOldLastSort;
1384 // correct mnLastSort first
1385 nOldLastSort = mnLastSort;
1386 if ( nPos <= mnLastSort )
1388 if ( nPos + nCount - 1 <= mnLastSort )
1389 mnLastSort -= nCount;
1390 else
1391 mnLastSort = nPos - 1;
1394 // remove the entries from the lists and correct the positions
1395 // in the original2sorted list
1396 for ( i=0; i < static_cast<sal_uInt32>(nCount); i++ )
1398 sal_IntPtr nSortPos = m_O2S[nPos];
1399 m_O2S.erase(m_O2S.begin() + nPos);
1401 for (size_t j=1; j < m_O2S.size(); ++j)
1403 sal_IntPtr nVal = m_O2S[j];
1404 if ( nVal > nSortPos )
1406 --nVal;
1407 m_O2S[j] = nVal;
1411 std::unique_ptr<SortListData> pData = maS2O.Remove( nSortPos );
1412 if ( pData->mbModified )
1413 m_ModList.erase(std::find(m_ModList.begin(), m_ModList.end(), pData.get()));
1415 // generate remove Event, but not for new entries
1416 if ( nSortPos <= nOldLastSort )
1417 pEvents->AddEvent( ListActionType::REMOVED, nSortPos );
1420 // correct the positions in the sorted list
1421 for ( i=1; i<= maS2O.Count(); i++ )
1423 SortListData *pData = maS2O.GetData( i );
1424 if ( pData->mnCurPos > nPos )
1425 pData->mnCurPos -= nCount;
1428 mnCount -= nCount;
1432 void SortedResultSet::Move( sal_IntPtr nPos, sal_IntPtr nCount, sal_IntPtr nOffset )
1434 if ( !nOffset )
1435 return;
1437 sal_IntPtr i, nSortPos, nTo;
1438 SortListData *pData;
1440 for ( i=0; i<nCount; i++ )
1442 nSortPos = m_O2S[nPos + i];
1443 pData = maS2O.GetData( nSortPos );
1444 pData->mnCurPos += nOffset;
1447 if ( nOffset < 0 )
1449 for ( i=nPos+nOffset; i<nPos; i++ )
1451 nSortPos = m_O2S[i];
1452 pData = maS2O.GetData( nSortPos );
1453 pData->mnCurPos += nCount;
1456 else
1458 sal_IntPtr nStart = nPos + nCount;
1459 sal_IntPtr nEnd = nStart + nOffset;
1460 for ( i=nStart; i<nEnd; i++ )
1462 nSortPos = m_O2S[i];
1463 pData = maS2O.GetData( nSortPos );
1464 pData->mnCurPos -= nCount;
1468 // remember the to be moved entries
1469 std::unique_ptr<sal_IntPtr[]> pTmpArr(new sal_IntPtr[ nCount ]);
1470 for ( i=0; i<nCount; i++ )
1471 pTmpArr[i] = m_O2S[nPos + i];
1473 // now move the entries, which are in the way
1474 if ( nOffset < 0 )
1476 // be carefully here, because nOffset is negative here, so an
1477 // addition is a subtraction
1478 sal_IntPtr nFrom = nPos - 1;
1479 nTo = nPos + nCount - 1;
1481 // same for i here
1482 for ( i=0; i>nOffset; i-- )
1484 sal_IntPtr const nVal = m_O2S[nFrom + i];
1485 m_O2S[nTo + i] = nVal;
1489 else
1491 sal_IntPtr nStart = nPos + nCount;
1492 for ( i=0; i<nOffset; i++ )
1494 sal_IntPtr const nVal = m_O2S[nStart + i];
1495 m_O2S[nPos + i] = nVal;
1499 // finally put the remembered entries at their new location
1500 nTo = nPos + nOffset;
1501 for ( i=0; i<nCount; i++ )
1503 m_O2S[nTo + i] = pTmpArr[i];
1508 void SortedResultSet::BuildSortInfo(
1509 const Reference< XResultSet >& aResult,
1510 const Sequence < NumberedSortingInfo > &xSortInfo,
1511 const Reference< XAnyCompareFactory > &xCompFactory )
1513 Reference < XResultSetMetaDataSupplier > xMeta ( aResult, UNO_QUERY );
1515 if ( ! xMeta.is() )
1517 OSL_FAIL( "No MetaData, No Sorting!" );
1518 return;
1521 Reference < XResultSetMetaData > xData = xMeta->getMetaData();
1522 const NumberedSortingInfo *pSortInfo = xSortInfo.getConstArray();
1524 sal_Int32 nColumn;
1525 OUString aPropName;
1526 SortInfo *pInfo;
1528 for ( sal_Int32 i=xSortInfo.getLength(); i > 0; )
1530 --i;
1531 nColumn = pSortInfo[ i ].ColumnIndex;
1532 aPropName = xData->getColumnName( nColumn );
1533 pInfo = new SortInfo;
1535 if ( xCompFactory.is() )
1536 pInfo->mxCompareFunction = xCompFactory->createAnyCompareByName(
1537 aPropName );
1539 if ( pInfo->mxCompareFunction.is() )
1541 pInfo->mbUseOwnCompare = false;
1542 pInfo->mnType = 0;
1544 else
1546 pInfo->mbUseOwnCompare = true;
1547 pInfo->mnType = xData->getColumnType( nColumn );
1550 pInfo->mnColumn = nColumn;
1551 pInfo->mbAscending = pSortInfo[ i ].Ascending;
1552 pInfo->mbCaseSensitive = xData->isCaseSensitive( nColumn );
1553 pInfo->mpNext = mpSortInfo;
1554 mpSortInfo = pInfo;
1559 void SortedResultSet::SetChanged( sal_IntPtr nPos, sal_IntPtr nCount )
1561 for ( sal_IntPtr i=0; i<nCount; i++ )
1563 sal_IntPtr const nSortPos = m_O2S[nPos];
1564 if ( nSortPos < mnLastSort )
1566 SortListData *pData = maS2O.GetData( nSortPos );
1567 if ( ! pData->mbModified )
1569 pData->mbModified = true;
1570 m_ModList.push_back(pData);
1573 nPos += 1;
1578 void SortedResultSet::ResortModified( EventList* pList )
1580 sal_IntPtr nCompare, nCurPos, nNewPos;
1581 sal_IntPtr nStart, nEnd, nOffset, nVal;
1583 try {
1584 for (size_t i = 0; i < m_ModList.size(); ++i)
1586 SortListData *const pData = m_ModList[i];
1587 nCompare = CompareImpl( mxOther, mxOriginal,
1588 pData->mnOldPos, pData->mnCurPos );
1589 pData->mbModified = false;
1590 if ( nCompare != 0 )
1592 nCurPos = m_O2S[pData->mnCurPos];
1593 if ( nCompare < 0 )
1595 nNewPos = FindPos( pData, 1, nCurPos-1 );
1596 nStart = nNewPos;
1597 nEnd = nCurPos;
1598 nOffset = 1;
1600 else
1602 nNewPos = FindPos( pData, nCurPos+1, mnLastSort );
1603 nStart = nCurPos;
1604 nEnd = mnLastSort;
1605 nOffset = -1;
1608 if ( nNewPos != nCurPos )
1610 // correct the lists!
1611 maS2O.Move( static_cast<sal_uInt32>(nCurPos), nNewPos );
1612 for (size_t j = 1; j < m_O2S.size(); ++j)
1614 nVal = m_O2S[j];
1615 if ( ( nStart <= nVal ) && ( nVal <= nEnd ) )
1617 nVal += nOffset;
1618 m_O2S[j] = nVal;
1622 m_O2S[pData->mnCurPos] = nNewPos;
1624 std::unique_ptr<ListAction> pAction(new ListAction);
1625 pAction->Position = nCurPos;
1626 pAction->Count = 1;
1627 pAction->ListActionType = ListActionType::MOVED;
1628 pAction->ActionInfo <<= nNewPos-nCurPos;
1629 pList->Insert( std::move(pAction) );
1631 pList->AddEvent( ListActionType::PROPERTIES_CHANGED, nNewPos );
1635 catch (const SQLException&)
1637 OSL_FAIL( "SortedResultSet::ResortModified() : Got unexpected SQLException" );
1640 m_ModList.clear();
1644 void SortedResultSet::ResortNew( EventList* pList )
1646 sal_IntPtr i, nNewPos, nVal;
1648 try {
1649 for ( i = mnLastSort; i<static_cast<sal_IntPtr>(maS2O.Count()); i++ )
1651 SortListData *const pData = m_ModList[i];
1652 nNewPos = FindPos( pData, 1, mnLastSort );
1653 if ( nNewPos != i )
1655 maS2O.Move( static_cast<sal_uInt32>(i), nNewPos );
1656 for (size_t j=1; j< m_O2S.size(); ++j)
1658 nVal = m_O2S[j];
1659 if ( nVal >= nNewPos )
1660 m_O2S[j] = nVal + 1;
1662 m_O2S[pData->mnCurPos] = nNewPos;
1664 mnLastSort++;
1665 pList->AddEvent( ListActionType::INSERTED, nNewPos );
1668 catch (const SQLException&)
1670 OSL_FAIL( "SortedResultSet::ResortNew() : Got unexpected SQLException" );
1675 // SortListData
1678 SortListData::SortListData( sal_IntPtr nPos )
1679 : mbModified(false)
1680 , mnCurPos(nPos)
1681 , mnOldPos(nPos)
1685 SortedEntryList::SortedEntryList()
1689 SortedEntryList::~SortedEntryList()
1693 void SortedEntryList::Clear()
1695 maData.clear();
1699 void SortedEntryList::Insert( std::unique_ptr<SortListData> pEntry, sal_IntPtr nPos )
1701 if ( nPos < static_cast<sal_IntPtr>(maData.size()) )
1702 maData.insert( maData.begin() + nPos, std::move(pEntry) );
1703 else
1704 maData.push_back( std::move(pEntry) );
1707 void SortedEntryList::Move( sal_IntPtr nOldPos, sal_IntPtr nNewPos )
1709 auto p = std::move(maData[nOldPos]);
1710 maData.erase( maData.begin() + nOldPos );
1711 maData.insert(maData.begin() + nNewPos, std::move(p));
1714 std::unique_ptr<SortListData> SortedEntryList::Remove( sal_IntPtr nPos )
1716 std::unique_ptr<SortListData> pData;
1718 if ( nPos < static_cast<sal_IntPtr>(maData.size()) )
1720 pData = std::move(maData[ nPos ]);
1721 maData.erase( maData.begin() + nPos );
1724 return pData;
1728 SortListData* SortedEntryList::GetData( sal_IntPtr nPos )
1730 SortListData *pData;
1732 if ( nPos < static_cast<sal_IntPtr>(maData.size()) )
1733 pData = maData[ nPos ].get();
1734 else
1735 pData = nullptr;
1737 return pData;
1741 sal_IntPtr SortedEntryList::operator [] ( sal_IntPtr nPos ) const
1743 SortListData *pData;
1745 if ( nPos < static_cast<sal_IntPtr>(maData.size()) )
1746 pData = maData[ nPos ].get();
1747 else
1748 pData = nullptr;
1750 if ( pData )
1751 if ( ! pData->mbModified )
1752 return pData->mnCurPos;
1753 else
1755 OSL_FAIL( "SortedEntryList: Can't get value for modified entry!");
1756 return 0;
1758 else
1760 OSL_FAIL( "SortedEntryList: invalid pos!");
1761 return 0;
1765 // class SRSPropertySetInfo.
1767 SRSPropertySetInfo::SRSPropertySetInfo()
1769 maProps[0].Name = "RowCount";
1770 maProps[0].Handle = -1;
1771 maProps[0].Type = cppu::UnoType<OUString>::get();
1772 maProps[0].Attributes = -1;
1774 maProps[1].Name = "IsRowCountFinal";
1775 maProps[1].Handle = -1;
1776 maProps[1].Type = cppu::UnoType<bool>::get();
1777 maProps[1].Attributes = -1;
1780 // XPropertySetInfo methods.
1782 Sequence< Property > SAL_CALL
1783 SRSPropertySetInfo::getProperties()
1785 return Sequence < Property > ( maProps, 2 );
1789 Property SAL_CALL
1790 SRSPropertySetInfo::getPropertyByName( const OUString& Name )
1792 if ( Name == "RowCount" )
1793 return maProps[0];
1794 else if ( Name == "IsRowCountFinal" )
1795 return maProps[1];
1796 else
1797 throw UnknownPropertyException(Name);
1801 sal_Bool SAL_CALL
1802 SRSPropertySetInfo::hasPropertyByName( const OUString& Name )
1804 if ( Name == "RowCount" )
1805 return true;
1806 else if ( Name == "IsRowCountFinal" )
1807 return true;
1808 else
1809 return false;
1812 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */