LibreOffice Module sw (master) 1
srtdlg.cxx
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
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/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
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 .
18 */
19
20#include <srtdlg.hxx>
21
22#include <editeng/editids.hrc>
23#include <vcl/svapp.hxx>
24#include <vcl/weld.hxx>
25#include <svl/intitem.hxx>
26#include <svx/svxdlg.hxx>
29#include <swwait.hxx>
30#include <view.hxx>
31#include <wrtsh.hxx>
32#include <strings.hrc>
33#include <swtable.hxx>
34#include <sortopt.hxx>
35#include <node.hxx>
36#include <tblsel.hxx>
37#include <memory>
38
39static bool bCheck1 = true;
40static bool bCheck2 = false;
41static bool bCheck3 = false;
42
43static sal_uInt16 nCol1 = 1;
44static sal_uInt16 nCol2 = 1;
45static sal_uInt16 nCol3 = 1;
46
47static sal_uInt16 nType1 = 0;
48static sal_uInt16 nType2 = 0;
49static sal_uInt16 nType3 = 0;
50
52
53static bool bAsc1 = true;
54static bool bAsc2 = true;
55static bool bAsc3 = true;
56static bool bCol = false;
57static bool bCsSens= false;
58
59static sal_Unicode cDeli = '\t';
60
61using namespace ::com::sun::star::lang;
62using namespace ::com::sun::star::uno;
63using namespace ::com::sun::star;
64
65// determine lines and columns for table selection
66static bool lcl_GetSelTable( SwWrtShell const &rSh, sal_uInt16& rX, sal_uInt16& rY )
67{
68 const SwTableNode* pTableNd = rSh.IsCursorInTable();
69 if( !pTableNd )
70 return false;
71
72 FndBox_ aFndBox( nullptr, nullptr );
73
74 // look for all boxes / lines
75 {
76 SwSelBoxes aSelBoxes;
77 ::GetTableSel( rSh, aSelBoxes );
78 FndPara aPara( aSelBoxes, &aFndBox );
79 const SwTable& rTable = pTableNd->GetTable();
80 ForEach_FndLineCopyCol( const_cast<SwTableLines&>(rTable.GetTabLines()), &aPara );
81 }
82 rX = aFndBox.GetLines().size();
83 if( !rX )
84 return false;
85
86 rY = aFndBox.GetLines().front()->GetBoxes().size();
87 return true;
88}
89
90// init list
92 : GenericDialogController(pParent, "modules/swriter/ui/sortdialog.ui", "SortDialog")
93 , m_pParent(pParent)
94 , m_xColLbl(m_xBuilder->weld_label("column"))
95 , m_xKeyCB1(m_xBuilder->weld_check_button("key1"))
96 , m_xColEdt1(m_xBuilder->weld_spin_button("colsb1"))
97 , m_xTypDLB1(m_xBuilder->weld_combo_box("typelb1"))
98 , m_xSortUp1RB(m_xBuilder->weld_radio_button("up1"))
99 , m_xSortDn1RB(m_xBuilder->weld_radio_button("down1"))
100 , m_xKeyCB2(m_xBuilder->weld_check_button("key2"))
101 , m_xColEdt2(m_xBuilder->weld_spin_button("colsb2"))
102 , m_xTypDLB2(m_xBuilder->weld_combo_box("typelb2"))
103 , m_xSortUp2RB(m_xBuilder->weld_radio_button("up2"))
104 , m_xSortDn2RB(m_xBuilder->weld_radio_button("down2"))
105 , m_xKeyCB3(m_xBuilder->weld_check_button("key3"))
106 , m_xColEdt3(m_xBuilder->weld_spin_button("colsb3"))
107 , m_xTypDLB3(m_xBuilder->weld_combo_box("typelb3"))
108 , m_xSortUp3RB(m_xBuilder->weld_radio_button("up3"))
109 , m_xSortDn3RB(m_xBuilder->weld_radio_button("down3"))
110 , m_xColumnRB(m_xBuilder->weld_radio_button("columns"))
111 , m_xRowRB(m_xBuilder->weld_radio_button("rows"))
112 , m_xDelimTabRB(m_xBuilder->weld_radio_button("tabs"))
113 , m_xDelimFreeRB(m_xBuilder->weld_radio_button("character"))
114 , m_xDelimEdt(m_xBuilder->weld_entry("separator"))
115 , m_xDelimPB(m_xBuilder->weld_button("delimpb"))
116 , m_xLangLB(new SvxLanguageBox(m_xBuilder->weld_combo_box("langlb")))
117 , m_xCaseCB(m_xBuilder->weld_check_button("matchcase"))
118 , aColText(SwResId(STR_COL))
119 , aRowText(SwResId(STR_ROW))
120 , aNumericText(SwResId(STR_NUMERIC))
121 , rSh(rShell)
122 , nX(99)
123 , nY(99)
124{
125 if(rSh.GetSelectionType() &
127 {
128 m_xColumnRB->set_active(bCol);
129 m_xColLbl->set_label(bCol ? aRowText : aColText);
130 m_xRowRB->set_active(!bCol);
131 m_xDelimTabRB->set_sensitive(false);
132 m_xDelimFreeRB->set_sensitive(false);
133 m_xDelimEdt->set_sensitive(false);
134 }
135 else
136 {
137 m_xColumnRB->set_sensitive(false);
138 m_xRowRB->set_active(true);
139 m_xColLbl->set_label(aColText);
140 }
141
142 // Set accessible names here because text of m_xColLbl may be changed
143 // by the if-else block above
144 m_xColEdt1->set_accessible_name(m_xColLbl->get_label());
145 m_xColEdt2->set_accessible_name(m_xColLbl->get_label());
146 m_xColEdt3->set_accessible_name(m_xColLbl->get_label());
147
148 // initialise
149 Link<weld::Toggleable&,void> aLk = LINK(this, SwSortDlg, CheckHdl);
150 m_xKeyCB1->connect_toggled( aLk );
151 m_xKeyCB2->connect_toggled( aLk );
152 m_xKeyCB3->connect_toggled( aLk );
153 m_xColumnRB->connect_toggled( aLk );
154 m_xRowRB->connect_toggled( aLk );
155
156 aLk = LINK(this, SwSortDlg, DelimHdl);
157 m_xDelimFreeRB->connect_toggled(aLk);
158 m_xDelimTabRB->connect_toggled(aLk);
159
160 m_xDelimPB->connect_clicked( LINK( this, SwSortDlg, DelimCharHdl ));
161
162 m_xKeyCB1->set_active(bCheck1);
163 m_xKeyCB2->set_active(bCheck2);
164 m_xKeyCB3->set_active(bCheck3);
165
166 m_xColEdt1->set_value(nCol1);
167 m_xColEdt2->set_value(nCol2);
168 m_xColEdt3->set_value(nCol3);
169
170 // first initialise the language, then select the
173
174 m_xLangLB->SetLanguageList( SvxLanguageListFlags::ALL | SvxLanguageListFlags::ONLY_KNOWN, true );
175 m_xLangLB->set_active_id(nLang);
176
177 LanguageHdl( nullptr );
178 m_xLangLB->connect_changed( LINK( this, SwSortDlg, LanguageListBoxHdl ));
179
180 m_xSortUp1RB->set_active(bAsc1);
181 m_xSortDn1RB->set_active(!bAsc1);
182 m_xSortUp2RB->set_active(bAsc2);
183 m_xSortDn2RB->set_active(!bAsc2);
184 m_xSortUp3RB->set_active(bAsc3);
185 m_xSortDn3RB->set_active(!bAsc3);
186
187 m_xCaseCB->set_active( bCsSens );
188
189 m_xDelimTabRB->set_active(cDeli == '\t');
190 if(!m_xDelimTabRB->get_active())
191 {
192 m_xDelimEdt->set_text(OUString(cDeli));
193 m_xDelimFreeRB->set_active(true);
194 DelimHdl(*m_xDelimFreeRB);
195 }
196 else
197 DelimHdl(*m_xDelimTabRB);
198
199 if( ::lcl_GetSelTable( rSh, nX, nY) )
200 {
201 sal_uInt16 nMax = m_xRowRB->get_active()? nY : nX;
202 m_xColEdt1->set_max(nMax);
203 m_xColEdt2->set_max(nMax);
204 m_xColEdt3->set_max(nMax);
205 }
206}
207
209{
210 sal_Unicode cRet = '\t';
211 if( !m_xDelimTabRB->get_active() )
212 {
213 OUString aTmp(m_xDelimEdt->get_text());
214 if( !aTmp.isEmpty() )
215 cRet = aTmp[0];
216 }
217 return cRet;
218}
219
221{
222 short nRet = GenericDialogController::run();
223 if (nRet == RET_OK)
224 Apply();
225 return nRet;
226}
227
228// pass on to the Core
230{
231 // save all settings
232 bCheck1 = m_xKeyCB1->get_active();
233 bCheck2 = m_xKeyCB2->get_active();
234 bCheck3 = m_xKeyCB3->get_active();
235
236 nCol1 = m_xColEdt1->get_value();
237 nCol2 = m_xColEdt2->get_value();
238 nCol3 = m_xColEdt3->get_value();
239
240 nType1 = m_xTypDLB1->get_active();
241 nType2 = m_xTypDLB2->get_active();
242 nType3 = m_xTypDLB3->get_active();
243
244 bAsc1 = m_xSortUp1RB->get_active();
245 bAsc2 = m_xSortUp2RB->get_active();
246 bAsc3 = m_xSortUp3RB->get_active();
247 bCol = m_xColumnRB->get_active();
248 nLang = m_xLangLB->get_active_id();
250 bCsSens = m_xCaseCB->get_active();
251
252 SwSortOptions aOptions;
253 if( bCheck1 )
254 {
255 OUString sEntry( m_xTypDLB1->get_active_text() );
256 if( sEntry == aNumericText )
257 sEntry.clear();
258 else if (!m_xTypDLB1->get_active_id().isEmpty())
259 sEntry = m_xTypDLB1->get_active_id();
260
261 aOptions.aKeys.push_back(
262 SwSortKey( nCol1, sEntry,
264 }
265
266 if( bCheck2 )
267 {
268 OUString sEntry( m_xTypDLB2->get_active_text() );
269 if( sEntry == aNumericText )
270 sEntry.clear();
271 else if (!m_xTypDLB2->get_active_id().isEmpty())
272 sEntry = m_xTypDLB2->get_active_id();
273
274 aOptions.aKeys.push_back(
275 SwSortKey( nCol2, sEntry,
277 }
278
279 if( bCheck3 )
280 {
281 OUString sEntry( m_xTypDLB3->get_active_text() );
282 if( sEntry == aNumericText )
283 sEntry.clear();
284 else if (!m_xTypDLB3->get_active_id().isEmpty())
285 sEntry = m_xTypDLB3->get_active_id();
286
287 aOptions.aKeys.push_back(
288 SwSortKey( nCol3, sEntry,
290 }
291
293 aOptions.cDeli = cDeli;
294 aOptions.nLanguage = nLang;
295 aOptions.bTable = rSh.IsTableMode();
296 aOptions.bIgnoreCase = !bCsSens;
297
298 bool bRet;
299 {
300 SwWait aWait( *rSh.GetView().GetDocShell(), true );
302 bRet = rSh.Sort( aOptions );
303 if( bRet )
306 }
307
308 if (!bRet)
309 {
310 std::unique_ptr<weld::MessageDialog> xInfoBox(Application::CreateMessageDialog(m_pParent,
311 VclMessageType::Info, VclButtonsType::Ok,
312 SwResId(STR_SRTERR)));
313 xInfoBox->run();
314 }
315}
316
317IMPL_LINK( SwSortDlg, DelimHdl, weld::Toggleable&, rButton, void )
318{
319 bool bEnable = &rButton == m_xDelimFreeRB.get() && m_xDelimFreeRB->get_sensitive();
320 m_xDelimEdt->set_sensitive( bEnable );
321 m_xDelimPB->set_sensitive( bEnable );
322}
323
325{
327 SfxAllItemSet aSet( rSh.GetAttrPool() );
328 aSet.Put( SfxInt32Item( SID_ATTR_CHAR, GetDelimChar() ) );
329 ScopedVclPtr<SfxAbstractDialog> pMap(pFact->CreateCharMapDialog(m_xDialog.get(), aSet, nullptr));
330 if( RET_OK == pMap->Execute() )
331 {
332 const SfxInt32Item* pItem = SfxItemSet::GetItem<SfxInt32Item>(pMap->GetOutputItemSet(), SID_ATTR_CHAR, false);
333 if ( pItem )
334 m_xDelimEdt->set_text(OUString(sal_Unicode(pItem->GetValue())));
335 }
336}
337
338IMPL_LINK( SwSortDlg, CheckHdl, weld::Toggleable&, rControl, void )
339{
340 if (&rControl == m_xRowRB.get())
341 {
342 m_xColLbl->set_label(aColText);
343 m_xColEdt1->set_max(nY);
344 m_xColEdt2->set_max(nY);
345 m_xColEdt3->set_max(nY);
346
347 m_xColEdt1->set_accessible_name(aColText);
348 m_xColEdt2->set_accessible_name(aColText);
349 m_xColEdt3->set_accessible_name(aColText);
350 }
351 else if (&rControl == m_xColumnRB.get())
352 {
353 m_xColLbl->set_label(aRowText);
354 m_xColEdt1->set_max(nX);
355 m_xColEdt2->set_max(nX);
356 m_xColEdt3->set_max(nX);
357
358 m_xColEdt1->set_accessible_name(aRowText);
359 m_xColEdt2->set_accessible_name(aRowText);
360 m_xColEdt3->set_accessible_name(aRowText);
361 }
362 else if(!m_xKeyCB1->get_active() &&
363 !m_xKeyCB2->get_active() &&
364 !m_xKeyCB3->get_active())
365 {
366 rControl.set_active(true);
367 }
368}
369
370IMPL_LINK( SwSortDlg, LanguageListBoxHdl, weld::ComboBox&, rLBox, void )
371{
372 LanguageHdl(&rLBox);
373}
374
376{
377 Sequence < OUString > aSeq( GetAppCollator().listCollatorAlgorithms(
378 LanguageTag( m_xLangLB->get_active_id()).getLocale() ));
379
380 if (!m_xColRes)
381 m_xColRes.reset(new CollatorResource);
382
383 const int nLstBoxCnt = 3;
384 weld::ComboBox* aLstArr[ nLstBoxCnt ] = { m_xTypDLB1.get(), m_xTypDLB2.get(), m_xTypDLB3.get() };
385 sal_uInt16* const aTypeArr[ nLstBoxCnt ] = { &nType1, &nType2, &nType3 };
386 OUString aOldStrArr[ nLstBoxCnt ];
387
388 for( int n = 0; n < nLstBoxCnt; ++n )
389 {
390 weld::ComboBox* pL = aLstArr[ n ];
391 OUString sUserData = pL->get_active_id();
392 if (!sUserData.isEmpty())
393 aOldStrArr[ n ] = sUserData;
394 pL->clear();
395 }
396
397 OUString sAlg, sUINm;
398 const sal_Int32 nEnd = aSeq.getLength();
399 for( sal_Int32 nCnt = 0; nCnt <= nEnd; ++nCnt )
400 {
401 if( nCnt < nEnd )
402 {
403 sAlg = aSeq[ nCnt ];
404 sUINm = m_xColRes->GetTranslation( sAlg );
405 }
406 else
407 sUINm = sAlg = aNumericText;
408
409 for( int n = 0; n < nLstBoxCnt; ++n )
410 {
411 weld::ComboBox* pL = aLstArr[ n ];
412 pL->append(sAlg, sUINm);
413 if (pLBox && sAlg == aOldStrArr[n])
414 pL->set_active_id(sAlg);
415 }
416 }
417
418 for( int n = 0; n < nLstBoxCnt; ++n )
419 {
420 weld::ComboBox* pL = aLstArr[ n ];
421 if( !pLBox )
422 pL->set_active(*aTypeArr[n]);
423 else if (pL->get_active() == -1)
424 pL->set_active(0);
425 }
426}
427
428/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
Reference< XExecutableDialog > m_xDialog
static weld::MessageDialog * CreateMessageDialog(weld::Widget *pParent, VclMessageType eMessageType, VclButtonsType eButtonType, const OUString &rPrimaryMessage, bool bMobile=false)
sal_Int32 GetValue() const
const FndLines_t & GetLines() const
Definition: tblsel.hxx:173
const css::lang::Locale & getLocale(bool bResolveSystem=true) const
const SfxPoolItem * Put(const SfxPoolItem &rItem, sal_uInt16 nWhich)
virtual VclPtr< SfxAbstractDialog > CreateCharMapDialog(weld::Window *pParent, const SfxItemSet &rAttr, const css::uno::Reference< css::frame::XFrame > &rFrame)=0
static SvxAbstractDialogFactory * Create()
const SwTableNode * IsCursorInTable() const
Definition: crsrsh.hxx:902
bool IsTableMode() const
Definition: crsrsh.hxx:652
void StartAllAction()
For all views of this document.
Definition: edws.cxx:86
void SetModified()
Definition: edws.cxx:70
void EndAllAction()
Definition: edws.cxx:97
bool Sort(const SwSortOptions &)
Definition: fews.cxx:517
std::unique_ptr< weld::RadioButton > m_xSortUp3RB
Definition: srtdlg.hxx:48
std::unique_ptr< SvxLanguageBox > m_xLangLB
Definition: srtdlg.hxx:59
void LanguageHdl(weld::ComboBox const *)
Definition: srtdlg.cxx:375
OUString aNumericText
Definition: srtdlg.hxx:65
std::unique_ptr< weld::SpinButton > m_xColEdt1
Definition: srtdlg.hxx:34
std::unique_ptr< weld::SpinButton > m_xColEdt3
Definition: srtdlg.hxx:46
std::unique_ptr< weld::Button > m_xDelimPB
Definition: srtdlg.hxx:57
std::unique_ptr< weld::SpinButton > m_xColEdt2
Definition: srtdlg.hxx:40
sal_uInt16 nX
Definition: srtdlg.hxx:70
std::unique_ptr< weld::RadioButton > m_xSortDn2RB
Definition: srtdlg.hxx:43
sal_Unicode GetDelimChar() const
Definition: srtdlg.cxx:208
SwWrtShell & rSh
Definition: srtdlg.hxx:67
std::unique_ptr< weld::RadioButton > m_xSortUp2RB
Definition: srtdlg.hxx:42
std::unique_ptr< weld::CheckButton > m_xKeyCB2
Definition: srtdlg.hxx:39
std::unique_ptr< weld::RadioButton > m_xSortDn3RB
Definition: srtdlg.hxx:49
std::unique_ptr< weld::ComboBox > m_xTypDLB2
Definition: srtdlg.hxx:41
OUString aRowText
Definition: srtdlg.hxx:64
std::unique_ptr< weld::RadioButton > m_xSortDn1RB
Definition: srtdlg.hxx:37
sal_uInt16 nY
Definition: srtdlg.hxx:71
std::unique_ptr< weld::RadioButton > m_xSortUp1RB
Definition: srtdlg.hxx:36
SwSortDlg(weld::Window *pParent, SwWrtShell &rSh)
Definition: srtdlg.cxx:91
std::unique_ptr< weld::RadioButton > m_xRowRB
Definition: srtdlg.hxx:52
std::unique_ptr< CollatorResource > m_xColRes
Definition: srtdlg.hxx:68
std::unique_ptr< weld::Label > m_xColLbl
Definition: srtdlg.hxx:31
std::unique_ptr< weld::Entry > m_xDelimEdt
Definition: srtdlg.hxx:56
std::unique_ptr< weld::CheckButton > m_xKeyCB3
Definition: srtdlg.hxx:45
std::unique_ptr< weld::RadioButton > m_xDelimTabRB
Definition: srtdlg.hxx:54
std::unique_ptr< weld::RadioButton > m_xColumnRB
Definition: srtdlg.hxx:51
std::unique_ptr< weld::RadioButton > m_xDelimFreeRB
Definition: srtdlg.hxx:55
OUString aColText
Definition: srtdlg.hxx:63
std::unique_ptr< weld::CheckButton > m_xKeyCB1
Definition: srtdlg.hxx:33
void Apply()
Definition: srtdlg.cxx:229
std::unique_ptr< weld::ComboBox > m_xTypDLB3
Definition: srtdlg.hxx:47
std::unique_ptr< weld::CheckButton > m_xCaseCB
Definition: srtdlg.hxx:61
weld::Window * m_pParent
Definition: srtdlg.hxx:30
std::unique_ptr< weld::ComboBox > m_xTypDLB1
Definition: srtdlg.hxx:35
virtual short run() override
Definition: srtdlg.cxx:220
const SwTable & GetTable() const
Definition: node.hxx:521
SwTable is one table in the document model, containing rows (which contain cells).
Definition: swtable.hxx:113
SwTableLines & GetTabLines()
Definition: swtable.hxx:201
SwDocShell * GetDocShell()
Definition: view.cxx:1159
Used by the UI to modify the document model.
Definition: wrtsh.hxx:97
SelectionType GetSelectionType() const
Definition: wrtsh1.cxx:1701
const SwView & GetView() const
Definition: wrtsh.hxx:438
void append(const OUString &rId, const OUString &rStr)
virtual OUString get_active_id() const=0
virtual void clear()=0
virtual void set_active_id(const OUString &rStr)=0
virtual void set_active(int pos)=0
virtual int get_active() const=0
LanguageType GetAppLanguage()
Definition: init.cxx:725
CollatorWrapper & GetAppCollator()
Definition: init.cxx:737
sal_Int64 n
#define LANGUAGE_NONE
#define LANGUAGE_DONTKNOW
Sequence< sal_Int8 > aSeq
static sal_uInt16 nType2
Definition: srtdlg.cxx:48
IMPL_LINK_NOARG(SwSortDlg, DelimCharHdl, weld::Button &, void)
Definition: srtdlg.cxx:324
static bool bAsc3
Definition: srtdlg.cxx:55
static sal_uInt16 nType1
Definition: srtdlg.cxx:47
static sal_uInt16 nType3
Definition: srtdlg.cxx:49
static bool bCheck1
Definition: srtdlg.cxx:39
static bool bCheck3
Definition: srtdlg.cxx:41
static bool bAsc2
Definition: srtdlg.cxx:54
static bool bAsc1
Definition: srtdlg.cxx:53
static bool bCol
Definition: srtdlg.cxx:56
IMPL_LINK(SwSortDlg, DelimHdl, weld::Toggleable &, rButton, void)
Definition: srtdlg.cxx:317
static sal_uInt16 nCol2
Definition: srtdlg.cxx:44
static bool lcl_GetSelTable(SwWrtShell const &rSh, sal_uInt16 &rX, sal_uInt16 &rY)
Definition: srtdlg.cxx:66
static sal_uInt16 nCol3
Definition: srtdlg.cxx:45
static bool bCsSens
Definition: srtdlg.cxx:57
static bool bCheck2
Definition: srtdlg.cxx:40
static LanguageType nLang
Definition: srtdlg.cxx:51
static sal_uInt16 nCol1
Definition: srtdlg.cxx:43
static sal_Unicode cDeli
Definition: srtdlg.cxx:59
std::vector< SwSortKey > aKeys
Definition: sortopt.hxx:49
sal_Unicode cDeli
Definition: sortopt.hxx:51
LanguageType nLanguage
Definition: sortopt.hxx:52
bool bIgnoreCase
Definition: sortopt.hxx:54
SwSortDirection eDirection
Definition: sortopt.hxx:50
OUString SwResId(TranslateId aId)
Definition: swmodule.cxx:164
void ForEach_FndLineCopyCol(SwTableLines &rLines, FndPara *pFndPara)
This creates a structure mirroring the SwTable structure that contains all rows and non-leaf boxes (a...
Definition: tblsel.cxx:2091
void GetTableSel(const SwCursorShell &rShell, SwSelBoxes &rBoxes, const SwTableSearchType eSearchType)
Definition: tblsel.cxx:149
sal_uInt16 sal_Unicode
RET_OK