View | Details | Raw Unified | Return to issue 49380
Collapse All | Expand All

(-)sc/inc/table.hxx (+10 lines)
Lines 709-714 private: Link Here
709
    BOOL		SearchAllStyle(const SvxSearchItem& rSearchItem, ScMarkData& rMark);
709
    BOOL		SearchAllStyle(const SvxSearchItem& rSearchItem, ScMarkData& rMark);
710
    BOOL		ReplaceAllStyle(const SvxSearchItem& rSearchItem, ScMarkData& rMark,
710
    BOOL		ReplaceAllStyle(const SvxSearchItem& rSearchItem, ScMarkData& rMark,
711
                                ScDocument* pUndoDoc);
711
                                ScDocument* pUndoDoc);
712
    bool        SearchAndReplaceEmptyCells(
713
                    const SvxSearchItem& rSearchItem,
714
                    SCCOL& rCol, SCROW& rRow, ScMarkData& rMark,
715
                    String& rUndoStr, ScDocument* pUndoDoc);
716
    bool        SearchRangeForEmptyCell(const ScRange& rRange,
717
                    const SvxSearchItem& rSearchItem, SCCOL& rCol, SCROW& rRow,
718
                    String& rUndoStr, ScDocument* pUndoDoc);
719
    bool        SearchRangeForAllEmptyCells(const ScRange& rRange,
720
                    const SvxSearchItem& rSearchItem, ScMarkData& rMark,
721
                    String& rUndoStr, ScDocument* pUndoDoc);
712
722
713
                                // benutzen globalen SortParam:
723
                                // benutzen globalen SortParam:
714
    BOOL		IsSorted(SCCOLROW nStart, SCCOLROW nEnd);
724
    BOOL		IsSorted(SCCOLROW nStart, SCCOLROW nEnd);
(-)sc/source/core/data/column.cxx (-1 / +18 lines)
Lines 1370-1376 void ScColumn::CopyToColumn(SCROW nRow1, SCROW nRow2, USHORT nFlags, BOOL bMarke Link Here
1370
                    CloneCell( i, nFlags, *rColumn.pDocument, aDestPos );
1370
                    CloneCell( i, nFlags, *rColumn.pDocument, aDestPos );
1371
1371
1372
                if (pNew)
1372
                if (pNew)
1373
                    rColumn.Insert(pItems[i].nRow, pNew);
1373
                {
1374
                    // Special case to allow removing of cell instances.  A
1375
                    // string cell with empty content is used to indicate an
1376
                    // empty cell.
1377
                    if (pNew->GetCellType() == CELLTYPE_STRING)
1378
                    {
1379
                        String aStr;
1380
                        static_cast<ScStringCell*>(pNew)->GetString(aStr);
1381
                        if (aStr.Len() == 0)
1382
                            // A string cell with empty string.  Delete the cell itself.
1383
                            rColumn.Delete(pItems[i].nRow);
1384
                        else
1385
                            // non-empty string cell
1386
                            rColumn.Insert(pItems[i].nRow, pNew);
1387
                    }
1388
                    else
1389
                        rColumn.Insert(pItems[i].nRow, pNew);
1390
                }
1374
            }
1391
            }
1375
        }
1392
        }
1376
    }
1393
    }
(-)sc/source/core/data/table6.cxx (+276 lines)
Lines 49-54 Link Here
49
//--------------------------------------------------------------------------
49
//--------------------------------------------------------------------------
50
50
51
51
52
using ::com::sun::star::util::SearchOptions;
53
52
BOOL lcl_GetTextWithBreaks( const ScEditCell& rCell, ScDocument* pDoc, String& rVal )
54
BOOL lcl_GetTextWithBreaks( const ScEditCell& rCell, ScDocument* pDoc, String& rVal )
53
{
55
{
54
    //	TRUE = more than 1 paragraph
56
    //	TRUE = more than 1 paragraph
Lines 657-662 BOOL ScTable::SearchAndReplace(const SvxSearchItem& rSearchItem, Link Here
657
            com::sun::star::util::SearchOptions aSearchOptions = rSearchItem.GetSearchOptions();
659
            com::sun::star::util::SearchOptions aSearchOptions = rSearchItem.GetSearchOptions();
658
            aSearchOptions.Locale = *ScGlobal::GetLocale();
660
            aSearchOptions.Locale = *ScGlobal::GetLocale();
659
661
662
            if (!aSearchOptions.searchString.getLength())
663
            {
664
                // Search for empty cells.
665
                return SearchAndReplaceEmptyCells(rSearchItem, rCol, rRow, rMark, rUndoStr, pUndoDoc);
666
            }
667
660
            //	#107259# reflect UseAsianOptions flag in SearchOptions
668
            //	#107259# reflect UseAsianOptions flag in SearchOptions
661
            //	(use only ignore case and width if asian options are disabled).
669
            //	(use only ignore case and width if asian options are disabled).
662
            //	This is also done in SvxSearchDialog CommandHdl, but not in API object.
670
            //	This is also done in SvxSearchDialog CommandHdl, but not in API object.
Lines 683-688 BOOL ScTable::SearchAndReplace(const SvxSearchItem& rSearchItem, Link Here
683
    return bFound;
691
    return bFound;
684
}
692
}
685
693
694
bool ScTable::SearchAndReplaceEmptyCells(
695
    const SvxSearchItem& rSearchItem, SCCOL& rCol, SCROW& rRow, ScMarkData& rMark,
696
    String& rUndoStr, ScDocument* pUndoDoc)
697
{
698
    SCCOL nColStart, nColEnd;
699
    SCROW nRowStart, nRowEnd;
700
    GetFirstDataPos(nColStart, nRowStart);
701
    GetLastDataPos(nColEnd, nRowEnd);
702
703
    ScRangeList aRanges;
704
    aRanges.Append(ScRange(nColStart, nRowStart, nTab, nColEnd, nRowEnd, nTab));
705
706
    if (rSearchItem.GetSelection())
707
    {
708
        // current selection only.
709
        if (!rMark.IsMarked() && !rMark.IsMultiMarked())
710
            // There is no selection.  Bail out.
711
            return false;
712
713
        ScRangeList aMarkedRanges, aNewRanges;
714
        rMark.FillRangeListWithMarks(&aMarkedRanges, true);
715
        for (ScRangePtr p = aMarkedRanges.First(); p; p = aMarkedRanges.Next())
716
        {
717
            if (p->aStart.Col() > nColEnd || p->aStart.Row() > nRowEnd)
718
                // This range is outside the data area.  Skip it.
719
                continue;
720
721
            // Shrink the range into data area only.
722
            if (p->aStart.Col() < nColStart)
723
                p->aStart.SetCol(rCol);
724
            if (p->aStart.Row() < nRowStart)
725
                p->aStart.SetRow(rRow);
726
727
            if (p->aEnd.Col() > nColEnd)
728
                p->aEnd.SetCol(nColEnd);
729
            if (p->aEnd.Row() > nRowEnd)
730
                p->aEnd.SetRow(nRowEnd);
731
732
            aNewRanges.Append(*p);
733
        }
734
        aRanges = aNewRanges;
735
    }
736
737
    sal_uInt16 nCommand = rSearchItem.GetCommand();
738
    if (nCommand == SVX_SEARCHCMD_FIND || nCommand == SVX_SEARCHCMD_REPLACE)
739
    {
740
        if (rSearchItem.GetBackward())
741
        {
742
            for (ScRangePtr p = aRanges.Last(); p; p = aRanges.Prev())
743
            {
744
                if (SearchRangeForEmptyCell(*p, rSearchItem, rCol, rRow, rUndoStr, pUndoDoc))
745
                    return true;
746
            }
747
        }
748
        else
749
        {
750
            for (ScRangePtr p = aRanges.First(); p; p = aRanges.Next())
751
            {
752
                if (SearchRangeForEmptyCell(*p, rSearchItem, rCol, rRow, rUndoStr, pUndoDoc))
753
                    return true;
754
            }
755
        }
756
    }
757
    else if (nCommand == SVX_SEARCHCMD_FIND_ALL || nCommand == SVX_SEARCHCMD_REPLACE_ALL)
758
    {
759
        bool bFound = false;
760
        ScMarkData aNewMark(rMark);
761
        aNewMark.ResetMark();
762
        for (ScRangePtr p = aRanges.First(); p; p = aRanges.Next())
763
            bFound |= SearchRangeForAllEmptyCells(*p, rSearchItem, aNewMark, rUndoStr, pUndoDoc);
764
        rMark = aNewMark;
765
        return bFound;
766
    }
767
    return false;
768
}
769
770
bool ScTable::SearchRangeForEmptyCell(
771
    const ScRange& rRange, const SvxSearchItem& rSearchItem,
772
    SCCOL& rCol, SCROW& rRow, String& rUndoStr, ScDocument* /*pUndoDoc*/)
773
{
774
    sal_uInt16 nCmd = rSearchItem.GetCommand();
775
    if (rSearchItem.GetBackward())
776
    {
777
        // backward search
778
        if (rSearchItem.GetRowDirection())
779
        {
780
            // row direction.
781
            SCROW nBeginRow = rRange.aEnd.Row() > rRow ? rRow : rRange.aEnd.Row();
782
            for (SCROW nRow = nBeginRow; nRow >= rRange.aStart.Row(); --nRow)
783
            {
784
                SCCOL nBeginCol = rRange.aEnd.Col();
785
                if (nRow == rRow && nBeginCol >= rCol)
786
                    // always start from one cell before the cursor.
787
                    nBeginCol = rCol - (nCmd == SVX_SEARCHCMD_FIND ? 1 : 0);
788
789
                for (SCCOL nCol = nBeginCol; nCol >= rRange.aStart.Col(); --nCol)
790
                {
791
                    ScBaseCell* pCell = aCol[nCol].GetCell(nRow);
792
                    if (!pCell)
793
                    {
794
                        // empty cell found.
795
                        rCol = nCol;
796
                        rRow = nRow;
797
                        if (rSearchItem.GetCommand() == SVX_SEARCHCMD_REPLACE &&
798
                            rSearchItem.GetReplaceString().Len())
799
                        {
800
                            aCol[nCol].Insert(nRow, new ScStringCell(rSearchItem.GetReplaceString()));
801
                            rUndoStr = String();
802
                        }
803
                        return true;
804
                    }
805
                }
806
            }
807
        }
808
        else
809
        {
810
            // column direction.
811
            SCCOL nBeginCol = rRange.aEnd.Col() > rCol ? rCol : rRange.aEnd.Col();
812
            for (SCCOL nCol = nBeginCol; nCol >= rRange.aStart.Col(); --nCol)
813
            {
814
                SCROW nBeginRow = rRange.aEnd.Row();
815
                if (nCol == rCol && nBeginRow >= rRow)
816
                    // always start from one cell before the cursor.
817
                    nBeginRow = rRow - (nCmd == SVX_SEARCHCMD_FIND ? 1 : 0);
818
                for (SCROW nRow = nBeginRow; nRow >= rRange.aStart.Row(); --nRow)
819
                {
820
                    ScBaseCell* pCell = aCol[nCol].GetCell(nRow);
821
                    if (!pCell)
822
                    {
823
                        // empty cell found.
824
                        rCol = nCol;
825
                        rRow = nRow;
826
                        if (rSearchItem.GetCommand() == SVX_SEARCHCMD_REPLACE &&
827
                            rSearchItem.GetReplaceString().Len())
828
                        {
829
                            aCol[nCol].Insert(nRow, new ScStringCell(rSearchItem.GetReplaceString()));
830
                            rUndoStr = String();
831
                        }
832
                        return true;
833
                    }
834
                }
835
            }
836
        }
837
    }
838
    else
839
    {
840
        // forward search
841
        if (rSearchItem.GetRowDirection())
842
        {
843
            // row direction.
844
            SCROW nBeginRow = rRange.aStart.Row() < rRow ? rRow : rRange.aStart.Row();
845
            for (SCROW nRow = nBeginRow; nRow <= rRange.aEnd.Row(); ++nRow)
846
            {
847
                SCCOL nBeginCol = rRange.aStart.Col();
848
                if (nRow == rRow && nBeginCol <= rCol)
849
                    // always start from one cell past the cursor.
850
                    nBeginCol = rCol + (nCmd == SVX_SEARCHCMD_FIND ? 1 : 0);
851
                for (SCCOL nCol = nBeginCol; nCol <= rRange.aEnd.Col(); ++nCol)
852
                {
853
                    ScBaseCell* pCell = aCol[nCol].GetCell(nRow);
854
                    if (!pCell)
855
                    {
856
                        // empty cell found.
857
                        rCol = nCol;
858
                        rRow = nRow;
859
                        if (rSearchItem.GetCommand() == SVX_SEARCHCMD_REPLACE &&
860
                            rSearchItem.GetReplaceString().Len())
861
                        {
862
                            aCol[nCol].Insert(nRow, new ScStringCell(rSearchItem.GetReplaceString()));
863
                            rUndoStr = String();
864
                        }
865
                        return true;
866
                    }
867
                }
868
            }
869
        }
870
        else
871
        {
872
            // column direction.
873
            SCCOL nBeginCol = rRange.aStart.Col() < rCol ? rCol : rRange.aStart.Col();
874
            for (SCCOL nCol = nBeginCol; nCol <= rRange.aEnd.Col(); ++nCol)
875
            {
876
                SCROW nBeginRow = rRange.aStart.Row();
877
                if (nCol == rCol && nBeginRow <= rRow)
878
                    // always start from one cell past the cursor.
879
                    nBeginRow = rRow + (nCmd == SVX_SEARCHCMD_FIND ? 1 : 0);
880
                for (SCROW nRow = nBeginRow; nRow <= rRange.aEnd.Row(); ++nRow)
881
                {
882
                    ScBaseCell* pCell = aCol[nCol].GetCell(nRow);
883
                    if (!pCell)
884
                    {
885
                        // empty cell found.
886
                        rCol = nCol;
887
                        rRow = nRow;
888
                        if (rSearchItem.GetCommand() == SVX_SEARCHCMD_REPLACE &&
889
                            rSearchItem.GetReplaceString().Len())
890
                        {
891
                            aCol[nCol].Insert(nRow, new ScStringCell(rSearchItem.GetReplaceString()));
892
                            rUndoStr = String();
893
                        }
894
                        return true;
895
                    }
896
                }
897
            }
898
        }
899
    }
900
    return false;
901
}
902
903
bool ScTable::SearchRangeForAllEmptyCells(
904
    const ScRange& rRange, const SvxSearchItem& rSearchItem, ScMarkData& rMark,
905
    String& rUndoStr, ScDocument* pUndoDoc)
906
{
907
    bool bFound = false;
908
    bool bReplace = (rSearchItem.GetCommand() == SVX_SEARCHCMD_REPLACE_ALL) &&
909
                    (rSearchItem.GetReplaceString().Len() > 0);
910
911
    for (SCCOL nCol = rRange.aStart.Col(); nCol <= rRange.aEnd.Col(); ++nCol)
912
    {
913
        if (aCol[nCol].IsEmptyData())
914
        {
915
            // The entire column is empty.  Add the whole column and move on.
916
            rMark.SetMultiMarkArea(
917
                ScRange(nCol, rRange.aStart.Row(), nTab, nCol, rRange.aEnd.Row(), nTab));
918
            bFound = true;
919
920
            if (bReplace)
921
            {
922
                const String& rNewStr = rSearchItem.GetReplaceString();
923
                for (SCROW nRow = rRange.aStart.Row(); nRow <= rRange.aEnd.Row(); ++nRow)
924
                {
925
                    aCol[nCol].Insert(nRow, new ScStringCell(rNewStr));
926
                    if (pUndoDoc)
927
                        // TODO: I'm using a string cell with empty content to
928
                        // trigger deletion of cell instance on undo.  Maybe I
929
                        // should create a new cell type for this?
930
                        pUndoDoc->PutCell(nCol, nRow, nTab, new ScStringCell(String()));
931
                }
932
                rUndoStr = String();
933
            }
934
            continue;
935
        }
936
937
        for (SCROW nRow = rRange.aStart.Row(); nRow <= rRange.aEnd.Row(); ++nRow)
938
        {
939
            ScBaseCell* pCell = aCol[nCol].GetCell(nRow);
940
            if (!pCell)
941
            {
942
                // empty cell found
943
                rMark.SetMultiMarkArea(ScRange(nCol, nRow, nTab));
944
                bFound = true;
945
946
                if (bReplace)
947
                {
948
                    aCol[nCol].Insert(nRow, new ScStringCell(rSearchItem.GetReplaceString()));
949
                    if (pUndoDoc)
950
                        // TODO: I'm using a string cell with empty content to
951
                        // trigger deletion of cell instance on undo.  Maybe I
952
                        // should create a new cell type for this?
953
                        pUndoDoc->PutCell(nCol, nRow, nTab, new ScStringCell(String()));
954
                }
955
            }
956
        }
957
    }
958
    return bFound;
959
}
960
961
686
962
687
963
688
964
(-)sc/source/ui/view/tabvwsha.cxx (-2 / +6 lines)
Lines 230-237 void __EXPORT ScTabViewShell::GetState( SfxItemSet& rSet ) Link Here
230
                break;
230
                break;
231
231
232
            case SID_SEARCH_ITEM:
232
            case SID_SEARCH_ITEM:
233
                rSet.Put( ScGlobal::GetSearchItem() );
233
            {
234
                SvxSearchItem aItem(ScGlobal::GetSearchItem()); // make a copy.
235
                // Search on current selection if a range is marked.
236
                aItem.SetSelection(rMark.IsMarked());
237
                rSet.Put(aItem);
234
                break;
238
                break;
239
            }
235
240
236
            case SID_SEARCH_OPTIONS:
241
            case SID_SEARCH_OPTIONS:
237
                {
242
                {
238
- 

Return to issue 49380