1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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 #undef SC_DLLIMPLEMENTATION
22 #include <comphelper/string.hxx>
23 #include <vcl/msgbox.hxx>
26 #include "document.hxx"
27 #include "tabvwsh.hxx"
28 #include "viewdata.hxx"
29 #include "uiitems.hxx"
30 #include "userlist.hxx"
31 #include "rangeutl.hxx"
33 #include "scresid.hxx"
35 #include "globstr.hrc"
36 #include "tpusrlst.hxx"
38 #define CR (sal_Unicode)13
39 #define LF (sal_Unicode)10
41 static const sal_Unicode cDelimiter
= ',';
43 // Benutzerdefinierte Listen:
45 ScTpUserLists::ScTpUserLists( vcl::Window
* pParent
,
46 const SfxItemSet
& rCoreAttrs
)
48 : SfxTabPage ( pParent
,
49 "OptSortLists", "modules/scalc/ui/optsortlists.ui",
51 aStrQueryRemove ( ScGlobal::GetRscString( STR_QUERYREMOVE
) ),
52 aStrCopyList ( ScGlobal::GetRscString( STR_COPYLIST
) ),
53 aStrCopyFrom ( ScGlobal::GetRscString( STR_COPYFROM
) ),
54 aStrCopyErr ( ScGlobal::GetRscString( STR_COPYERR
) ),
55 nWhichUserLists ( GetWhich( SID_SCUSERLISTS
) ),
56 pUserLists ( nullptr ),
58 pViewData ( nullptr ),
59 bModifyMode ( false ),
60 bCancelMode ( false ),
64 get(mpFtLists
, "listslabel");
65 get(mpLbLists
, "lists");
66 get(mpFtEntries
, "entrieslabel");
67 get(mpEdEntries
, "entries");
68 get(mpFtCopyFrom
, "copyfromlabel");
69 get(mpEdCopyFrom
, "copyfrom");
71 get(mpBtnDiscard
, "discard");
73 get(mpBtnModify
, "modify");
74 get(mpBtnRemove
, "delete");
75 get(mpBtnCopy
, "copy");
82 ScTpUserLists::~ScTpUserLists()
87 void ScTpUserLists::dispose()
102 SfxTabPage::dispose();
105 void ScTpUserLists::Init()
107 SfxViewShell
* pSh
= SfxViewShell::Current();
108 ScTabViewShell
* pViewSh
= dynamic_cast<ScTabViewShell
*>( pSh
);
110 mpLbLists
->SetSelectHdl ( LINK( this, ScTpUserLists
, LbSelectHdl
) );
111 mpBtnNew
->SetClickHdl ( LINK( this, ScTpUserLists
, BtnClickHdl
) );
112 mpBtnDiscard
->SetClickHdl ( LINK( this, ScTpUserLists
, BtnClickHdl
) );
113 mpBtnAdd
->SetClickHdl ( LINK( this, ScTpUserLists
, BtnClickHdl
) );
114 mpBtnModify
->SetClickHdl ( LINK( this, ScTpUserLists
, BtnClickHdl
) );
115 mpBtnRemove
->SetClickHdl ( LINK( this, ScTpUserLists
, BtnClickHdl
) );
116 mpEdEntries
->SetModifyHdl ( LINK( this, ScTpUserLists
, EdEntriesModHdl
) );
127 pViewData
= &pViewSh
->GetViewData();
128 pDoc
= pViewData
->GetDocument();
130 pViewData
->GetSimpleArea( nStartCol
, nStartRow
, nStartTab
,
131 nEndCol
, nEndRow
, nEndTab
);
133 PutInOrder( nStartCol
, nEndCol
);
134 PutInOrder( nStartRow
, nEndRow
);
135 PutInOrder( nStartTab
, nEndTab
);
137 aStrSelectedArea
= ScRange( nStartCol
, nStartRow
, nStartTab
, nEndCol
, nEndRow
, nEndTab
138 ).Format(ScRefFlags::RANGE_ABS_3D
, pDoc
);
140 mpBtnCopy
->SetClickHdl ( LINK( this, ScTpUserLists
, BtnClickHdl
) );
145 mpBtnCopy
->Disable();
146 mpFtCopyFrom
->Disable();
147 mpEdCopyFrom
->Disable();
152 VclPtr
<SfxTabPage
> ScTpUserLists::Create( vcl::Window
* pParent
, const SfxItemSet
* rAttrSet
)
154 return VclPtr
<ScTpUserLists
>::Create( pParent
, *rAttrSet
);
157 void ScTpUserLists::Reset( const SfxItemSet
* rCoreAttrs
)
159 const ScUserListItem
& rUserListItem
= static_cast<const ScUserListItem
&>(
160 rCoreAttrs
->Get( nWhichUserLists
));
161 const ScUserList
* pCoreList
= rUserListItem
.GetUserList();
163 OSL_ENSURE( pCoreList
, "UserList not found :-/" );
168 pUserLists
= new ScUserList( *pCoreList
);
170 *pUserLists
= *pCoreList
;
172 if ( UpdateUserListBox() > 0 )
174 mpLbLists
->SelectEntryPos( 0 );
178 else if ( !pUserLists
)
179 pUserLists
= new ScUserList
;
181 mpEdCopyFrom
->SetText( aStrSelectedArea
);
183 if ( mpLbLists
->GetEntryCount() == 0 )
185 mpFtLists
->Disable();
186 mpLbLists
->Disable();
187 mpFtEntries
->Disable();
188 mpEdEntries
->Disable();
189 mpBtnRemove
->Disable();
193 mpBtnDiscard
->Hide();
197 mpBtnModify
->Disable();
199 if ( !bCopyDone
&& pViewData
)
201 mpFtCopyFrom
->Enable();
202 mpEdCopyFrom
->Enable();
207 bool ScTpUserLists::FillItemSet( SfxItemSet
* rCoreAttrs
)
209 // Modifikationen noch nicht uebernommen?
210 // -> Click auf Add-Button simulieren
212 if ( bModifyMode
|| bCancelMode
)
213 BtnClickHdl( mpBtnAdd
);
215 const ScUserListItem
& rUserListItem
= static_cast<const ScUserListItem
&>(
216 GetItemSet().Get( nWhichUserLists
));
218 ScUserList
* pCoreList
= rUserListItem
.GetUserList();
219 bool bDataModified
= false;
221 if ( (pUserLists
== nullptr) && (pCoreList
== nullptr) )
223 bDataModified
= false;
225 else if ( pUserLists
!= nullptr )
227 if ( pCoreList
!= nullptr )
228 bDataModified
= (*pUserLists
!= *pCoreList
);
230 bDataModified
= true;
235 ScUserListItem
aULItem( nWhichUserLists
);
238 aULItem
.SetUserList( *pUserLists
);
240 rCoreAttrs
->Put( aULItem
);
243 return bDataModified
;
246 SfxTabPage::sfxpg
ScTpUserLists::DeactivatePage( SfxItemSet
* pSetP
)
249 FillItemSet( pSetP
);
254 size_t ScTpUserLists::UpdateUserListBox()
258 if ( !pUserLists
) return 0;
260 size_t nCount
= pUserLists
->size();
263 for ( size_t i
=0; i
<nCount
; ++i
)
265 aEntry
= (*pUserLists
)[i
].GetString();
266 OSL_ENSURE( !aEntry
.isEmpty(), "Empty UserList-entry :-/" );
267 mpLbLists
->InsertEntry( aEntry
);
273 void ScTpUserLists::UpdateEntries( size_t nList
)
275 if ( !pUserLists
) return;
277 if ( nList
< pUserLists
->size() )
279 const ScUserListData
& rList
= (*pUserLists
)[nList
];
280 std::size_t nSubCount
= rList
.GetSubCount();
281 OUString aEntryListStr
;
283 for ( size_t i
=0; i
<nSubCount
; i
++ )
286 aEntryListStr
+= OUStringLiteral1
<CR
>();
287 aEntryListStr
+= rList
.GetSubStr(i
);
290 mpEdEntries
->SetText(convertLineEnd(aEntryListStr
, GetSystemLineEnd()));
294 OSL_FAIL( "Invalid ListIndex :-/" );
298 void ScTpUserLists::MakeListStr( OUString
& rListStr
)
302 sal_Int32 nToken
= comphelper::string::getTokenCount(rListStr
, LF
);
304 for(sal_Int32 i
=0; i
<nToken
; i
++)
306 OUString aString
= comphelper::string::strip(rListStr
.getToken(i
, LF
), ' ');
308 aStr
+= OUStringLiteral1
<cDelimiter
>();
311 aStr
= comphelper::string::strip(aStr
, cDelimiter
);
312 sal_Int32 nLen
= aStr
.getLength();
316 // Alle Doppelten cDelimiter entfernen:
320 rListStr
+= OUString(aStr
[c
]);
323 if ((c
< nLen
) && (aStr
[c
] == cDelimiter
))
325 rListStr
+= OUString(aStr
[c
]);
327 while ((c
< nLen
) && (aStr
[c
] == cDelimiter
))
334 void ScTpUserLists::AddNewList( const OUString
& rEntriesStr
)
336 OUString
theEntriesStr( rEntriesStr
);
339 pUserLists
= new ScUserList
;
341 MakeListStr( theEntriesStr
);
343 pUserLists
->push_back(new ScUserListData(theEntriesStr
));
346 void ScTpUserLists::CopyListFromArea( const ScRefAddress
& rStartPos
,
347 const ScRefAddress
& rEndPos
)
349 if ( bCopyDone
) return;
351 SCTAB nTab
= rStartPos
.Tab();
352 SCCOL nStartCol
= rStartPos
.Col();
353 SCROW nStartRow
= rStartPos
.Row();
354 SCCOL nEndCol
= rEndPos
.Col();
355 SCROW nEndRow
= rEndPos
.Row();
356 sal_uInt16 nCellDir
= SCRET_COLS
;
358 if ( (nStartCol
!= nEndCol
) && (nStartRow
!= nEndRow
) )
360 nCellDir
= ScopedVclPtrInstance
<ScColOrRowDlg
>(this, aStrCopyList
, aStrCopyFrom
)->Execute();
362 else if ( nStartCol
!= nEndCol
)
363 nCellDir
= SCRET_ROWS
;
365 nCellDir
= SCRET_COLS
;
367 if ( nCellDir
!= RET_CANCEL
)
369 bool bValueIgnored
= false;
373 if ( nCellDir
== SCRET_COLS
)
375 for ( SCCOL col
=nStartCol
; col
<=nEndCol
; col
++ )
377 for ( SCROW row
=nStartRow
; row
<=nEndRow
; row
++ )
379 if ( pDoc
->HasStringData( col
, row
, nTab
) )
381 aStrField
= pDoc
->GetString(col
, row
, nTab
);
383 if ( !aStrField
.isEmpty() )
385 aStrList
+= aStrField
;
390 bValueIgnored
= true;
392 if ( !aStrList
.isEmpty() )
393 AddNewList( aStrList
);
399 for ( SCROW row
=nStartRow
; row
<=nEndRow
; row
++ )
401 for ( SCCOL col
=nStartCol
; col
<=nEndCol
; col
++ )
403 if ( pDoc
->HasStringData( col
, row
, nTab
) )
405 aStrField
= pDoc
->GetString(col
, row
, nTab
);
407 if ( !aStrField
.isEmpty() )
409 aStrList
+= aStrField
;
414 bValueIgnored
= true;
416 if ( !aStrList
.isEmpty() )
417 AddNewList( aStrList
);
424 ScopedVclPtrInstance
<InfoBox
>(this, aStrCopyErr
)->Execute();
432 void ScTpUserLists::ModifyList( size_t nSelList
,
433 const OUString
& rEntriesStr
)
435 if ( !pUserLists
) return;
437 OUString
theEntriesStr( rEntriesStr
);
439 MakeListStr( theEntriesStr
);
441 (*pUserLists
)[nSelList
].SetString( theEntriesStr
);
444 void ScTpUserLists::RemoveList( size_t nList
)
446 if (pUserLists
&& nList
< pUserLists
->size())
448 ScUserList::iterator itr
= pUserLists
->begin();
449 ::std::advance(itr
, nList
);
450 pUserLists
->erase(itr
);
456 IMPL_LINK_TYPED( ScTpUserLists
, LbSelectHdl
, ListBox
&, rLb
, void )
458 if ( &rLb
== mpLbLists
)
460 sal_Int32 nSelPos
= mpLbLists
->GetSelectEntryPos();
461 if ( nSelPos
!= LISTBOX_ENTRY_NOTFOUND
)
463 if ( !mpFtEntries
->IsEnabled() ) mpFtEntries
->Enable();
464 if ( !mpEdEntries
->IsEnabled() ) mpEdEntries
->Enable();
465 if ( !mpBtnRemove
->IsEnabled() ) mpBtnRemove
->Enable();
466 if ( mpBtnAdd
->IsEnabled() )
469 mpBtnModify
->Disable();
472 UpdateEntries( nSelPos
);
477 IMPL_LINK_TYPED( ScTpUserLists
, BtnClickHdl
, Button
*, pBtn
, void )
479 if ( pBtn
== mpBtnNew
|| pBtn
== mpBtnDiscard
)
483 nCancelPos
= ( mpLbLists
->GetEntryCount() > 0 )
484 ? mpLbLists
->GetSelectEntryPos()
486 mpLbLists
->SetNoSelection();
487 mpFtLists
->Disable();
488 mpLbLists
->Disable();
489 mpFtEntries
->Enable();
490 mpEdEntries
->Enable();
491 mpEdEntries
->SetText( EMPTY_OUSTRING
);
492 mpEdEntries
->GrabFocus();
494 mpBtnModify
->Disable();
495 mpBtnRemove
->Disable();
497 if ( mpBtnCopy
->IsEnabled() )
499 mpBtnCopy
->Disable();
500 mpFtCopyFrom
->Disable();
501 mpEdCopyFrom
->Disable();
504 mpBtnDiscard
->Show();
507 else // if ( bCancelMode )
509 if ( mpLbLists
->GetEntryCount() > 0 )
511 mpLbLists
->SelectEntryPos( nCancelPos
);
512 LbSelectHdl( *mpLbLists
.get() );
518 mpFtEntries
->Disable();
519 mpEdEntries
->Disable();
520 mpEdEntries
->SetText( EMPTY_OUSTRING
);
521 mpBtnRemove
->Disable();
524 mpBtnModify
->Disable();
526 if ( pViewData
&& !bCopyDone
)
529 mpFtCopyFrom
->Enable();
530 mpEdCopyFrom
->Enable();
533 mpBtnDiscard
->Hide();
538 else if (pBtn
== mpBtnAdd
|| pBtn
== mpBtnModify
)
540 OUString
theEntriesStr( mpEdEntries
->GetText() );
544 if ( !theEntriesStr
.isEmpty() )
546 AddNewList( theEntriesStr
);
548 mpLbLists
->SelectEntryPos( mpLbLists
->GetEntryCount()-1 );
549 LbSelectHdl( *mpLbLists
.get() );
555 if ( mpLbLists
->GetEntryCount() > 0 )
557 mpLbLists
->SelectEntryPos( nCancelPos
);
558 LbSelectHdl( *mpLbLists
.get() );
565 mpBtnModify
->Disable();
566 mpBtnRemove
->Enable();
568 mpBtnDiscard
->Hide();
571 else // if ( bModifyMode )
573 sal_Int32 nSelList
= mpLbLists
->GetSelectEntryPos();
575 OSL_ENSURE( nSelList
!= LISTBOX_ENTRY_NOTFOUND
, "Modify without List :-/" );
577 if ( !theEntriesStr
.isEmpty() )
579 ModifyList( nSelList
, theEntriesStr
);
581 mpLbLists
->SelectEntryPos( nSelList
);
585 mpLbLists
->SelectEntryPos( 0 );
586 LbSelectHdl( *mpLbLists
.get() );
590 mpBtnDiscard
->Hide();
595 mpBtnModify
->Disable();
597 mpBtnRemove
->Enable();
602 if ( pViewData
&& !bCopyDone
)
605 mpFtCopyFrom
->Enable();
606 mpEdCopyFrom
->Enable();
609 else if ( pBtn
== mpBtnRemove
)
611 if ( mpLbLists
->GetEntryCount() > 0 )
613 sal_Int32 nRemovePos
= mpLbLists
->GetSelectEntryPos();
614 OUString
aMsg ( aStrQueryRemove
.getToken( 0, '#' ) );
616 aMsg
+= mpLbLists
->GetEntry( nRemovePos
);
617 aMsg
+= aStrQueryRemove
.getToken( 1, '#' );
619 if ( RET_YES
== ScopedVclPtrInstance
<QueryBox
>( this,
620 WinBits( WB_YES_NO
| WB_DEF_YES
),
624 RemoveList( nRemovePos
);
627 if ( mpLbLists
->GetEntryCount() > 0 )
629 mpLbLists
->SelectEntryPos(
630 ( nRemovePos
>= mpLbLists
->GetEntryCount() )
631 ? mpLbLists
->GetEntryCount()-1
633 LbSelectHdl( *mpLbLists
.get() );
637 mpFtLists
->Disable();
638 mpLbLists
->Disable();
639 mpFtEntries
->Disable();
640 mpEdEntries
->Disable();
641 mpEdEntries
->SetText( EMPTY_OUSTRING
);
642 mpBtnRemove
->Disable();
646 if ( pViewData
&& !bCopyDone
&& !mpBtnCopy
->IsEnabled() )
649 mpFtCopyFrom
->Enable();
650 mpEdCopyFrom
->Enable();
654 else if ( pViewData
&& (pBtn
== mpBtnCopy
) )
659 ScRefAddress theStartPos
;
660 ScRefAddress theEndPos
;
661 OUString
theAreaStr( mpEdCopyFrom
->GetText() );
662 bool bAreaOk
= false;
664 if ( !theAreaStr
.isEmpty() )
666 bAreaOk
= ScRangeUtil::IsAbsArea( theAreaStr
,
668 pViewData
->GetTabNo(),
672 pDoc
->GetAddressConvention() );
675 bAreaOk
= ScRangeUtil::IsAbsPos( theAreaStr
,
677 pViewData
->GetTabNo(),
680 pDoc
->GetAddressConvention() );
681 theEndPos
= theStartPos
;
687 CopyListFromArea( theStartPos
, theEndPos
);
689 mpLbLists
->SelectEntryPos( mpLbLists
->GetEntryCount()-1 );
690 LbSelectHdl( *mpLbLists
.get() );
691 mpEdCopyFrom
->SetText( theAreaStr
);
692 mpEdCopyFrom
->Disable();
693 mpBtnCopy
->Disable();
694 mpFtCopyFrom
->Disable();
698 ScopedVclPtrInstance
<MessageDialog
>(this,
699 ScGlobal::GetRscString( STR_INVALID_TABREF
)
701 mpEdCopyFrom
->GrabFocus();
702 mpEdCopyFrom
->SetSelection( Selection( 0, SELECTION_MAX
) );
707 IMPL_LINK_TYPED( ScTpUserLists
, EdEntriesModHdl
, Edit
&, rEd
, void )
709 if ( &rEd
!= mpEdEntries
)
712 if ( mpBtnCopy
->IsEnabled() )
714 mpBtnCopy
->Disable();
715 mpFtCopyFrom
->Disable();
716 mpEdCopyFrom
->Disable();
719 if ( !mpEdEntries
->GetText().isEmpty() )
721 if ( !bCancelMode
&& !bModifyMode
)
724 mpBtnDiscard
->Show();
729 mpBtnModify
->Enable();
731 mpBtnRemove
->Disable();
732 mpFtLists
->Disable();
733 mpLbLists
->Disable();
735 else // if ( bCancelMode || bModifyMode )
737 if ( !mpBtnAdd
->IsEnabled() )
740 mpBtnModify
->Enable();
746 if ( mpBtnAdd
->IsEnabled() )
749 mpBtnModify
->Disable();
754 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */