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 // STATIC DATA -----------------------------------------------------------
40 #define CR (sal_Unicode)13
41 #define LF (sal_Unicode)10
43 static const sal_Unicode cDelimiter
= ',';
45 // Benutzerdefinierte Listen:
47 ScTpUserLists::ScTpUserLists( vcl::Window
* pParent
,
48 const SfxItemSet
& rCoreAttrs
)
50 : SfxTabPage ( pParent
,
51 "OptSortLists", "modules/scalc/ui/optsortlists.ui",
53 aStrQueryRemove ( ScGlobal::GetRscString( STR_QUERYREMOVE
) ),
54 aStrCopyList ( ScGlobal::GetRscString( STR_COPYLIST
) ),
55 aStrCopyFrom ( ScGlobal::GetRscString( STR_COPYFROM
) ),
56 aStrCopyErr ( ScGlobal::GetRscString( STR_COPYERR
) ),
57 nWhichUserLists ( GetWhich( SID_SCUSERLISTS
) ),
61 pRangeUtil ( new ScRangeUtil
),
62 bModifyMode ( false ),
63 bCancelMode ( false ),
67 get(mpFtLists
, "listslabel");
68 get(mpLbLists
, "lists");
69 get(mpFtEntries
, "entrieslabel");
70 get(mpEdEntries
, "entries");
71 get(mpFtCopyFrom
, "copyfromlabel");
72 get(mpEdCopyFrom
, "copyfrom");
74 get(mpBtnDiscard
, "discard");
76 get(mpBtnModify
, "modify");
77 get(mpBtnRemove
, "delete");
78 get(mpBtnCopy
, "copy");
85 ScTpUserLists::~ScTpUserLists()
90 void ScTpUserLists::dispose()
101 mpBtnDiscard
.clear();
106 SfxTabPage::dispose();
109 void ScTpUserLists::Init()
111 SfxViewShell
* pSh
= SfxViewShell::Current();
112 ScTabViewShell
* pViewSh
= PTR_CAST(ScTabViewShell
, pSh
);
114 mpLbLists
->SetSelectHdl ( LINK( this, ScTpUserLists
, LbSelectHdl
) );
115 mpBtnNew
->SetClickHdl ( LINK( this, ScTpUserLists
, BtnClickHdl
) );
116 mpBtnDiscard
->SetClickHdl ( LINK( this, ScTpUserLists
, BtnClickHdl
) );
117 mpBtnAdd
->SetClickHdl ( LINK( this, ScTpUserLists
, BtnClickHdl
) );
118 mpBtnModify
->SetClickHdl ( LINK( this, ScTpUserLists
, BtnClickHdl
) );
119 mpBtnRemove
->SetClickHdl ( LINK( this, ScTpUserLists
, BtnClickHdl
) );
120 mpEdEntries
->SetModifyHdl ( LINK( this, ScTpUserLists
, EdEntriesModHdl
) );
131 pViewData
= &pViewSh
->GetViewData();
132 pDoc
= pViewData
->GetDocument();
134 pViewData
->GetSimpleArea( nStartCol
, nStartRow
, nStartTab
,
135 nEndCol
, nEndRow
, nEndTab
);
137 PutInOrder( nStartCol
, nEndCol
);
138 PutInOrder( nStartRow
, nEndRow
);
139 PutInOrder( nStartTab
, nEndTab
);
141 aStrSelectedArea
= ScRange( nStartCol
, nStartRow
, nStartTab
, nEndCol
, nEndRow
, nEndTab
142 ).Format(SCR_ABS_3D
, pDoc
);
144 mpBtnCopy
->SetClickHdl ( LINK( this, ScTpUserLists
, BtnClickHdl
) );
149 mpBtnCopy
->Disable();
150 mpFtCopyFrom
->Disable();
151 mpEdCopyFrom
->Disable();
156 VclPtr
<SfxTabPage
> ScTpUserLists::Create( vcl::Window
* pParent
, const SfxItemSet
* rAttrSet
)
158 return VclPtr
<ScTpUserLists
>::Create( pParent
, *rAttrSet
);
161 void ScTpUserLists::Reset( const SfxItemSet
* rCoreAttrs
)
163 const ScUserListItem
& rUserListItem
= static_cast<const ScUserListItem
&>(
164 rCoreAttrs
->Get( nWhichUserLists
));
165 const ScUserList
* pCoreList
= rUserListItem
.GetUserList();
167 OSL_ENSURE( pCoreList
, "UserList not found :-/" );
172 pUserLists
= new ScUserList( *pCoreList
);
174 *pUserLists
= *pCoreList
;
176 if ( UpdateUserListBox() > 0 )
178 mpLbLists
->SelectEntryPos( 0 );
182 else if ( !pUserLists
)
183 pUserLists
= new ScUserList
;
185 mpEdCopyFrom
->SetText( aStrSelectedArea
);
187 if ( mpLbLists
->GetEntryCount() == 0 )
189 mpFtLists
->Disable();
190 mpLbLists
->Disable();
191 mpFtEntries
->Disable();
192 mpEdEntries
->Disable();
193 mpBtnRemove
->Disable();
197 mpBtnDiscard
->Hide();
201 mpBtnModify
->Disable();
203 if ( !bCopyDone
&& pViewData
)
205 mpFtCopyFrom
->Enable();
206 mpEdCopyFrom
->Enable();
211 bool ScTpUserLists::FillItemSet( SfxItemSet
* rCoreAttrs
)
213 // Modifikationen noch nicht uebernommen?
214 // -> Click auf Add-Button simulieren
216 if ( bModifyMode
|| bCancelMode
)
217 BtnClickHdl( mpBtnAdd
);
219 const ScUserListItem
& rUserListItem
= static_cast<const ScUserListItem
&>(
220 GetItemSet().Get( nWhichUserLists
));
222 ScUserList
* pCoreList
= rUserListItem
.GetUserList();
223 bool bDataModified
= false;
225 if ( (pUserLists
== NULL
) && (pCoreList
== NULL
) )
227 bDataModified
= false;
229 else if ( pUserLists
!= NULL
)
231 if ( pCoreList
!= NULL
)
232 bDataModified
= (*pUserLists
!= *pCoreList
);
234 bDataModified
= true;
239 ScUserListItem
aULItem( nWhichUserLists
);
242 aULItem
.SetUserList( *pUserLists
);
244 rCoreAttrs
->Put( aULItem
);
247 return bDataModified
;
250 SfxTabPage::sfxpg
ScTpUserLists::DeactivatePage( SfxItemSet
* pSetP
)
253 FillItemSet( pSetP
);
258 size_t ScTpUserLists::UpdateUserListBox()
262 if ( !pUserLists
) return 0;
264 size_t nCount
= pUserLists
->size();
267 for ( size_t i
=0; i
<nCount
; ++i
)
269 aEntry
= (*pUserLists
)[i
]->GetString();
270 OSL_ENSURE( !aEntry
.isEmpty(), "Empty UserList-entry :-/" );
271 mpLbLists
->InsertEntry( aEntry
);
277 void ScTpUserLists::UpdateEntries( size_t nList
)
279 if ( !pUserLists
) return;
281 if ( nList
< pUserLists
->size() )
283 const ScUserListData
* pList
= (*pUserLists
)[nList
];
284 std::size_t nSubCount
= pList
->GetSubCount();
285 OUString aEntryListStr
;
287 for ( sal_uInt16 i
=0; i
<nSubCount
; i
++ )
290 aEntryListStr
+= OUString(CR
);
291 aEntryListStr
+= pList
->GetSubStr(i
);
294 mpEdEntries
->SetText(convertLineEnd(aEntryListStr
, GetSystemLineEnd()));
298 OSL_FAIL( "Invalid ListIndex :-/" );
302 void ScTpUserLists::MakeListStr( OUString
& rListStr
)
306 sal_Int32 nToken
= comphelper::string::getTokenCount(rListStr
, LF
);
308 for(sal_Int32 i
=0; i
<nToken
; i
++)
310 OUString aString
= comphelper::string::strip(rListStr
.getToken(i
, LF
), ' ');
312 aStr
+= OUString(cDelimiter
);
315 aStr
= comphelper::string::strip(aStr
, cDelimiter
);
316 sal_Int32 nLen
= aStr
.getLength();
320 // Alle Doppelten cDelimiter entfernen:
324 rListStr
+= OUString(aStr
[c
]);
327 if ((c
< nLen
) && (aStr
[c
] == cDelimiter
))
329 rListStr
+= OUString(aStr
[c
]);
331 while ((c
< nLen
) && (aStr
[c
] == cDelimiter
))
338 void ScTpUserLists::AddNewList( const OUString
& rEntriesStr
)
340 OUString
theEntriesStr( rEntriesStr
);
343 pUserLists
= new ScUserList
;
345 MakeListStr( theEntriesStr
);
347 pUserLists
->push_back(new ScUserListData(theEntriesStr
));
350 void ScTpUserLists::CopyListFromArea( const ScRefAddress
& rStartPos
,
351 const ScRefAddress
& rEndPos
)
353 if ( bCopyDone
) return;
355 SCTAB nTab
= rStartPos
.Tab();
356 SCCOL nStartCol
= rStartPos
.Col();
357 SCROW nStartRow
= rStartPos
.Row();
358 SCCOL nEndCol
= rEndPos
.Col();
359 SCROW nEndRow
= rEndPos
.Row();
360 sal_uInt16 nCellDir
= SCRET_COLS
;
362 if ( (nStartCol
!= nEndCol
) && (nStartRow
!= nEndRow
) )
364 nCellDir
= ScopedVclPtr
<ScColOrRowDlg
>::Create( this, aStrCopyList
, aStrCopyFrom
)->Execute();
366 else if ( nStartCol
!= nEndCol
)
367 nCellDir
= SCRET_ROWS
;
369 nCellDir
= SCRET_COLS
;
371 if ( nCellDir
!= RET_CANCEL
)
373 bool bValueIgnored
= false;
377 if ( nCellDir
== SCRET_COLS
)
379 for ( SCCOL col
=nStartCol
; col
<=nEndCol
; col
++ )
381 for ( SCROW row
=nStartRow
; row
<=nEndRow
; row
++ )
383 if ( pDoc
->HasStringData( col
, row
, nTab
) )
385 aStrField
= pDoc
->GetString(col
, row
, nTab
);
387 if ( !aStrField
.isEmpty() )
389 aStrList
+= aStrField
;
394 bValueIgnored
= true;
396 if ( !aStrList
.isEmpty() )
397 AddNewList( aStrList
);
403 for ( SCROW row
=nStartRow
; row
<=nEndRow
; row
++ )
405 for ( SCCOL col
=nStartCol
; col
<=nEndCol
; col
++ )
407 if ( pDoc
->HasStringData( col
, row
, nTab
) )
409 aStrField
= pDoc
->GetString(col
, row
, nTab
);
411 if ( !aStrField
.isEmpty() )
413 aStrList
+= aStrField
;
418 bValueIgnored
= true;
420 if ( !aStrList
.isEmpty() )
421 AddNewList( aStrList
);
428 ScopedVclPtr
<InfoBox
>::Create( this, aStrCopyErr
)->Execute();
436 void ScTpUserLists::ModifyList( size_t nSelList
,
437 const OUString
& rEntriesStr
)
439 if ( !pUserLists
) return;
441 OUString
theEntriesStr( rEntriesStr
);
443 MakeListStr( theEntriesStr
);
445 (*pUserLists
)[nSelList
]->SetString( theEntriesStr
);
448 void ScTpUserLists::RemoveList( size_t nList
)
450 if (pUserLists
&& nList
< pUserLists
->size())
452 ScUserList::iterator itr
= pUserLists
->begin();
453 ::std::advance(itr
, nList
);
454 pUserLists
->erase(itr
);
460 IMPL_LINK( ScTpUserLists
, LbSelectHdl
, ListBox
*, pLb
)
462 if ( pLb
== mpLbLists
)
464 sal_Int32 nSelPos
= mpLbLists
->GetSelectEntryPos();
465 if ( nSelPos
!= LISTBOX_ENTRY_NOTFOUND
)
467 if ( !mpFtEntries
->IsEnabled() ) mpFtEntries
->Enable();
468 if ( !mpEdEntries
->IsEnabled() ) mpEdEntries
->Enable();
469 if ( !mpBtnRemove
->IsEnabled() ) mpBtnRemove
->Enable();
470 if ( mpBtnAdd
->IsEnabled() )
473 mpBtnModify
->Disable();
476 UpdateEntries( nSelPos
);
483 IMPL_LINK( ScTpUserLists
, BtnClickHdl
, PushButton
*, pBtn
)
485 if ( pBtn
== mpBtnNew
|| pBtn
== mpBtnDiscard
)
489 nCancelPos
= ( mpLbLists
->GetEntryCount() > 0 )
490 ? mpLbLists
->GetSelectEntryPos()
492 mpLbLists
->SetNoSelection();
493 mpFtLists
->Disable();
494 mpLbLists
->Disable();
495 mpFtEntries
->Enable();
496 mpEdEntries
->Enable();
497 mpEdEntries
->SetText( EMPTY_OUSTRING
);
498 mpEdEntries
->GrabFocus();
500 mpBtnModify
->Disable();
501 mpBtnRemove
->Disable();
503 if ( mpBtnCopy
->IsEnabled() )
505 mpBtnCopy
->Disable();
506 mpFtCopyFrom
->Disable();
507 mpEdCopyFrom
->Disable();
510 mpBtnDiscard
->Show();
513 else // if ( bCancelMode )
515 if ( mpLbLists
->GetEntryCount() > 0 )
517 mpLbLists
->SelectEntryPos( nCancelPos
);
518 LbSelectHdl( mpLbLists
);
524 mpFtEntries
->Disable();
525 mpEdEntries
->Disable();
526 mpEdEntries
->SetText( EMPTY_OUSTRING
);
527 mpBtnRemove
->Disable();
530 mpBtnModify
->Disable();
532 if ( pViewData
&& !bCopyDone
)
535 mpFtCopyFrom
->Enable();
536 mpEdCopyFrom
->Enable();
539 mpBtnDiscard
->Hide();
544 else if (pBtn
== mpBtnAdd
|| pBtn
== mpBtnModify
)
546 OUString
theEntriesStr( mpEdEntries
->GetText() );
550 if ( !theEntriesStr
.isEmpty() )
552 AddNewList( theEntriesStr
);
554 mpLbLists
->SelectEntryPos( mpLbLists
->GetEntryCount()-1 );
555 LbSelectHdl( mpLbLists
);
561 if ( mpLbLists
->GetEntryCount() > 0 )
563 mpLbLists
->SelectEntryPos( nCancelPos
);
564 LbSelectHdl( mpLbLists
);
571 mpBtnModify
->Disable();
572 mpBtnRemove
->Enable();
574 mpBtnDiscard
->Hide();
577 else // if ( bModifyMode )
579 sal_Int32 nSelList
= mpLbLists
->GetSelectEntryPos();
581 OSL_ENSURE( nSelList
!= LISTBOX_ENTRY_NOTFOUND
, "Modify without List :-/" );
583 if ( !theEntriesStr
.isEmpty() )
585 ModifyList( nSelList
, theEntriesStr
);
587 mpLbLists
->SelectEntryPos( nSelList
);
591 mpLbLists
->SelectEntryPos( 0 );
592 LbSelectHdl( mpLbLists
);
596 mpBtnDiscard
->Hide();
601 mpBtnModify
->Disable();
603 mpBtnRemove
->Enable();
608 if ( pViewData
&& !bCopyDone
)
611 mpFtCopyFrom
->Enable();
612 mpEdCopyFrom
->Enable();
615 else if ( pBtn
== mpBtnRemove
)
617 if ( mpLbLists
->GetEntryCount() > 0 )
619 sal_Int32 nRemovePos
= mpLbLists
->GetSelectEntryPos();
620 OUString
aMsg ( aStrQueryRemove
.getToken( 0, '#' ) );
622 aMsg
+= mpLbLists
->GetEntry( nRemovePos
);
623 aMsg
+= aStrQueryRemove
.getToken( 1, '#' );
625 if ( RET_YES
== ScopedVclPtr
<QueryBox
>::Create( this,
626 WinBits( WB_YES_NO
| WB_DEF_YES
),
630 RemoveList( nRemovePos
);
633 if ( mpLbLists
->GetEntryCount() > 0 )
635 mpLbLists
->SelectEntryPos(
636 ( nRemovePos
>= mpLbLists
->GetEntryCount() )
637 ? mpLbLists
->GetEntryCount()-1
639 LbSelectHdl( mpLbLists
);
643 mpFtLists
->Disable();
644 mpLbLists
->Disable();
645 mpFtEntries
->Disable();
646 mpEdEntries
->Disable();
647 mpEdEntries
->SetText( EMPTY_OUSTRING
);
648 mpBtnRemove
->Disable();
652 if ( pViewData
&& !bCopyDone
&& !mpBtnCopy
->IsEnabled() )
655 mpFtCopyFrom
->Enable();
656 mpEdCopyFrom
->Enable();
660 else if ( pViewData
&& (pBtn
== mpBtnCopy
) )
665 ScRefAddress theStartPos
;
666 ScRefAddress theEndPos
;
667 OUString
theAreaStr( mpEdCopyFrom
->GetText() );
668 bool bAreaOk
= false;
670 if ( !theAreaStr
.isEmpty() )
672 bAreaOk
= ScRangeUtil::IsAbsArea( theAreaStr
,
674 pViewData
->GetTabNo(),
678 pDoc
->GetAddressConvention() );
681 bAreaOk
= ScRangeUtil::IsAbsPos( theAreaStr
,
683 pViewData
->GetTabNo(),
686 pDoc
->GetAddressConvention() );
687 theEndPos
= theStartPos
;
693 CopyListFromArea( theStartPos
, theEndPos
);
695 mpLbLists
->SelectEntryPos( mpLbLists
->GetEntryCount()-1 );
696 LbSelectHdl( mpLbLists
);
697 mpEdCopyFrom
->SetText( theAreaStr
);
698 mpEdCopyFrom
->Disable();
699 mpBtnCopy
->Disable();
700 mpFtCopyFrom
->Disable();
704 ScopedVclPtr
<MessageDialog
>::Create(this,
705 ScGlobal::GetRscString( STR_INVALID_TABREF
)
707 mpEdCopyFrom
->GrabFocus();
708 mpEdCopyFrom
->SetSelection( Selection( 0, SELECTION_MAX
) );
715 IMPL_LINK( ScTpUserLists
, EdEntriesModHdl
, VclMultiLineEdit
*, pEd
)
717 if ( pEd
!= mpEdEntries
)
720 if ( mpBtnCopy
->IsEnabled() )
722 mpBtnCopy
->Disable();
723 mpFtCopyFrom
->Disable();
724 mpEdCopyFrom
->Disable();
727 if ( !mpEdEntries
->GetText().isEmpty() )
729 if ( !bCancelMode
&& !bModifyMode
)
732 mpBtnDiscard
->Show();
737 mpBtnModify
->Enable();
739 mpBtnRemove
->Disable();
740 mpFtLists
->Disable();
741 mpLbLists
->Disable();
743 else // if ( bCancelMode || bModifyMode )
745 if ( !mpBtnAdd
->IsEnabled() )
748 mpBtnModify
->Enable();
754 if ( mpBtnAdd
->IsEnabled() )
757 mpBtnModify
->Disable();
764 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */