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 .
24 #include <vcl/svapp.hxx>
25 #include <vcl/weld.hxx>
26 #include <svl/intitem.hxx>
27 #include <svl/eitem.hxx>
28 #include <sfx2/dispatch.hxx>
29 #include <svx/svxids.hrc>
30 #include <editeng/unolingu.hxx>
31 #include <svx/svxdlg.hxx>
32 #include <svx/dialogs.hrc>
33 #include <unotools/collatorwrapper.hxx>
34 #include <svtools/collatorres.hxx>
40 #include <strings.hrc>
41 #include <swtable.hxx>
42 #include <sortopt.hxx>
45 #include <sfx2/request.hxx>
48 static bool bCheck1
= true;
49 static bool bCheck2
= false;
50 static bool bCheck3
= false;
52 static sal_uInt16 nCol1
= 1;
53 static sal_uInt16 nCol2
= 1;
54 static sal_uInt16 nCol3
= 1;
56 static sal_uInt16 nType1
= 0;
57 static sal_uInt16 nType2
= 0;
58 static sal_uInt16 nType3
= 0;
60 static LanguageType nLang
= LANGUAGE_NONE
;
62 static bool bAsc1
= true;
63 static bool bAsc2
= true;
64 static bool bAsc3
= true;
65 static bool bCol
= false;
66 static bool bCsSens
= false;
68 static sal_Unicode cDeli
= '\t';
70 using namespace ::com::sun::star::lang
;
71 using namespace ::com::sun::star::uno
;
72 using namespace ::com::sun::star
;
74 // determine lines and columns for table selection
75 static bool lcl_GetSelTable( SwWrtShell
const &rSh
, sal_uInt16
& rX
, sal_uInt16
& rY
)
77 const SwTableNode
* pTableNd
= rSh
.IsCursorInTable();
81 FndBox_
aFndBox( nullptr, nullptr );
83 // look for all boxes / lines
86 ::GetTableSel( rSh
, aSelBoxes
);
87 FndPara
aPara( aSelBoxes
, &aFndBox
);
88 const SwTable
& rTable
= pTableNd
->GetTable();
89 ForEach_FndLineCopyCol( const_cast<SwTableLines
&>(rTable
.GetTabLines()), &aPara
);
91 rX
= aFndBox
.GetLines().size();
95 rY
= aFndBox
.GetLines().front()->GetBoxes().size();
100 SwSortDlg::SwSortDlg(weld::Window
* pParent
, SwWrtShell
&rShell
)
101 : GenericDialogController(pParent
, "modules/swriter/ui/sortdialog.ui", "SortDialog")
103 , m_xColLbl(m_xBuilder
->weld_label("column"))
104 , m_xKeyCB1(m_xBuilder
->weld_check_button("key1"))
105 , m_xColEdt1(m_xBuilder
->weld_spin_button("colsb1"))
106 , m_xTypDLB1(m_xBuilder
->weld_combo_box("typelb1"))
107 , m_xSortUp1RB(m_xBuilder
->weld_radio_button("up1"))
108 , m_xSortDn1RB(m_xBuilder
->weld_radio_button("down1"))
109 , m_xKeyCB2(m_xBuilder
->weld_check_button("key2"))
110 , m_xColEdt2(m_xBuilder
->weld_spin_button("colsb2"))
111 , m_xTypDLB2(m_xBuilder
->weld_combo_box("typelb2"))
112 , m_xSortUp2RB(m_xBuilder
->weld_radio_button("up2"))
113 , m_xSortDn2RB(m_xBuilder
->weld_radio_button("down2"))
114 , m_xKeyCB3(m_xBuilder
->weld_check_button("key3"))
115 , m_xColEdt3(m_xBuilder
->weld_spin_button("colsb3"))
116 , m_xTypDLB3(m_xBuilder
->weld_combo_box("typelb3"))
117 , m_xSortUp3RB(m_xBuilder
->weld_radio_button("up3"))
118 , m_xSortDn3RB(m_xBuilder
->weld_radio_button("down3"))
119 , m_xColumnRB(m_xBuilder
->weld_radio_button("columns"))
120 , m_xRowRB(m_xBuilder
->weld_radio_button("rows"))
121 , m_xDelimTabRB(m_xBuilder
->weld_radio_button("tabs"))
122 , m_xDelimFreeRB(m_xBuilder
->weld_radio_button("character"))
123 , m_xDelimEdt(m_xBuilder
->weld_entry("separator"))
124 , m_xDelimPB(m_xBuilder
->weld_button("delimpb"))
125 , m_xLangLB(new SvxLanguageBox(m_xBuilder
->weld_combo_box("langlb")))
126 , m_xCaseCB(m_xBuilder
->weld_check_button("matchcase"))
127 , aColText(SwResId(STR_COL
))
128 , aRowText(SwResId(STR_ROW
))
129 , aNumericText(SwResId(STR_NUMERIC
))
134 if(rSh
.GetSelectionType() &
135 (SelectionType::Table
|SelectionType::TableCell
) )
137 m_xColumnRB
->set_active(bCol
);
138 m_xColLbl
->set_label(bCol
? aRowText
: aColText
);
139 m_xRowRB
->set_active(!bCol
);
140 m_xDelimTabRB
->set_sensitive(false);
141 m_xDelimFreeRB
->set_sensitive(false);
142 m_xDelimEdt
->set_sensitive(false);
146 m_xColumnRB
->set_sensitive(false);
147 m_xRowRB
->set_active(true);
148 m_xColLbl
->set_label(aColText
);
151 // Set accessible names here because text of m_xColLbl may be changed
152 // by the if-else block above
153 m_xColEdt1
->set_accessible_name(m_xColLbl
->get_label());
154 m_xColEdt2
->set_accessible_name(m_xColLbl
->get_label());
155 m_xColEdt3
->set_accessible_name(m_xColLbl
->get_label());
158 Link
<weld::ToggleButton
&,void> aLk
= LINK(this, SwSortDlg
, CheckHdl
);
159 m_xKeyCB1
->connect_toggled( aLk
);
160 m_xKeyCB2
->connect_toggled( aLk
);
161 m_xKeyCB3
->connect_toggled( aLk
);
162 m_xColumnRB
->connect_toggled( aLk
);
163 m_xRowRB
->connect_toggled( aLk
);
165 aLk
= LINK(this, SwSortDlg
, DelimHdl
);
166 m_xDelimFreeRB
->connect_toggled(aLk
);
167 m_xDelimTabRB
->connect_toggled(aLk
);
169 m_xDelimPB
->connect_clicked( LINK( this, SwSortDlg
, DelimCharHdl
));
171 m_xKeyCB1
->set_active(bCheck1
);
172 m_xKeyCB2
->set_active(bCheck2
);
173 m_xKeyCB3
->set_active(bCheck3
);
175 m_xColEdt1
->set_value(nCol1
);
176 m_xColEdt2
->set_value(nCol2
);
177 m_xColEdt3
->set_value(nCol3
);
179 // first initialise the language, then select the
180 if( LANGUAGE_NONE
== nLang
|| LANGUAGE_DONTKNOW
== nLang
)
181 nLang
= GetAppLanguage();
183 m_xLangLB
->SetLanguageList( SvxLanguageListFlags::ALL
| SvxLanguageListFlags::ONLY_KNOWN
, true );
184 m_xLangLB
->set_active_id(nLang
);
186 LanguageHdl( nullptr );
187 m_xLangLB
->connect_changed( LINK( this, SwSortDlg
, LanguageListBoxHdl
));
189 m_xSortUp1RB
->set_active(bAsc1
);
190 m_xSortDn1RB
->set_active(!bAsc1
);
191 m_xSortUp2RB
->set_active(bAsc2
);
192 m_xSortDn2RB
->set_active(!bAsc2
);
193 m_xSortUp3RB
->set_active(bAsc3
);
194 m_xSortDn3RB
->set_active(!bAsc3
);
196 m_xCaseCB
->set_active( bCsSens
);
198 m_xDelimTabRB
->set_active(cDeli
== '\t');
199 if(!m_xDelimTabRB
->get_active())
201 m_xDelimEdt
->set_text(OUString(cDeli
));
202 m_xDelimFreeRB
->set_active(true);
203 DelimHdl(*m_xDelimFreeRB
);
206 DelimHdl(*m_xDelimTabRB
);
208 if( ::lcl_GetSelTable( rSh
, nX
, nY
) )
210 sal_uInt16 nMax
= m_xRowRB
->get_active()? nY
: nX
;
211 m_xColEdt1
->set_max(nMax
);
212 m_xColEdt2
->set_max(nMax
);
213 m_xColEdt3
->set_max(nMax
);
217 sal_Unicode
SwSortDlg::GetDelimChar() const
219 sal_Unicode cRet
= '\t';
220 if( !m_xDelimTabRB
->get_active() )
222 OUString
aTmp(m_xDelimEdt
->get_text());
223 if( !aTmp
.isEmpty() )
229 short SwSortDlg::run()
231 short nRet
= GenericDialogController::run();
237 // pass on to the Core
238 void SwSortDlg::Apply()
241 bCheck1
= m_xKeyCB1
->get_active();
242 bCheck2
= m_xKeyCB2
->get_active();
243 bCheck3
= m_xKeyCB3
->get_active();
245 nCol1
= m_xColEdt1
->get_value();
246 nCol2
= m_xColEdt2
->get_value();
247 nCol3
= m_xColEdt3
->get_value();
249 nType1
= m_xTypDLB1
->get_active();
250 nType2
= m_xTypDLB2
->get_active();
251 nType3
= m_xTypDLB3
->get_active();
253 bAsc1
= m_xSortUp1RB
->get_active();
254 bAsc2
= m_xSortUp2RB
->get_active();
255 bAsc3
= m_xSortUp3RB
->get_active();
256 bCol
= m_xColumnRB
->get_active();
257 nLang
= m_xLangLB
->get_active_id();
258 cDeli
= GetDelimChar();
259 bCsSens
= m_xCaseCB
->get_active();
261 SwSortOptions aOptions
;
264 OUString
sEntry( m_xTypDLB1
->get_active_text() );
265 if( sEntry
== aNumericText
)
267 else if (!m_xTypDLB1
->get_active_id().isEmpty())
268 sEntry
= m_xTypDLB1
->get_active_id();
270 aOptions
.aKeys
.push_back(
271 std::make_unique
<SwSortKey
>( nCol1
, sEntry
,
272 bAsc1
? SRT_ASCENDING
: SRT_DESCENDING
));
277 OUString
sEntry( m_xTypDLB2
->get_active_text() );
278 if( sEntry
== aNumericText
)
280 else if (!m_xTypDLB2
->get_active_id().isEmpty())
281 sEntry
= m_xTypDLB2
->get_active_id();
283 aOptions
.aKeys
.push_back(
284 std::make_unique
<SwSortKey
>( nCol2
, sEntry
,
285 bAsc2
? SRT_ASCENDING
: SRT_DESCENDING
));
290 OUString
sEntry( m_xTypDLB3
->get_active_text() );
291 if( sEntry
== aNumericText
)
293 else if (!m_xTypDLB3
->get_active_id().isEmpty())
294 sEntry
= m_xTypDLB3
->get_active_id();
296 aOptions
.aKeys
.push_back(
297 std::make_unique
<SwSortKey
>( nCol3
, sEntry
,
298 bAsc3
? SRT_ASCENDING
: SRT_DESCENDING
));
301 aOptions
.eDirection
= bCol
? SRT_COLUMNS
: SRT_ROWS
;
302 aOptions
.cDeli
= cDeli
;
303 aOptions
.nLanguage
= nLang
;
304 aOptions
.bTable
= rSh
.IsTableMode();
305 aOptions
.bIgnoreCase
= !bCsSens
;
309 SwWait
aWait( *rSh
.GetView().GetDocShell(), true );
310 rSh
.StartAllAction();
311 bRet
= rSh
.Sort( aOptions
);
319 std::unique_ptr
<weld::MessageDialog
> xInfoBox(Application::CreateMessageDialog(m_pParent
,
320 VclMessageType::Info
, VclButtonsType::Ok
,
321 SwResId(STR_SRTERR
)));
326 IMPL_LINK( SwSortDlg
, DelimHdl
, weld::ToggleButton
&, rButton
, void )
328 bool bEnable
= &rButton
== m_xDelimFreeRB
.get() && m_xDelimFreeRB
->get_sensitive();
329 m_xDelimEdt
->set_sensitive( bEnable
);
330 m_xDelimPB
->set_sensitive( bEnable
);
333 IMPL_LINK_NOARG(SwSortDlg
, DelimCharHdl
, weld::Button
&, void)
335 SvxAbstractDialogFactory
* pFact
= SvxAbstractDialogFactory::Create();
336 SfxAllItemSet
aSet( rSh
.GetAttrPool() );
337 aSet
.Put( SfxInt32Item( SID_ATTR_CHAR
, GetDelimChar() ) );
338 ScopedVclPtr
<SfxAbstractDialog
> pMap(pFact
->CreateCharMapDialog(m_xDialog
.get(), aSet
, nullptr));
339 if( RET_OK
== pMap
->Execute() )
341 const SfxInt32Item
* pItem
= SfxItemSet::GetItem
<SfxInt32Item
>(pMap
->GetOutputItemSet(), SID_ATTR_CHAR
, false);
343 m_xDelimEdt
->set_text(OUString(sal_Unicode(pItem
->GetValue())));
347 IMPL_LINK( SwSortDlg
, CheckHdl
, weld::ToggleButton
&, rControl
, void )
349 if (&rControl
== m_xRowRB
.get())
351 m_xColLbl
->set_label(aColText
);
352 m_xColEdt1
->set_max(nY
);
353 m_xColEdt2
->set_max(nY
);
354 m_xColEdt3
->set_max(nY
);
356 m_xColEdt1
->set_accessible_name(aColText
);
357 m_xColEdt2
->set_accessible_name(aColText
);
358 m_xColEdt3
->set_accessible_name(aColText
);
360 else if (&rControl
== m_xColumnRB
.get())
362 m_xColLbl
->set_label(aRowText
);
363 m_xColEdt1
->set_max(nX
);
364 m_xColEdt2
->set_max(nX
);
365 m_xColEdt3
->set_max(nX
);
367 m_xColEdt1
->set_accessible_name(aRowText
);
368 m_xColEdt2
->set_accessible_name(aRowText
);
369 m_xColEdt3
->set_accessible_name(aRowText
);
371 else if(!m_xKeyCB1
->get_active() &&
372 !m_xKeyCB2
->get_active() &&
373 !m_xKeyCB3
->get_active())
375 rControl
.set_active(true);
379 IMPL_LINK( SwSortDlg
, LanguageListBoxHdl
, weld::ComboBox
&, rLBox
, void )
384 void SwSortDlg::LanguageHdl(weld::ComboBox
const* pLBox
)
386 Sequence
< OUString
> aSeq( GetAppCollator().listCollatorAlgorithms(
387 LanguageTag( m_xLangLB
->get_active_id()).getLocale() ));
390 m_xColRes
.reset(new CollatorResource
);
392 const int nLstBoxCnt
= 3;
393 weld::ComboBox
* aLstArr
[ nLstBoxCnt
] = { m_xTypDLB1
.get(), m_xTypDLB2
.get(), m_xTypDLB3
.get() };
394 sal_uInt16
* const aTypeArr
[ nLstBoxCnt
] = { &nType1
, &nType2
, &nType3
};
395 OUString aOldStrArr
[ nLstBoxCnt
];
397 for( int n
= 0; n
< nLstBoxCnt
; ++n
)
399 weld::ComboBox
* pL
= aLstArr
[ n
];
400 OUString sUserData
= pL
->get_active_id();
401 if (!sUserData
.isEmpty())
402 aOldStrArr
[ n
] = sUserData
;
406 OUString sAlg
, sUINm
;
407 const sal_Int32 nEnd
= aSeq
.getLength();
408 for( sal_Int32 nCnt
= 0; nCnt
<= nEnd
; ++nCnt
)
413 sUINm
= m_xColRes
->GetTranslation( sAlg
);
416 sUINm
= sAlg
= aNumericText
;
418 for( int n
= 0; n
< nLstBoxCnt
; ++n
)
420 weld::ComboBox
* pL
= aLstArr
[ n
];
421 pL
->append(sAlg
, sUINm
);
422 if (pLBox
&& sAlg
== aOldStrArr
[n
])
423 pL
->set_active_id(sAlg
);
427 for( int n
= 0; n
< nLstBoxCnt
; ++n
)
429 weld::ComboBox
* pL
= aLstArr
[ n
];
431 pL
->set_active(*aTypeArr
[n
]);
432 else if (pL
->get_active() == -1)
437 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */