tdf#160582 Preserve settings saving in csv import dialog
Also, improve detection algorithm by replacing the limit of 20 lines with a time limit of 500ms. Change-Id: Iac519b6ebe675b91ce84b900646d9d320ea9ddc1 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/165905 Reviewed-by: Andras Timar <andras.timar@collabora.com> Tested-by: Jenkins
This commit is contained in:
committed by
Andras Timar
parent
2f1dcf01d7
commit
565b619d57
@@ -141,6 +141,7 @@ typedef sal_uInt16 rtl_TextEncoding;
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#define RTL_TEXTENCODING_USER_START (RTL_TEXTENC_CAST( 0x8000 ))
|
#define RTL_TEXTENCODING_USER_START (RTL_TEXTENC_CAST( 0x8000 ))
|
||||||
|
#define RTL_TEXTENCODING_USER_DETECTED (RTL_TEXTENCODING_USER_START + 0)
|
||||||
#define RTL_TEXTENCODING_USER_END (RTL_TEXTENC_CAST( 0xEFFF ))
|
#define RTL_TEXTENCODING_USER_END (RTL_TEXTENC_CAST( 0xEFFF ))
|
||||||
|
|
||||||
#define RTL_TEXTENCODING_UCS4 (RTL_TEXTENC_CAST( 0xFFFE ))
|
#define RTL_TEXTENCODING_UCS4 (RTL_TEXTENC_CAST( 0xFFFE ))
|
||||||
|
@@ -1012,6 +1012,13 @@
|
|||||||
</info>
|
</info>
|
||||||
<value>false</value>
|
<value>false</value>
|
||||||
</prop>
|
</prop>
|
||||||
|
<prop oor:name="SeparatorType" oor:type="xs:short" oor:nillable="false">
|
||||||
|
<info>
|
||||||
|
<desc>Fixed width, separator or detected separator</desc>
|
||||||
|
<label>SeparatorType</label>
|
||||||
|
</info>
|
||||||
|
<value>2</value>
|
||||||
|
</prop>
|
||||||
<prop oor:name="QuotedFieldAsText" oor:type="xs:boolean" oor:nillable="false">
|
<prop oor:name="QuotedFieldAsText" oor:type="xs:boolean" oor:nillable="false">
|
||||||
<info>
|
<info>
|
||||||
<desc>If true, quoted field is always imported as text with no exception.</desc>
|
<desc>If true, quoted field is always imported as text with no exception.</desc>
|
||||||
|
@@ -152,8 +152,8 @@ public:
|
|||||||
const css::uno::Reference<css::beans::XPropertySet>& xProp,
|
const css::uno::Reference<css::beans::XPropertySet>& xProp,
|
||||||
const OUString& rName, const OUString& rDefault );
|
const OUString& rName, const OUString& rDefault );
|
||||||
|
|
||||||
SC_DLLPUBLIC static bool GetBoolFromAny( const css::uno::Any& aAny );
|
SC_DLLPUBLIC static bool GetBoolFromAny( const css::uno::Any& aAny );
|
||||||
static sal_Int16 GetInt16FromAny( const css::uno::Any& aAny );
|
SC_DLLPUBLIC static sal_Int16 GetInt16FromAny( const css::uno::Any& aAny );
|
||||||
static sal_Int32 GetInt32FromAny( const css::uno::Any& aAny );
|
static sal_Int32 GetInt32FromAny( const css::uno::Any& aAny );
|
||||||
static sal_Int32 GetEnumFromAny( const css::uno::Any& aAny );
|
static sal_Int32 GetEnumFromAny( const css::uno::Any& aAny );
|
||||||
|
|
||||||
|
@@ -419,8 +419,7 @@ public:
|
|||||||
virtual VclPtr<AbstractScImportAsciiDlg> CreateScImportAsciiDlg(weld::Window* pParent,
|
virtual VclPtr<AbstractScImportAsciiDlg> CreateScImportAsciiDlg(weld::Window* pParent,
|
||||||
const OUString& aDatName,
|
const OUString& aDatName,
|
||||||
SvStream* pInStream,
|
SvStream* pInStream,
|
||||||
ScImportAsciiCall eCall,
|
ScImportAsciiCall eCall) = 0;
|
||||||
ScAsciiOptions* aOptions = nullptr) = 0;
|
|
||||||
|
|
||||||
virtual VclPtr<AbstractScTextImportOptionsDlg> CreateScTextImportOptionsDlg(weld::Window* pParent) = 0;
|
virtual VclPtr<AbstractScTextImportOptionsDlg> CreateScTextImportOptionsDlg(weld::Window* pParent) = 0;
|
||||||
|
|
||||||
|
@@ -85,6 +85,8 @@
|
|||||||
#define SCSTR_FIELDSEP_SPACE NC_("SCSTR_FIELDSEP_SPACE", "space")
|
#define SCSTR_FIELDSEP_SPACE NC_("SCSTR_FIELDSEP_SPACE", "space")
|
||||||
#define SCSTR_UNDO_GRAFFILTER NC_("SCSTR_UNDO_GRAFFILTER", "Image Filter")
|
#define SCSTR_UNDO_GRAFFILTER NC_("SCSTR_UNDO_GRAFFILTER", "Image Filter")
|
||||||
#define STR_CAPTION_DEFAULT_TEXT NC_("STR_CAPTION_DEFAULT_TEXT", "Text")
|
#define STR_CAPTION_DEFAULT_TEXT NC_("STR_CAPTION_DEFAULT_TEXT", "Text")
|
||||||
|
#define SCSTR_DETECTED NC_("SCSTR_DETECTED", "Detected (%1)")
|
||||||
|
#define SCSTR_AUTOMATIC NC_("SCSTR_AUTOMATIC", "Automatic")
|
||||||
// Select tables dialog title
|
// Select tables dialog title
|
||||||
#define STR_DLG_SELECTTABLES_TITLE NC_("STR_DLG_SELECTTABLES_TITLE", "Select Sheets")
|
#define STR_DLG_SELECTTABLES_TITLE NC_("STR_DLG_SELECTTABLES_TITLE", "Select Sheets")
|
||||||
#define STR_DLG_SELECTTABLE_TITLE NC_("STR_DLG_SELECTTABLE_TITLE", "Go to Sheet")
|
#define STR_DLG_SELECTTABLE_TITLE NC_("STR_DLG_SELECTTABLE_TITLE", "Go to Sheet")
|
||||||
|
@@ -17,21 +17,12 @@ class Td117868(UITestCase):
|
|||||||
|
|
||||||
with load_csv_file(self, "tdf117868.csv", False) as xDialog:
|
with load_csv_file(self, "tdf117868.csv", False) as xDialog:
|
||||||
# Set text delimiter in case it's changed by another test
|
# Set text delimiter in case it's changed by another test
|
||||||
xSeparatedBy = xDialog.getChild("toseparatedby")
|
self.assertEqual('Detected (|)', get_state_as_dict(xDialog.getChild("todetectseparator"))['Text'])
|
||||||
xSeparatedBy.executeAction("CLICK", tuple())
|
xDetected = xDialog.getChild("todetectseparator")
|
||||||
|
xDetected.executeAction("CLICK", tuple())
|
||||||
# Without the fix in place, this test would have failed with
|
|
||||||
# AssertionError: 'true' != 'false'
|
|
||||||
self.assertEqual('true', get_state_as_dict(xDialog.getChild("other"))['Selected'])
|
|
||||||
self.assertEqual('false', get_state_as_dict(xDialog.getChild("tab"))['Selected'])
|
|
||||||
self.assertEqual('false', get_state_as_dict(xDialog.getChild("comma"))['Selected'])
|
|
||||||
self.assertEqual('false', get_state_as_dict(xDialog.getChild("semicolon"))['Selected'])
|
|
||||||
|
|
||||||
self.assertEqual('1', get_state_as_dict(xDialog.getChild("fromrow"))['Text'])
|
self.assertEqual('1', get_state_as_dict(xDialog.getChild("fromrow"))['Text'])
|
||||||
|
|
||||||
xInputOther = xDialog.getChild("inputother")
|
|
||||||
self.assertEqual("|", get_state_as_dict(xInputOther)['Text'])
|
|
||||||
|
|
||||||
document = self.ui_test.get_component()
|
document = self.ui_test.get_component()
|
||||||
|
|
||||||
self.assertEqual("LETTER", get_cell_by_position(document, 0, 0, 1).getString())
|
self.assertEqual("LETTER", get_cell_by_position(document, 0, 0, 1).getString())
|
||||||
|
@@ -22,6 +22,9 @@ class tdf143008(UITestCase):
|
|||||||
enter_text_to_cell(gridwin, "A1", "22/06/2021 10:02 PM")
|
enter_text_to_cell(gridwin, "A1", "22/06/2021 10:02 PM")
|
||||||
|
|
||||||
with self.ui_test.execute_dialog_through_command(".uno:TextToColumns") as xDialog:
|
with self.ui_test.execute_dialog_through_command(".uno:TextToColumns") as xDialog:
|
||||||
|
xSeparatedBy = xDialog.getChild("toseparatedby")
|
||||||
|
xSeparatedBy.executeAction("CLICK", tuple())
|
||||||
|
|
||||||
xGrid = xDialog.getChild("csvgrid")
|
xGrid = xDialog.getChild("csvgrid")
|
||||||
xColumnType = xDialog.getChild("columntype")
|
xColumnType = xDialog.getChild("columntype")
|
||||||
|
|
||||||
|
@@ -28,6 +28,9 @@ class tdf51700(UITestCase):
|
|||||||
self.xUITest.executeCommand(".uno:SelectColumn")
|
self.xUITest.executeCommand(".uno:SelectColumn")
|
||||||
# Data - Text to Columns
|
# Data - Text to Columns
|
||||||
with self.ui_test.execute_dialog_through_command(".uno:TextToColumns") as xDialog:
|
with self.ui_test.execute_dialog_through_command(".uno:TextToColumns") as xDialog:
|
||||||
|
xSeparatedBy = xDialog.getChild("toseparatedby")
|
||||||
|
xSeparatedBy.executeAction("CLICK", tuple())
|
||||||
|
|
||||||
xcomma = xDialog.getChild("comma")
|
xcomma = xDialog.getChild("comma")
|
||||||
if (get_state_as_dict(xcomma)["Selected"]) == "false":
|
if (get_state_as_dict(xcomma)["Selected"]) == "false":
|
||||||
xcomma.executeAction("CLICK", tuple())
|
xcomma.executeAction("CLICK", tuple())
|
||||||
|
@@ -23,6 +23,9 @@ class tdf69981(UITestCase):
|
|||||||
gridwin.executeAction("SELECT", mkPropertyValues({"RANGE": "A2:A7"}))
|
gridwin.executeAction("SELECT", mkPropertyValues({"RANGE": "A2:A7"}))
|
||||||
#Data - Text to Columns
|
#Data - Text to Columns
|
||||||
with self.ui_test.execute_dialog_through_command(".uno:TextToColumns", close_button="") as xDialog:
|
with self.ui_test.execute_dialog_through_command(".uno:TextToColumns", close_button="") as xDialog:
|
||||||
|
xSeparatedBy = xDialog.getChild("toseparatedby")
|
||||||
|
xSeparatedBy.executeAction("CLICK", tuple())
|
||||||
|
|
||||||
xtab = xDialog.getChild("tab")
|
xtab = xDialog.getChild("tab")
|
||||||
xcomma = xDialog.getChild("comma")
|
xcomma = xDialog.getChild("comma")
|
||||||
xtab.executeAction("CLICK", tuple())
|
xtab.executeAction("CLICK", tuple())
|
||||||
|
@@ -26,6 +26,9 @@ class tdf73006(UITestCase):
|
|||||||
self.xUITest.executeCommand(".uno:SelectColumn")
|
self.xUITest.executeCommand(".uno:SelectColumn")
|
||||||
# Data - Text to Columns
|
# Data - Text to Columns
|
||||||
with self.ui_test.execute_dialog_through_command(".uno:TextToColumns") as xDialog:
|
with self.ui_test.execute_dialog_through_command(".uno:TextToColumns") as xDialog:
|
||||||
|
xSeparatedBy = xDialog.getChild("toseparatedby")
|
||||||
|
xSeparatedBy.executeAction("CLICK", tuple())
|
||||||
|
|
||||||
xspace = xDialog.getChild("space")
|
xspace = xDialog.getChild("space")
|
||||||
if (get_state_as_dict(xspace)["Selected"]) == "false":
|
if (get_state_as_dict(xspace)["Selected"]) == "false":
|
||||||
xspace.executeAction("CLICK", tuple())
|
xspace.executeAction("CLICK", tuple())
|
||||||
|
@@ -29,6 +29,9 @@ class tdf82398(UITestCase):
|
|||||||
self.xUITest.executeCommand(".uno:NumberFormatDate")
|
self.xUITest.executeCommand(".uno:NumberFormatDate")
|
||||||
# Data - Text to Columns
|
# Data - Text to Columns
|
||||||
with self.ui_test.execute_dialog_through_command(".uno:TextToColumns") as xDialog:
|
with self.ui_test.execute_dialog_through_command(".uno:TextToColumns") as xDialog:
|
||||||
|
xSeparatedBy = xDialog.getChild("toseparatedby")
|
||||||
|
xSeparatedBy.executeAction("CLICK", tuple())
|
||||||
|
|
||||||
xother = xDialog.getChild("other")
|
xother = xDialog.getChild("other")
|
||||||
xinputother = xDialog.getChild("inputother")
|
xinputother = xDialog.getChild("inputother")
|
||||||
|
|
||||||
|
@@ -23,6 +23,9 @@ class tdf85979(UITestCase):
|
|||||||
gridwin.executeAction("SELECT", mkPropertyValues({"RANGE": "C1:C5"}))
|
gridwin.executeAction("SELECT", mkPropertyValues({"RANGE": "C1:C5"}))
|
||||||
# Data - Text to Columns
|
# Data - Text to Columns
|
||||||
with self.ui_test.execute_dialog_through_command(".uno:TextToColumns") as xDialog:
|
with self.ui_test.execute_dialog_through_command(".uno:TextToColumns") as xDialog:
|
||||||
|
xSeparatedBy = xDialog.getChild("toseparatedby")
|
||||||
|
xSeparatedBy.executeAction("CLICK", tuple())
|
||||||
|
|
||||||
xspace = xDialog.getChild("space")
|
xspace = xDialog.getChild("space")
|
||||||
if (get_state_as_dict(xspace)["Selected"]) == "false":
|
if (get_state_as_dict(xspace)["Selected"]) == "false":
|
||||||
xspace.executeAction("CLICK", tuple())
|
xspace.executeAction("CLICK", tuple())
|
||||||
|
@@ -37,6 +37,9 @@ class tdf89907(UITestCase):
|
|||||||
|
|
||||||
# Data - Text to Columns
|
# Data - Text to Columns
|
||||||
with self.ui_test.execute_dialog_through_command(".uno:TextToColumns") as xDialog:
|
with self.ui_test.execute_dialog_through_command(".uno:TextToColumns") as xDialog:
|
||||||
|
xSeparatedBy = xDialog.getChild("toseparatedby")
|
||||||
|
xSeparatedBy.executeAction("CLICK", tuple())
|
||||||
|
|
||||||
xother = xDialog.getChild("other")
|
xother = xDialog.getChild("other")
|
||||||
xinputother = xDialog.getChild("inputother")
|
xinputother = xDialog.getChild("inputother")
|
||||||
if (get_state_as_dict(xother)["Selected"]) == "false":
|
if (get_state_as_dict(xother)["Selected"]) == "false":
|
||||||
|
@@ -39,6 +39,9 @@ class tdf92423(UITestCase):
|
|||||||
self.assertEqual(gridWinState["MarkedArea"], "Sheet1.A7:Sheet1.A9")
|
self.assertEqual(gridWinState["MarkedArea"], "Sheet1.A7:Sheet1.A9")
|
||||||
# Data - Text to Columns
|
# Data - Text to Columns
|
||||||
with self.ui_test.execute_dialog_through_command(".uno:TextToColumns") as xDialog:
|
with self.ui_test.execute_dialog_through_command(".uno:TextToColumns") as xDialog:
|
||||||
|
xSeparatedBy = xDialog.getChild("toseparatedby")
|
||||||
|
xSeparatedBy.executeAction("CLICK", tuple())
|
||||||
|
|
||||||
xSemicolon = xDialog.getChild("semicolon") #check semicolon checkbox
|
xSemicolon = xDialog.getChild("semicolon") #check semicolon checkbox
|
||||||
if (get_state_as_dict(xSemicolon)["Selected"]) == "false":
|
if (get_state_as_dict(xSemicolon)["Selected"]) == "false":
|
||||||
xSemicolon.executeAction("CLICK", tuple())
|
xSemicolon.executeAction("CLICK", tuple())
|
||||||
|
@@ -26,6 +26,9 @@ class CalcTextToColumns(UITestCase):
|
|||||||
#Data - Text to Columns
|
#Data - Text to Columns
|
||||||
with self.ui_test.execute_dialog_through_command(".uno:TextToColumns", close_button="") as xDialog:
|
with self.ui_test.execute_dialog_through_command(".uno:TextToColumns", close_button="") as xDialog:
|
||||||
#Untag Tab as separator and tag other. Put a dot into the input field next to the other checkbox
|
#Untag Tab as separator and tag other. Put a dot into the input field next to the other checkbox
|
||||||
|
xSeparatedBy = xDialog.getChild("toseparatedby")
|
||||||
|
xSeparatedBy.executeAction("CLICK", tuple())
|
||||||
|
|
||||||
xother = xDialog.getChild("other")
|
xother = xDialog.getChild("other")
|
||||||
xinputother = xDialog.getChild("inputother")
|
xinputother = xDialog.getChild("inputother")
|
||||||
|
|
||||||
@@ -85,6 +88,9 @@ class CalcTextToColumns(UITestCase):
|
|||||||
# Data - Text to Columns
|
# Data - Text to Columns
|
||||||
with self.ui_test.execute_dialog_through_command(".uno:TextToColumns", close_button="") as xDialog:
|
with self.ui_test.execute_dialog_through_command(".uno:TextToColumns", close_button="") as xDialog:
|
||||||
# Untag Tab as separator and tag comma.
|
# Untag Tab as separator and tag comma.
|
||||||
|
xSeparatedBy = xDialog.getChild("toseparatedby")
|
||||||
|
xSeparatedBy.executeAction("CLICK", tuple())
|
||||||
|
|
||||||
xComma = xDialog.getChild("comma")
|
xComma = xDialog.getChild("comma")
|
||||||
if (get_state_as_dict(xComma)["Selected"]) == "false":
|
if (get_state_as_dict(xComma)["Selected"]) == "false":
|
||||||
xComma.executeAction("CLICK", tuple())
|
xComma.executeAction("CLICK", tuple())
|
||||||
@@ -142,6 +148,9 @@ class CalcTextToColumns(UITestCase):
|
|||||||
# Data - Text to Columns
|
# Data - Text to Columns
|
||||||
with self.ui_test.execute_dialog_through_command(".uno:TextToColumns", close_button="") as xDialog:
|
with self.ui_test.execute_dialog_through_command(".uno:TextToColumns", close_button="") as xDialog:
|
||||||
# Untag comma as separator and tag Semicolon
|
# Untag comma as separator and tag Semicolon
|
||||||
|
xSeparatedBy = xDialog.getChild("toseparatedby")
|
||||||
|
xSeparatedBy.executeAction("CLICK", tuple())
|
||||||
|
|
||||||
xSemicolon = xDialog.getChild("semicolon")
|
xSemicolon = xDialog.getChild("semicolon")
|
||||||
if (get_state_as_dict(xSemicolon)["Selected"]) == "false":
|
if (get_state_as_dict(xSemicolon)["Selected"]) == "false":
|
||||||
xSemicolon.executeAction("CLICK", tuple())
|
xSemicolon.executeAction("CLICK", tuple())
|
||||||
@@ -199,6 +208,9 @@ class CalcTextToColumns(UITestCase):
|
|||||||
# Data - Text to Columns
|
# Data - Text to Columns
|
||||||
with self.ui_test.execute_dialog_through_command(".uno:TextToColumns", close_button="") as xDialog:
|
with self.ui_test.execute_dialog_through_command(".uno:TextToColumns", close_button="") as xDialog:
|
||||||
# Untag comma as separator and tag Semicolon
|
# Untag comma as separator and tag Semicolon
|
||||||
|
xSeparatedBy = xDialog.getChild("toseparatedby")
|
||||||
|
xSeparatedBy.executeAction("CLICK", tuple())
|
||||||
|
|
||||||
xSpace = xDialog.getChild("space")
|
xSpace = xDialog.getChild("space")
|
||||||
if (get_state_as_dict(xSpace)["Selected"]) == "false":
|
if (get_state_as_dict(xSpace)["Selected"]) == "false":
|
||||||
xSpace.executeAction("CLICK", tuple())
|
xSpace.executeAction("CLICK", tuple())
|
||||||
@@ -257,6 +269,9 @@ class CalcTextToColumns(UITestCase):
|
|||||||
# Data - Text to Columns
|
# Data - Text to Columns
|
||||||
with self.ui_test.execute_dialog_through_command(".uno:TextToColumns", close_button="") as xDialog:
|
with self.ui_test.execute_dialog_through_command(".uno:TextToColumns", close_button="") as xDialog:
|
||||||
# Untag comma as separator and tag Semicolon
|
# Untag comma as separator and tag Semicolon
|
||||||
|
xSeparatedBy = xDialog.getChild("toseparatedby")
|
||||||
|
xSeparatedBy.executeAction("CLICK", tuple())
|
||||||
|
|
||||||
xother = xDialog.getChild("other")
|
xother = xDialog.getChild("other")
|
||||||
xinputother = xDialog.getChild("inputother")
|
xinputother = xDialog.getChild("inputother")
|
||||||
if (get_state_as_dict(xother)["Selected"]) == "false":
|
if (get_state_as_dict(xother)["Selected"]) == "false":
|
||||||
@@ -315,6 +330,9 @@ class CalcTextToColumns(UITestCase):
|
|||||||
gridwin.executeAction("SELECT", mkPropertyValues({"RANGE": "A1:A5"}))
|
gridwin.executeAction("SELECT", mkPropertyValues({"RANGE": "A1:A5"}))
|
||||||
# Data - Text to Columns
|
# Data - Text to Columns
|
||||||
with self.ui_test.execute_dialog_through_command(".uno:TextToColumns", close_button="") as xDialog:
|
with self.ui_test.execute_dialog_through_command(".uno:TextToColumns", close_button="") as xDialog:
|
||||||
|
xSeparatedBy = xDialog.getChild("toseparatedby")
|
||||||
|
xSeparatedBy.executeAction("CLICK", tuple())
|
||||||
|
|
||||||
xspace = xDialog.getChild("space")
|
xspace = xDialog.getChild("space")
|
||||||
xother = xDialog.getChild("other")
|
xother = xDialog.getChild("other")
|
||||||
xinputother = xDialog.getChild("inputother")
|
xinputother = xDialog.getChild("inputother")
|
||||||
|
@@ -1073,10 +1073,9 @@ bool AbstractScSelEntryDlg_Impl::StartExecuteAsync(VclAbstractDialog::AsyncConte
|
|||||||
// =========================Factories for createdialog ===================
|
// =========================Factories for createdialog ===================
|
||||||
VclPtr<AbstractScImportAsciiDlg> ScAbstractDialogFactory_Impl::CreateScImportAsciiDlg(weld::Window* pParent,
|
VclPtr<AbstractScImportAsciiDlg> ScAbstractDialogFactory_Impl::CreateScImportAsciiDlg(weld::Window* pParent,
|
||||||
const OUString& aDatName,
|
const OUString& aDatName,
|
||||||
SvStream* pInStream, ScImportAsciiCall eCall,
|
SvStream* pInStream, ScImportAsciiCall eCall)
|
||||||
ScAsciiOptions* aOptions)
|
|
||||||
{
|
{
|
||||||
return VclPtr<AbstractScImportAsciiDlg_Impl>::Create(std::make_shared<ScImportAsciiDlg>(pParent, aDatName,pInStream, eCall, aOptions));
|
return VclPtr<AbstractScImportAsciiDlg_Impl>::Create(std::make_shared<ScImportAsciiDlg>(pParent, aDatName,pInStream, eCall));
|
||||||
}
|
}
|
||||||
|
|
||||||
VclPtr<AbstractScTextImportOptionsDlg> ScAbstractDialogFactory_Impl::CreateScTextImportOptionsDlg(weld::Window* pParent)
|
VclPtr<AbstractScTextImportOptionsDlg> ScAbstractDialogFactory_Impl::CreateScTextImportOptionsDlg(weld::Window* pParent)
|
||||||
|
@@ -666,8 +666,7 @@ public:
|
|||||||
virtual VclPtr<AbstractScImportAsciiDlg> CreateScImportAsciiDlg(weld::Window* pParent,
|
virtual VclPtr<AbstractScImportAsciiDlg> CreateScImportAsciiDlg(weld::Window* pParent,
|
||||||
const OUString& aDatName,
|
const OUString& aDatName,
|
||||||
SvStream* pInStream,
|
SvStream* pInStream,
|
||||||
ScImportAsciiCall eCall,
|
ScImportAsciiCall eCall) override;
|
||||||
ScAsciiOptions* aOptions = nullptr) override;
|
|
||||||
|
|
||||||
virtual VclPtr<AbstractScTextImportOptionsDlg> CreateScTextImportOptionsDlg(weld::Window* pParent) override;
|
virtual VclPtr<AbstractScTextImportOptionsDlg> CreateScTextImportOptionsDlg(weld::Window* pParent) override;
|
||||||
|
|
||||||
|
@@ -22,9 +22,11 @@
|
|||||||
#include <comphelper/string.hxx>
|
#include <comphelper/string.hxx>
|
||||||
#include <osl/thread.h>
|
#include <osl/thread.h>
|
||||||
#include <o3tl/string_view.hxx>
|
#include <o3tl/string_view.hxx>
|
||||||
|
#include <sfx2/objsh.hxx>
|
||||||
|
|
||||||
constexpr std::u16string_view pStrFix = u"FIX";
|
constexpr std::u16string_view pStrFix = u"FIX";
|
||||||
constexpr std::u16string_view pStrMrg = u"MRG";
|
constexpr std::u16string_view pStrMrg = u"MRG";
|
||||||
|
constexpr std::u16string_view pStrDet = u"DETECT";
|
||||||
|
|
||||||
ScAsciiOptions::ScAsciiOptions() :
|
ScAsciiOptions::ScAsciiOptions() :
|
||||||
bFixedLen ( false ),
|
bFixedLen ( false ),
|
||||||
@@ -86,9 +88,10 @@ static OUString lcl_decodeSepString( std::u16string_view rSepNums, bool & o_bMer
|
|||||||
// The options string must not contain semicolons (because of the pick list),
|
// The options string must not contain semicolons (because of the pick list),
|
||||||
// use comma as separator.
|
// use comma as separator.
|
||||||
|
|
||||||
void ScAsciiOptions::ReadFromString( std::u16string_view rString )
|
void ScAsciiOptions::ReadFromString( std::u16string_view rString, SvStream* pStream4Detect )
|
||||||
{
|
{
|
||||||
sal_Int32 nPos = rString.empty() ? -1 : 0;
|
sal_Int32 nPos = rString.empty() ? -1 : 0;
|
||||||
|
bool bDetectSep = false;
|
||||||
|
|
||||||
// Token 0: Field separator.
|
// Token 0: Field separator.
|
||||||
if ( nPos >= 0 )
|
if ( nPos >= 0 )
|
||||||
@@ -96,9 +99,14 @@ void ScAsciiOptions::ReadFromString( std::u16string_view rString )
|
|||||||
bFixedLen = bMergeFieldSeps = false;
|
bFixedLen = bMergeFieldSeps = false;
|
||||||
|
|
||||||
const std::u16string_view aToken = o3tl::getToken(rString, 0, ',', nPos);
|
const std::u16string_view aToken = o3tl::getToken(rString, 0, ',', nPos);
|
||||||
if ( aToken == pStrFix )
|
if ( aToken == pStrDet)
|
||||||
bFixedLen = true;
|
bDetectSep = true;
|
||||||
aFieldSeps = lcl_decodeSepString( aToken, bMergeFieldSeps);
|
else
|
||||||
|
{
|
||||||
|
if ( aToken == pStrFix )
|
||||||
|
bFixedLen = true;
|
||||||
|
aFieldSeps = lcl_decodeSepString( aToken, bMergeFieldSeps);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Token 1: Text separator.
|
// Token 1: Text separator.
|
||||||
@@ -111,9 +119,22 @@ void ScAsciiOptions::ReadFromString( std::u16string_view rString )
|
|||||||
// Token 2: Text encoding.
|
// Token 2: Text encoding.
|
||||||
if ( nPos >= 0 )
|
if ( nPos >= 0 )
|
||||||
{
|
{
|
||||||
eCharSet = ScGlobal::GetCharsetValue( o3tl::getToken(rString, 0, ',', nPos) );
|
const std::u16string_view aToken = o3tl::getToken(rString, 0, ',', nPos);
|
||||||
|
SvStreamEndian endian;
|
||||||
|
bool bDetectCharSet = aToken == pStrDet;
|
||||||
|
if ( bDetectCharSet && pStream4Detect )
|
||||||
|
{
|
||||||
|
SfxObjectShell::DetectCharSet(*pStream4Detect, eCharSet, endian);
|
||||||
|
if (eCharSet == RTL_TEXTENCODING_UNICODE)
|
||||||
|
pStream4Detect->SetEndian(endian);
|
||||||
|
}
|
||||||
|
else if (!bDetectCharSet)
|
||||||
|
eCharSet = ScGlobal::GetCharsetValue( aToken );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (bDetectSep && pStream4Detect)
|
||||||
|
SfxObjectShell::DetectCsvSeparators(*pStream4Detect, eCharSet, aFieldSeps, cTextSep);
|
||||||
|
|
||||||
// Token 3: Number of start row.
|
// Token 3: Number of start row.
|
||||||
if ( nPos >= 0 )
|
if ( nPos >= 0 )
|
||||||
{
|
{
|
||||||
|
@@ -57,6 +57,26 @@ ScCsvTableBox::~ScCsvTableBox()
|
|||||||
|
|
||||||
// common table box handling --------------------------------------------------
|
// common table box handling --------------------------------------------------
|
||||||
|
|
||||||
|
void ScCsvTableBox::Refresh()
|
||||||
|
{
|
||||||
|
mxGrid->DisableRepaint();
|
||||||
|
mxGrid->Execute( CSVCMD_SETLINEOFFSET, 0 );
|
||||||
|
if (mbFixedMode)
|
||||||
|
{
|
||||||
|
mxGrid->Execute( CSVCMD_SETPOSCOUNT, mnFixedWidth );
|
||||||
|
mxGrid->SetSplits( mxRuler->GetSplits() );
|
||||||
|
mxGrid->SetColumnStates( std::vector(maFixColStates) );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mxGrid->Execute( CSVCMD_SETPOSCOUNT, 1 );
|
||||||
|
mxGrid->Execute( CSVCMD_NEWCELLTEXTS );
|
||||||
|
mxGrid->SetColumnStates( std::vector(maSepColStates) );
|
||||||
|
}
|
||||||
|
InitControls();
|
||||||
|
mxGrid->EnableRepaint();
|
||||||
|
}
|
||||||
|
|
||||||
void ScCsvTableBox::SetSeparatorsMode()
|
void ScCsvTableBox::SetSeparatorsMode()
|
||||||
{
|
{
|
||||||
if( !mbFixedMode )
|
if( !mbFixedMode )
|
||||||
@@ -68,13 +88,7 @@ void ScCsvTableBox::SetSeparatorsMode()
|
|||||||
// switch to separators mode
|
// switch to separators mode
|
||||||
mbFixedMode = false;
|
mbFixedMode = false;
|
||||||
// reset and reinitialize controls
|
// reset and reinitialize controls
|
||||||
mxGrid->DisableRepaint();
|
Refresh();
|
||||||
mxGrid->Execute( CSVCMD_SETLINEOFFSET, 0 );
|
|
||||||
mxGrid->Execute( CSVCMD_SETPOSCOUNT, 1 );
|
|
||||||
mxGrid->Execute( CSVCMD_NEWCELLTEXTS );
|
|
||||||
mxGrid->SetColumnStates( std::vector(maSepColStates) );
|
|
||||||
InitControls();
|
|
||||||
mxGrid->EnableRepaint();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ScCsvTableBox::SetFixedWidthMode()
|
void ScCsvTableBox::SetFixedWidthMode()
|
||||||
@@ -87,13 +101,7 @@ void ScCsvTableBox::SetFixedWidthMode()
|
|||||||
// switch to fixed width mode
|
// switch to fixed width mode
|
||||||
mbFixedMode = true;
|
mbFixedMode = true;
|
||||||
// reset and reinitialize controls
|
// reset and reinitialize controls
|
||||||
mxGrid->DisableRepaint();
|
Refresh();
|
||||||
mxGrid->Execute( CSVCMD_SETLINEOFFSET, 0 );
|
|
||||||
mxGrid->Execute( CSVCMD_SETPOSCOUNT, mnFixedWidth );
|
|
||||||
mxGrid->SetSplits( mxRuler->GetSplits() );
|
|
||||||
mxGrid->SetColumnStates( std::vector(maFixColStates) );
|
|
||||||
InitControls();
|
|
||||||
mxGrid->EnableRepaint();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ScCsvTableBox::Init()
|
void ScCsvTableBox::Init()
|
||||||
|
@@ -41,6 +41,8 @@
|
|||||||
#include <o3tl/string_view.hxx>
|
#include <o3tl/string_view.hxx>
|
||||||
|
|
||||||
#include <unicode/ucsdet.h>
|
#include <unicode/ucsdet.h>
|
||||||
|
#include <sfx2/objsh.hxx>
|
||||||
|
#include <svx/txenctab.hxx>
|
||||||
|
|
||||||
//! TODO make dynamic
|
//! TODO make dynamic
|
||||||
const SCSIZE ASCIIDLG_MAXROWS = MAXROWCOUNT;
|
const SCSIZE ASCIIDLG_MAXROWS = MAXROWCOUNT;
|
||||||
@@ -67,6 +69,7 @@ enum CSVImportOptionsIndex
|
|||||||
CSVIO_FixedWidth,
|
CSVIO_FixedWidth,
|
||||||
CSVIO_RemoveSpace,
|
CSVIO_RemoveSpace,
|
||||||
CSVIO_EvaluateFormulas,
|
CSVIO_EvaluateFormulas,
|
||||||
|
CSVIO_SeparatorType,
|
||||||
// Settings for *all* dialog invocations above.
|
// Settings for *all* dialog invocations above.
|
||||||
// Settings not for SC_TEXTTOCOLUMNS below.
|
// Settings not for SC_TEXTTOCOLUMNS below.
|
||||||
CSVIO_FromRow,
|
CSVIO_FromRow,
|
||||||
@@ -80,6 +83,13 @@ enum CSVImportOptionsIndex
|
|||||||
CSVIO_PasteSkipEmptyCells
|
CSVIO_PasteSkipEmptyCells
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum SeparatorType
|
||||||
|
{
|
||||||
|
FIXED,
|
||||||
|
SEPARATOR,
|
||||||
|
DETECT_SEPARATOR
|
||||||
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Config items for all three paths are defined in
|
// Config items for all three paths are defined in
|
||||||
@@ -93,6 +103,7 @@ const ::std::vector<OUString> CSVImportOptionNames =
|
|||||||
u"FixedWidth"_ustr,
|
u"FixedWidth"_ustr,
|
||||||
u"RemoveSpace"_ustr,
|
u"RemoveSpace"_ustr,
|
||||||
u"EvaluateFormulas"_ustr,
|
u"EvaluateFormulas"_ustr,
|
||||||
|
u"SeparatorType"_ustr,
|
||||||
u"FromRow"_ustr,
|
u"FromRow"_ustr,
|
||||||
u"CharSet"_ustr,
|
u"CharSet"_ustr,
|
||||||
u"QuotedFieldAsText"_ustr,
|
u"QuotedFieldAsText"_ustr,
|
||||||
@@ -176,16 +187,16 @@ static void lcl_CreatePropertiesNames ( OUString& rSepPath, Sequence<OUString>&
|
|||||||
{
|
{
|
||||||
case SC_IMPORTFILE:
|
case SC_IMPORTFILE:
|
||||||
rSepPath = aSep_Path;
|
rSepPath = aSep_Path;
|
||||||
nProperties = 12;
|
nProperties = 13;
|
||||||
break;
|
break;
|
||||||
case SC_PASTETEXT:
|
case SC_PASTETEXT:
|
||||||
rSepPath = aSep_Path_Clpbrd;
|
rSepPath = aSep_Path_Clpbrd;
|
||||||
nProperties = 13;
|
nProperties = 14;
|
||||||
break;
|
break;
|
||||||
case SC_TEXTTOCOLUMNS:
|
case SC_TEXTTOCOLUMNS:
|
||||||
default:
|
default:
|
||||||
rSepPath = aSep_Path_Text2Col;
|
rSepPath = aSep_Path_Text2Col;
|
||||||
nProperties = 7;
|
nProperties = 8;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
rNames.realloc( nProperties );
|
rNames.realloc( nProperties );
|
||||||
@@ -196,6 +207,7 @@ static void lcl_CreatePropertiesNames ( OUString& rSepPath, Sequence<OUString>&
|
|||||||
pNames[ CSVIO_FixedWidth ] = CSVImportOptionNames[ CSVIO_FixedWidth ];
|
pNames[ CSVIO_FixedWidth ] = CSVImportOptionNames[ CSVIO_FixedWidth ];
|
||||||
pNames[ CSVIO_RemoveSpace ] = CSVImportOptionNames[ CSVIO_RemoveSpace ];
|
pNames[ CSVIO_RemoveSpace ] = CSVImportOptionNames[ CSVIO_RemoveSpace ];
|
||||||
pNames[ CSVIO_EvaluateFormulas ] = CSVImportOptionNames[ CSVIO_EvaluateFormulas ];
|
pNames[ CSVIO_EvaluateFormulas ] = CSVImportOptionNames[ CSVIO_EvaluateFormulas ];
|
||||||
|
pNames[ CSVIO_SeparatorType ] = CSVImportOptionNames[ CSVIO_SeparatorType ];
|
||||||
if (eCall != SC_TEXTTOCOLUMNS)
|
if (eCall != SC_TEXTTOCOLUMNS)
|
||||||
{
|
{
|
||||||
pNames[ CSVIO_FromRow ] = CSVImportOptionNames[ CSVIO_FromRow ];
|
pNames[ CSVIO_FromRow ] = CSVImportOptionNames[ CSVIO_FromRow ];
|
||||||
@@ -215,9 +227,9 @@ static void lcl_CreatePropertiesNames ( OUString& rSepPath, Sequence<OUString>&
|
|||||||
|
|
||||||
static void lcl_LoadSeparators( OUString& rFieldSeparators, OUString& rTextSeparators,
|
static void lcl_LoadSeparators( OUString& rFieldSeparators, OUString& rTextSeparators,
|
||||||
bool& rMergeDelimiters, bool& rQuotedAsText, bool& rDetectSpecialNum, bool& rDetectScientificNum,
|
bool& rMergeDelimiters, bool& rQuotedAsText, bool& rDetectSpecialNum, bool& rDetectScientificNum,
|
||||||
bool& rFixedWidth, sal_Int32& rFromRow, sal_Int32& rCharSet,
|
SeparatorType& rSepType, sal_Int32& rFromRow, sal_Int32& rCharSet,
|
||||||
sal_Int32& rLanguage, bool& rSkipEmptyCells, bool& rRemoveSpace,
|
sal_Int32& rLanguage, bool& rSkipEmptyCells, bool& rRemoveSpace,
|
||||||
bool& rEvaluateFormulas, ScImportAsciiCall eCall )
|
bool& rEvaluateFormulas, ScImportAsciiCall eCall, bool& rBeforeDetection )
|
||||||
{
|
{
|
||||||
Sequence<Any>aValues;
|
Sequence<Any>aValues;
|
||||||
const Any *pProperties;
|
const Any *pProperties;
|
||||||
@@ -240,8 +252,14 @@ static void lcl_LoadSeparators( OUString& rFieldSeparators, OUString& rTextSepar
|
|||||||
if( pProperties[ CSVIO_TextSeparators ].hasValue() )
|
if( pProperties[ CSVIO_TextSeparators ].hasValue() )
|
||||||
pProperties[ CSVIO_TextSeparators ] >>= rTextSeparators;
|
pProperties[ CSVIO_TextSeparators ] >>= rTextSeparators;
|
||||||
|
|
||||||
if( pProperties[ CSVIO_FixedWidth ].hasValue() )
|
rBeforeDetection = true;
|
||||||
rFixedWidth = ScUnoHelpFunctions::GetBoolFromAny( pProperties[ CSVIO_FixedWidth ] );
|
if( pProperties[ CSVIO_SeparatorType ].hasValue() )
|
||||||
|
{
|
||||||
|
rBeforeDetection = false;
|
||||||
|
rSepType = static_cast<SeparatorType>(ScUnoHelpFunctions::GetInt16FromAny( pProperties[ CSVIO_SeparatorType ] ));
|
||||||
|
}
|
||||||
|
else if( pProperties[ CSVIO_FixedWidth ].hasValue() )
|
||||||
|
rSepType = (ScUnoHelpFunctions::GetBoolFromAny( pProperties[ CSVIO_FixedWidth ] ) ? SeparatorType::FIXED : SeparatorType::DETECT_SEPARATOR);
|
||||||
|
|
||||||
if( pProperties[ CSVIO_EvaluateFormulas ].hasValue() )
|
if( pProperties[ CSVIO_EvaluateFormulas ].hasValue() )
|
||||||
rEvaluateFormulas = ScUnoHelpFunctions::GetBoolFromAny( pProperties[ CSVIO_EvaluateFormulas ] );
|
rEvaluateFormulas = ScUnoHelpFunctions::GetBoolFromAny( pProperties[ CSVIO_EvaluateFormulas ] );
|
||||||
@@ -277,7 +295,7 @@ static void lcl_LoadSeparators( OUString& rFieldSeparators, OUString& rTextSepar
|
|||||||
|
|
||||||
static void lcl_SaveSeparators(
|
static void lcl_SaveSeparators(
|
||||||
const OUString& sFieldSeparators, const OUString& sTextSeparators, bool bMergeDelimiters, bool bQuotedAsText,
|
const OUString& sFieldSeparators, const OUString& sTextSeparators, bool bMergeDelimiters, bool bQuotedAsText,
|
||||||
bool bDetectSpecialNum, bool bDetectScientificNum, bool bFixedWidth, sal_Int32 nFromRow,
|
bool bDetectSpecialNum, bool bDetectScientificNum, SeparatorType rSepType, sal_Int32 nFromRow,
|
||||||
sal_Int32 nCharSet, sal_Int32 nLanguage, bool bSkipEmptyCells, bool bRemoveSpace, bool bEvaluateFormulas,
|
sal_Int32 nCharSet, sal_Int32 nLanguage, bool bSkipEmptyCells, bool bRemoveSpace, bool bEvaluateFormulas,
|
||||||
ScImportAsciiCall eCall )
|
ScImportAsciiCall eCall )
|
||||||
{
|
{
|
||||||
@@ -294,8 +312,8 @@ static void lcl_SaveSeparators(
|
|||||||
pProperties[ CSVIO_RemoveSpace ] <<= bRemoveSpace;
|
pProperties[ CSVIO_RemoveSpace ] <<= bRemoveSpace;
|
||||||
pProperties[ CSVIO_Separators ] <<= sFieldSeparators;
|
pProperties[ CSVIO_Separators ] <<= sFieldSeparators;
|
||||||
pProperties[ CSVIO_TextSeparators ] <<= sTextSeparators;
|
pProperties[ CSVIO_TextSeparators ] <<= sTextSeparators;
|
||||||
pProperties[ CSVIO_FixedWidth ] <<= bFixedWidth;
|
|
||||||
pProperties[ CSVIO_EvaluateFormulas ] <<= bEvaluateFormulas;
|
pProperties[ CSVIO_EvaluateFormulas ] <<= bEvaluateFormulas;
|
||||||
|
pProperties[ CSVIO_SeparatorType ] <<= static_cast<sal_Int16>(rSepType);
|
||||||
if (eCall != SC_TEXTTOCOLUMNS)
|
if (eCall != SC_TEXTTOCOLUMNS)
|
||||||
{
|
{
|
||||||
pProperties[ CSVIO_FromRow ] <<= nFromRow;
|
pProperties[ CSVIO_FromRow ] <<= nFromRow;
|
||||||
@@ -316,21 +334,24 @@ static void lcl_SaveSeparators(
|
|||||||
}
|
}
|
||||||
|
|
||||||
ScImportAsciiDlg::ScImportAsciiDlg(weld::Window* pParent, std::u16string_view aDatName,
|
ScImportAsciiDlg::ScImportAsciiDlg(weld::Window* pParent, std::u16string_view aDatName,
|
||||||
SvStream* pInStream, ScImportAsciiCall eCall,
|
SvStream* pInStream, ScImportAsciiCall eCall)
|
||||||
const ScAsciiOptions* aOptions)
|
|
||||||
: GenericDialogController(pParent, u"modules/scalc/ui/textimportcsv.ui"_ustr, u"TextImportCsvDialog"_ustr)
|
: GenericDialogController(pParent, u"modules/scalc/ui/textimportcsv.ui"_ustr, u"TextImportCsvDialog"_ustr)
|
||||||
, mpDatStream(pInStream)
|
, mpDatStream(pInStream)
|
||||||
, mnStreamPos(pInStream ? pInStream->Tell() : 0)
|
, mnStreamPos(pInStream ? pInStream->Tell() : 0)
|
||||||
|
, mnStreamInitPos(mnStreamPos)
|
||||||
, mnRowPosCount(0)
|
, mnRowPosCount(0)
|
||||||
, mcTextSep(ScAsciiOptions::cDefaultTextSep)
|
, mcTextSep(ScAsciiOptions::cDefaultTextSep)
|
||||||
|
, meDetectedCharSet(RTL_TEXTENCODING_DONTKNOW)
|
||||||
|
, mbCharSetDetect(true)
|
||||||
, meCall(eCall)
|
, meCall(eCall)
|
||||||
, mbDetectSep(eCall != SC_TEXTTOCOLUMNS)
|
|
||||||
, mxFtCharSet(m_xBuilder->weld_label(u"textcharset"_ustr))
|
, mxFtCharSet(m_xBuilder->weld_label(u"textcharset"_ustr))
|
||||||
, mxLbCharSet(new SvxTextEncodingBox(m_xBuilder->weld_combo_box(u"charset"_ustr)))
|
, mxLbCharSet(new SvxTextEncodingBox(m_xBuilder->weld_combo_box(u"charset"_ustr)))
|
||||||
|
, mxFtDetectedCharSet(m_xBuilder->weld_label(u"textdetectedcharset"_ustr))
|
||||||
, mxFtCustomLang(m_xBuilder->weld_label(u"textlanguage"_ustr))
|
, mxFtCustomLang(m_xBuilder->weld_label(u"textlanguage"_ustr))
|
||||||
, mxLbCustomLang(new SvxLanguageBox(m_xBuilder->weld_combo_box(u"language"_ustr)))
|
, mxLbCustomLang(new SvxLanguageBox(m_xBuilder->weld_combo_box(u"language"_ustr)))
|
||||||
, mxFtRow(m_xBuilder->weld_label(u"textfromrow"_ustr))
|
, mxFtRow(m_xBuilder->weld_label(u"textfromrow"_ustr))
|
||||||
, mxNfRow(m_xBuilder->weld_spin_button(u"fromrow"_ustr))
|
, mxNfRow(m_xBuilder->weld_spin_button(u"fromrow"_ustr))
|
||||||
|
, mxRbDetectSep(m_xBuilder->weld_radio_button(u"todetectseparator"_ustr))
|
||||||
, mxRbFixed(m_xBuilder->weld_radio_button(u"tofixedwidth"_ustr))
|
, mxRbFixed(m_xBuilder->weld_radio_button(u"tofixedwidth"_ustr))
|
||||||
, mxRbSeparated(m_xBuilder->weld_radio_button(u"toseparatedby"_ustr))
|
, mxRbSeparated(m_xBuilder->weld_radio_button(u"toseparatedby"_ustr))
|
||||||
, mxCkbTab(m_xBuilder->weld_check_button(u"tab"_ustr))
|
, mxCkbTab(m_xBuilder->weld_check_button(u"tab"_ustr))
|
||||||
@@ -376,40 +397,23 @@ ScImportAsciiDlg::ScImportAsciiDlg(weld::Window* pParent, std::u16string_view aD
|
|||||||
OUString sFieldSeparators(u",;\t"_ustr);
|
OUString sFieldSeparators(u",;\t"_ustr);
|
||||||
OUString sTextSeparators(mcTextSep);
|
OUString sTextSeparators(mcTextSep);
|
||||||
bool bMergeDelimiters = false;
|
bool bMergeDelimiters = false;
|
||||||
bool bFixedWidth = false;
|
SeparatorType eSepType = DETECT_SEPARATOR;
|
||||||
bool bQuotedFieldAsText = false;
|
bool bQuotedFieldAsText = false;
|
||||||
bool bDetectSpecialNum = true;
|
bool bDetectSpecialNum = true;
|
||||||
bool bDetectScientificNum = true;
|
bool bDetectScientificNum = true;
|
||||||
bool bEvaluateFormulas = (meCall != SC_IMPORTFILE);
|
bool bEvaluateFormulas = (meCall != SC_IMPORTFILE);
|
||||||
bool bSkipEmptyCells = true;
|
bool bSkipEmptyCells = true;
|
||||||
bool bRemoveSpace = false;
|
bool bRemoveSpace = false;
|
||||||
|
bool bBeforeDetection = false;
|
||||||
sal_Int32 nFromRow = 1;
|
sal_Int32 nFromRow = 1;
|
||||||
sal_Int32 nCharSet = -1;
|
sal_Int32 nCharSet = -1;
|
||||||
sal_Int32 nLanguage = 0;
|
sal_Int32 nLanguage = 0;
|
||||||
|
|
||||||
if (aOptions)
|
lcl_LoadSeparators (sFieldSeparators, sTextSeparators, bMergeDelimiters,
|
||||||
{
|
bQuotedFieldAsText, bDetectSpecialNum, bDetectScientificNum, eSepType, nFromRow,
|
||||||
if (!aOptions->GetFieldSeps().isEmpty())
|
nCharSet, nLanguage, bSkipEmptyCells, bRemoveSpace, bEvaluateFormulas, meCall,
|
||||||
sFieldSeparators = aOptions->GetFieldSeps();
|
bBeforeDetection);
|
||||||
if (aOptions->GetTextSep())
|
|
||||||
sTextSeparators = OUStringChar(aOptions->GetTextSep());
|
|
||||||
bMergeDelimiters = aOptions->IsMergeSeps();
|
|
||||||
bFixedWidth = aOptions->IsFixedLen();
|
|
||||||
bQuotedFieldAsText = aOptions->IsQuotedAsText();
|
|
||||||
bDetectSpecialNum = aOptions->IsDetectSpecialNumber();
|
|
||||||
bDetectScientificNum = aOptions->IsDetectScientificNumber();
|
|
||||||
bEvaluateFormulas = aOptions->IsEvaluateFormulas();
|
|
||||||
bSkipEmptyCells = aOptions->IsSkipEmptyCells();
|
|
||||||
bRemoveSpace = aOptions->IsRemoveSpace();
|
|
||||||
nFromRow = aOptions->GetStartRow();
|
|
||||||
nCharSet = aOptions->GetCharSet();
|
|
||||||
nLanguage = static_cast<sal_uInt16>(aOptions->GetLanguage());
|
|
||||||
}
|
|
||||||
else
|
|
||||||
lcl_LoadSeparators (sFieldSeparators, sTextSeparators, bMergeDelimiters,
|
|
||||||
bQuotedFieldAsText, bDetectSpecialNum, bDetectScientificNum, bFixedWidth, nFromRow,
|
|
||||||
nCharSet, nLanguage, bSkipEmptyCells, bRemoveSpace, bEvaluateFormulas, meCall);
|
|
||||||
// load from saved settings
|
|
||||||
maFieldSeparators = sFieldSeparators;
|
maFieldSeparators = sFieldSeparators;
|
||||||
|
|
||||||
if( bMergeDelimiters && !bIsTSV )
|
if( bMergeDelimiters && !bIsTSV )
|
||||||
@@ -430,95 +434,48 @@ ScImportAsciiDlg::ScImportAsciiDlg(weld::Window* pParent, std::u16string_view aD
|
|||||||
mxCkbEvaluateFormulas->set_active(true);
|
mxCkbEvaluateFormulas->set_active(true);
|
||||||
if (bSkipEmptyCells)
|
if (bSkipEmptyCells)
|
||||||
mxCkbSkipEmptyCells->set_active(true);
|
mxCkbSkipEmptyCells->set_active(true);
|
||||||
if (bFixedWidth && !bIsTSV)
|
if (eSepType == SeparatorType::FIXED)
|
||||||
mxRbFixed->set_active(true);
|
{
|
||||||
|
if (bIsTSV)
|
||||||
|
{
|
||||||
|
eSepType = SeparatorType::SEPARATOR;
|
||||||
|
mxRbSeparated->set_active(true);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
mxRbFixed->set_active(true);
|
||||||
|
}
|
||||||
|
else if (eSepType == SeparatorType::SEPARATOR)
|
||||||
|
mxRbSeparated->set_active(true);
|
||||||
|
else
|
||||||
|
mxRbDetectSep->set_active(true);
|
||||||
if (nFromRow != 1)
|
if (nFromRow != 1)
|
||||||
mxNfRow->set_value(nFromRow);
|
mxNfRow->set_value(nFromRow);
|
||||||
|
|
||||||
// Clipboard is always Unicode, else detect.
|
// Clipboard is always Unicode, else rely on default/config.
|
||||||
rtl_TextEncoding ePreselectUnicode = (aOptions ? aOptions->GetCharSet() : (meCall == SC_IMPORTFILE ?
|
rtl_TextEncoding ePreselectUnicode = (meCall == SC_IMPORTFILE ?
|
||||||
RTL_TEXTENCODING_DONTKNOW : RTL_TEXTENCODING_UNICODE));
|
RTL_TEXTENCODING_DONTKNOW : RTL_TEXTENCODING_UNICODE);
|
||||||
// Sniff for Unicode / not
|
|
||||||
if( ePreselectUnicode == RTL_TEXTENCODING_DONTKNOW && mpDatStream )
|
// Detect character set only once and then use it for "Detect" option.
|
||||||
|
SvStreamEndian eEndian;
|
||||||
|
SfxObjectShell::DetectCharSet(*mpDatStream, meDetectedCharSet, eEndian);
|
||||||
|
if (meDetectedCharSet == RTL_TEXTENCODING_UNICODE)
|
||||||
|
mpDatStream->SetEndian(eEndian);
|
||||||
|
else if ( meDetectedCharSet == RTL_TEXTENCODING_DONTKNOW )
|
||||||
{
|
{
|
||||||
mpDatStream->Seek( 0 );
|
meDetectedCharSet = osl_getThreadTextEncoding();
|
||||||
constexpr size_t buffsize = 4096;
|
// Prefer UTF-8, as UTF-16 would have already been detected from the stream.
|
||||||
sal_Int8 bytes[buffsize] = { 0 };
|
// This gives a better chance that the file is going to be opened correctly.
|
||||||
sal_Int32 nRead = mpDatStream->ReadBytes( bytes, buffsize );
|
if ( meDetectedCharSet == RTL_TEXTENCODING_UNICODE && mpDatStream )
|
||||||
mpDatStream->Seek( 0 );
|
meDetectedCharSet = RTL_TEXTENCODING_UTF8;
|
||||||
|
|
||||||
if ( nRead > 0 )
|
|
||||||
{
|
|
||||||
UErrorCode uerr = U_ZERO_ERROR;
|
|
||||||
UCharsetDetector* ucd = ucsdet_open( &uerr );
|
|
||||||
ucsdet_setText( ucd, reinterpret_cast<const char*>(bytes), nRead, &uerr );
|
|
||||||
|
|
||||||
if ( const UCharsetMatch* match = ucsdet_detect(ucd, &uerr) )
|
|
||||||
{
|
|
||||||
const char* pEncodingName = ucsdet_getName( match, &uerr );
|
|
||||||
|
|
||||||
if ( U_SUCCESS(uerr) && !strcmp("UTF-8", pEncodingName) )
|
|
||||||
{
|
|
||||||
ePreselectUnicode = RTL_TEXTENCODING_UTF8; // UTF-8
|
|
||||||
mpDatStream->StartReadingUnicodeText( RTL_TEXTENCODING_UTF8 );
|
|
||||||
}
|
|
||||||
else if ( U_SUCCESS(uerr) && !strcmp("UTF-16LE", pEncodingName) )
|
|
||||||
{
|
|
||||||
ePreselectUnicode = RTL_TEXTENCODING_UNICODE; // UTF-16LE
|
|
||||||
mpDatStream->SetEndian( SvStreamEndian::LITTLE );
|
|
||||||
mpDatStream->StartReadingUnicodeText( RTL_TEXTENCODING_UNICODE );
|
|
||||||
}
|
|
||||||
else if ( U_SUCCESS(uerr) && !strcmp("UTF-16BE", pEncodingName) )
|
|
||||||
{
|
|
||||||
ePreselectUnicode = RTL_TEXTENCODING_UNICODE; // UTF-16BE
|
|
||||||
mpDatStream->SetEndian( SvStreamEndian::BIG );
|
|
||||||
mpDatStream->StartReadingUnicodeText( RTL_TEXTENCODING_UNICODE );
|
|
||||||
}
|
|
||||||
else // other
|
|
||||||
mpDatStream->StartReadingUnicodeText( RTL_TEXTENCODING_DONTKNOW );
|
|
||||||
}
|
|
||||||
|
|
||||||
ucsdet_close( ucd );
|
|
||||||
}
|
|
||||||
|
|
||||||
mnStreamPos = mpDatStream->Tell();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (aOptions && !maFieldSeparators.isEmpty())
|
if (bIsTSV)
|
||||||
SetSeparators(0);
|
|
||||||
else if (bIsTSV)
|
|
||||||
SetSeparators('\t');
|
SetSeparators('\t');
|
||||||
else
|
else
|
||||||
{
|
SetSeparators(0);
|
||||||
// Some MS-Excel convention is the first line containing the field
|
|
||||||
// separator as "sep=|" (without quotes and any field separator
|
|
||||||
// character). The second possibility seems to be it is present *with*
|
|
||||||
// quotes so it shows up as cell content *including* the separator and
|
|
||||||
// can be preserved during round trips. Check for an exact match of
|
|
||||||
// any such and set separator.
|
|
||||||
/* TODO: it is debatable whether the unquoted form should rather be
|
|
||||||
* treated special to actually include the separator in the field data.
|
|
||||||
* Currently it does not. */
|
|
||||||
sal_Unicode cSep = 0;
|
|
||||||
OUString aLine;
|
|
||||||
// Try to read one more character, if more than 7 it can't be an exact
|
|
||||||
// match of any.
|
|
||||||
mpDatStream->ReadUniOrByteStringLine( aLine, mpDatStream->GetStreamCharSet(), 8);
|
|
||||||
mpDatStream->Seek(mnStreamPos);
|
|
||||||
if (aLine.getLength() == 8)
|
|
||||||
; // nothing
|
|
||||||
else if (aLine.getLength() == 5 && aLine.startsWithIgnoreAsciiCase("sep="))
|
|
||||||
cSep = aLine[4];
|
|
||||||
else if (aLine.getLength() == 7 && aLine[6] == '"' && aLine.startsWithIgnoreAsciiCase("\"sep="))
|
|
||||||
cSep = aLine[5];
|
|
||||||
|
|
||||||
// Set Separators in the dialog from maFieldSeparators (empty are not
|
|
||||||
// set) or an optionally defined by file content field separator.
|
|
||||||
SetSeparators(cSep);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get Separators from the dialog (empty are set from default)
|
// Get Separators from the dialog (empty are set from default)
|
||||||
maFieldSeparators = GetSeparators();
|
maFieldSeparators = GetActiveSeparators();
|
||||||
|
|
||||||
mxNfRow->connect_value_changed( LINK( this, ScImportAsciiDlg, FirstRowHdl ) );
|
mxNfRow->connect_value_changed( LINK( this, ScImportAsciiDlg, FirstRowHdl ) );
|
||||||
|
|
||||||
@@ -551,22 +508,15 @@ ScImportAsciiDlg::ScImportAsciiDlg(weld::Window* pParent, std::u16string_view aD
|
|||||||
// Insert one "SYSTEM" entry for compatibility in AsciiOptions and system
|
// Insert one "SYSTEM" entry for compatibility in AsciiOptions and system
|
||||||
// independent document linkage.
|
// independent document linkage.
|
||||||
mxLbCharSet->InsertTextEncoding( RTL_TEXTENCODING_DONTKNOW, ScResId( SCSTR_CHARSET_USER ) );
|
mxLbCharSet->InsertTextEncoding( RTL_TEXTENCODING_DONTKNOW, ScResId( SCSTR_CHARSET_USER ) );
|
||||||
if ( ePreselectUnicode == RTL_TEXTENCODING_DONTKNOW )
|
// Insert one for detecting charset.
|
||||||
{
|
mxLbCharSet->InsertTextEncoding( RTL_TEXTENCODING_USER_DETECTED, "- " + ScResId( SCSTR_AUTOMATIC ) + " -" );
|
||||||
rtl_TextEncoding eSystemEncoding = osl_getThreadTextEncoding();
|
|
||||||
// Prefer UTF-8, as UTF-16 would have already been detected from the stream.
|
|
||||||
// This gives a better chance that the file is going to be opened correctly.
|
|
||||||
if ( ( eSystemEncoding == RTL_TEXTENCODING_UNICODE ) && mpDatStream )
|
|
||||||
eSystemEncoding = RTL_TEXTENCODING_UTF8;
|
|
||||||
mxLbCharSet->SelectTextEncoding( eSystemEncoding );
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
mxLbCharSet->SelectTextEncoding( ePreselectUnicode );
|
|
||||||
}
|
|
||||||
|
|
||||||
if (nCharSet >= 0 && ePreselectUnicode == RTL_TEXTENCODING_DONTKNOW)
|
if (ePreselectUnicode != RTL_TEXTENCODING_DONTKNOW)
|
||||||
|
mxLbCharSet->SelectTextEncoding( ePreselectUnicode );
|
||||||
|
else if (nCharSet >= 0 && !bBeforeDetection)
|
||||||
mxLbCharSet->set_active(nCharSet);
|
mxLbCharSet->set_active(nCharSet);
|
||||||
|
else
|
||||||
|
mxLbCharSet->SelectTextEncoding(RTL_TEXTENCODING_USER_DETECTED);
|
||||||
|
|
||||||
SetSelectedCharSet();
|
SetSelectedCharSet();
|
||||||
mxLbCharSet->connect_changed( LINK( this, ScImportAsciiDlg, CharSetHdl ) );
|
mxLbCharSet->connect_changed( LINK( this, ScImportAsciiDlg, CharSetHdl ) );
|
||||||
@@ -592,10 +542,10 @@ ScImportAsciiDlg::ScImportAsciiDlg(weld::Window* pParent, std::u16string_view aD
|
|||||||
mxTableBox->InitTypes( *mxLbType );
|
mxTableBox->InitTypes( *mxLbType );
|
||||||
mxTableBox->SetColTypeHdl( LINK( this, ScImportAsciiDlg, ColTypeHdl ) );
|
mxTableBox->SetColTypeHdl( LINK( this, ScImportAsciiDlg, ColTypeHdl ) );
|
||||||
|
|
||||||
|
mxRbDetectSep->connect_toggled( LINK( this, ScImportAsciiDlg, RbSepFixHdl ) );
|
||||||
mxRbSeparated->connect_toggled( LINK( this, ScImportAsciiDlg, RbSepFixHdl ) );
|
mxRbSeparated->connect_toggled( LINK( this, ScImportAsciiDlg, RbSepFixHdl ) );
|
||||||
mxRbFixed->connect_toggled( LINK( this, ScImportAsciiDlg, RbSepFixHdl ) );
|
mxRbFixed->connect_toggled( LINK( this, ScImportAsciiDlg, RbSepFixHdl ) );
|
||||||
|
|
||||||
SetupSeparatorCtrls();
|
|
||||||
RbSepFix();
|
RbSepFix();
|
||||||
|
|
||||||
UpdateVertical();
|
UpdateVertical();
|
||||||
@@ -715,9 +665,9 @@ void ScImportAsciiDlg::GetOptions( ScAsciiOptions& rOpt )
|
|||||||
rOpt.SetFixedLen( mxRbFixed->get_active() );
|
rOpt.SetFixedLen( mxRbFixed->get_active() );
|
||||||
rOpt.SetStartRow( mxNfRow->get_value() );
|
rOpt.SetStartRow( mxNfRow->get_value() );
|
||||||
mxTableBox->FillColumnData( rOpt );
|
mxTableBox->FillColumnData( rOpt );
|
||||||
if( mxRbSeparated->get_active() )
|
if( mxRbSeparated->get_active() || mxRbDetectSep->get_active())
|
||||||
{
|
{
|
||||||
rOpt.SetFieldSeps( GetSeparators() );
|
rOpt.SetFieldSeps( GetActiveSeparators() );
|
||||||
rOpt.SetMergeSeps( mxCkbAsOnce->get_active() );
|
rOpt.SetMergeSeps( mxCkbAsOnce->get_active() );
|
||||||
rOpt.SetRemoveSpace( mxCkbRemoveSpace->get_active() );
|
rOpt.SetRemoveSpace( mxCkbRemoveSpace->get_active() );
|
||||||
rOpt.SetTextSep( lcl_CharFromCombo( *mxCbTextSep, SCSTR_TEXTSEP ) );
|
rOpt.SetTextSep( lcl_CharFromCombo( *mxCbTextSep, SCSTR_TEXTSEP ) );
|
||||||
@@ -732,9 +682,9 @@ void ScImportAsciiDlg::GetOptions( ScAsciiOptions& rOpt )
|
|||||||
|
|
||||||
void ScImportAsciiDlg::SaveParameters()
|
void ScImportAsciiDlg::SaveParameters()
|
||||||
{
|
{
|
||||||
lcl_SaveSeparators( maFieldSeparators, mxCbTextSep->get_active_text(), mxCkbAsOnce->get_active(),
|
lcl_SaveSeparators( GetSeparators(), mxCbTextSep->get_active_text(), mxCkbAsOnce->get_active(),
|
||||||
mxCkbQuotedAsText->get_active(), mxCkbDetectNumber->get_active(), mxCkbDetectScientificNumber->get_active(),
|
mxCkbQuotedAsText->get_active(), mxCkbDetectNumber->get_active(), mxCkbDetectScientificNumber->get_active(),
|
||||||
mxRbFixed->get_active(),
|
mxRbFixed->get_active() ? FIXED : (mxRbDetectSep->get_active() ? DETECT_SEPARATOR : SEPARATOR),
|
||||||
mxNfRow->get_value(),
|
mxNfRow->get_value(),
|
||||||
mxLbCharSet->get_active(),
|
mxLbCharSet->get_active(),
|
||||||
static_cast<sal_uInt16>(mxLbCustomLang->get_active_id()),
|
static_cast<sal_uInt16>(mxLbCustomLang->get_active_id()),
|
||||||
@@ -788,10 +738,27 @@ void ScImportAsciiDlg::SetSeparators( sal_Unicode cSep )
|
|||||||
|
|
||||||
void ScImportAsciiDlg::SetSelectedCharSet()
|
void ScImportAsciiDlg::SetSelectedCharSet()
|
||||||
{
|
{
|
||||||
|
rtl_TextEncoding eOldCharSet = meCharSet;
|
||||||
meCharSet = mxLbCharSet->GetSelectTextEncoding();
|
meCharSet = mxLbCharSet->GetSelectTextEncoding();
|
||||||
|
mbCharSetDetect = (meCharSet == RTL_TEXTENCODING_USER_DETECTED);
|
||||||
mbCharSetSystem = (meCharSet == RTL_TEXTENCODING_DONTKNOW);
|
mbCharSetSystem = (meCharSet == RTL_TEXTENCODING_DONTKNOW);
|
||||||
if( mbCharSetSystem )
|
if (mbCharSetDetect)
|
||||||
|
{
|
||||||
|
meCharSet = meDetectedCharSet;
|
||||||
|
mxFtDetectedCharSet->set_label(SvxTextEncodingTable::GetTextString(meCharSet));
|
||||||
|
}
|
||||||
|
else if( mbCharSetSystem )
|
||||||
|
{
|
||||||
meCharSet = osl_getThreadTextEncoding();
|
meCharSet = osl_getThreadTextEncoding();
|
||||||
|
mxFtDetectedCharSet->set_label(SvxTextEncodingTable::GetTextString(meCharSet));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
mxFtDetectedCharSet->set_label(SvxTextEncodingTable::GetTextString(meCharSet));
|
||||||
|
|
||||||
|
if (eOldCharSet != meCharSet)
|
||||||
|
DetectCsvSeparators();
|
||||||
|
|
||||||
|
RbSepFix();
|
||||||
}
|
}
|
||||||
|
|
||||||
OUString ScImportAsciiDlg::GetSeparators() const
|
OUString ScImportAsciiDlg::GetSeparators() const
|
||||||
@@ -810,6 +777,17 @@ OUString ScImportAsciiDlg::GetSeparators() const
|
|||||||
return aSepChars;
|
return aSepChars;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
OUString ScImportAsciiDlg::GetActiveSeparators() const
|
||||||
|
{
|
||||||
|
if (mxRbSeparated->get_active())
|
||||||
|
return GetSeparators();
|
||||||
|
|
||||||
|
if (mxRbDetectSep->get_active())
|
||||||
|
return maDetectedFieldSeps;
|
||||||
|
|
||||||
|
return OUString();
|
||||||
|
}
|
||||||
|
|
||||||
void ScImportAsciiDlg::SetupSeparatorCtrls()
|
void ScImportAsciiDlg::SetupSeparatorCtrls()
|
||||||
{
|
{
|
||||||
bool bEnable = mxRbSeparated->get_active();
|
bool bEnable = mxRbSeparated->get_active();
|
||||||
@@ -817,12 +795,41 @@ void ScImportAsciiDlg::SetupSeparatorCtrls()
|
|||||||
mxCkbSemicolon->set_sensitive( bEnable );
|
mxCkbSemicolon->set_sensitive( bEnable );
|
||||||
mxCkbComma->set_sensitive( bEnable );
|
mxCkbComma->set_sensitive( bEnable );
|
||||||
mxCkbSpace->set_sensitive( bEnable );
|
mxCkbSpace->set_sensitive( bEnable );
|
||||||
mxCkbRemoveSpace->set_sensitive( bEnable );
|
|
||||||
mxCkbOther->set_sensitive( bEnable );
|
mxCkbOther->set_sensitive( bEnable );
|
||||||
mxEdOther->set_sensitive( bEnable );
|
mxEdOther->set_sensitive( bEnable );
|
||||||
|
|
||||||
|
bEnable = bEnable || mxRbDetectSep->get_active();
|
||||||
|
mxCkbRemoveSpace->set_sensitive( bEnable );
|
||||||
mxCkbAsOnce->set_sensitive( bEnable );
|
mxCkbAsOnce->set_sensitive( bEnable );
|
||||||
mxFtTextSep->set_sensitive( bEnable );
|
mxFtTextSep->set_sensitive( bEnable );
|
||||||
mxCbTextSep->set_sensitive( bEnable );
|
mxCbTextSep->set_sensitive( bEnable );
|
||||||
|
|
||||||
|
OUString aSepName;
|
||||||
|
if (maDetectedFieldSeps.isEmpty())
|
||||||
|
aSepName += ScResId(SCSTR_NONE);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (int idx = 0; idx < maDetectedFieldSeps.getLength(); idx ++)
|
||||||
|
{
|
||||||
|
if (idx > 0)
|
||||||
|
aSepName += u" ";
|
||||||
|
|
||||||
|
if (maDetectedFieldSeps[idx] == u' ')
|
||||||
|
aSepName += ScResId(SCSTR_FIELDSEP_SPACE);
|
||||||
|
else if (maDetectedFieldSeps[idx] == u'\t')
|
||||||
|
aSepName += ScResId(SCSTR_FIELDSEP_TAB);
|
||||||
|
else
|
||||||
|
aSepName += OUStringChar(maDetectedFieldSeps[idx]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mxRbDetectSep->set_label(ScResId(SCSTR_DETECTED).replaceFirst( "%1", aSepName));
|
||||||
|
}
|
||||||
|
|
||||||
|
void ScImportAsciiDlg::DetectCsvSeparators()
|
||||||
|
{
|
||||||
|
mpDatStream->Seek(mnStreamInitPos);
|
||||||
|
SfxObjectShell::DetectCsvSeparators(*mpDatStream, meCharSet, maDetectedFieldSeps, mcTextSep);
|
||||||
|
mpDatStream->Seek(mnStreamPos);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ScImportAsciiDlg::UpdateVertical()
|
void ScImportAsciiDlg::UpdateVertical()
|
||||||
@@ -835,10 +842,17 @@ void ScImportAsciiDlg::UpdateVertical()
|
|||||||
void ScImportAsciiDlg::RbSepFix()
|
void ScImportAsciiDlg::RbSepFix()
|
||||||
{
|
{
|
||||||
weld::WaitObject aWaitObj(m_xDialog.get());
|
weld::WaitObject aWaitObj(m_xDialog.get());
|
||||||
if( mxRbFixed->get_active() )
|
if (mxRbSeparated->get_active() || mxRbDetectSep->get_active())
|
||||||
mxTableBox->SetFixedWidthMode();
|
{
|
||||||
|
maFieldSeparators = GetActiveSeparators();
|
||||||
|
if (mxTableBox->IsFixedWidthMode())
|
||||||
|
mxTableBox->SetSeparatorsMode();
|
||||||
|
else
|
||||||
|
mxTableBox->Refresh();
|
||||||
|
}
|
||||||
else
|
else
|
||||||
mxTableBox->SetSeparatorsMode();
|
mxTableBox->SetFixedWidthMode();
|
||||||
|
|
||||||
SetupSeparatorCtrls();
|
SetupSeparatorCtrls();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -892,13 +906,26 @@ void ScImportAsciiDlg::SeparatorHdl(const weld::Widget* pCtrl)
|
|||||||
mxCkbOther->set_active(!mxEdOther->get_text().isEmpty());
|
mxCkbOther->set_active(!mxEdOther->get_text().isEmpty());
|
||||||
|
|
||||||
OUString aOldFldSeps( maFieldSeparators);
|
OUString aOldFldSeps( maFieldSeparators);
|
||||||
maFieldSeparators = GetSeparators();
|
|
||||||
sal_Unicode cOldSep = mcTextSep;
|
sal_Unicode cOldSep = mcTextSep;
|
||||||
mcTextSep = lcl_CharFromCombo( *mxCbTextSep, SCSTR_TEXTSEP );
|
mcTextSep = lcl_CharFromCombo( *mxCbTextSep, SCSTR_TEXTSEP );
|
||||||
// Any separator changed may result in completely different lines due to
|
// Any separator changed may result in completely different lines due to
|
||||||
// embedded line breaks.
|
// embedded line breaks.
|
||||||
if (cOldSep != mcTextSep || aOldFldSeps != maFieldSeparators)
|
if (cOldSep != mcTextSep)
|
||||||
UpdateVertical();
|
{
|
||||||
|
DetectCsvSeparators();
|
||||||
|
|
||||||
|
SetupSeparatorCtrls();
|
||||||
|
|
||||||
|
maFieldSeparators = GetActiveSeparators();
|
||||||
|
if (aOldFldSeps != maFieldSeparators)
|
||||||
|
{
|
||||||
|
UpdateVertical();
|
||||||
|
mxTableBox->Refresh();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
maFieldSeparators = GetActiveSeparators();
|
||||||
|
|
||||||
mxTableBox->GetGrid().Execute( CSVCMD_NEWCELLTEXTS );
|
mxTableBox->GetGrid().Execute( CSVCMD_NEWCELLTEXTS );
|
||||||
}
|
}
|
||||||
@@ -931,14 +958,7 @@ IMPL_LINK(ScImportAsciiDlg, LbColTypeHdl, weld::ComboBox&, rListBox, void)
|
|||||||
|
|
||||||
IMPL_LINK_NOARG(ScImportAsciiDlg, UpdateTextHdl, ScCsvTableBox&, void)
|
IMPL_LINK_NOARG(ScImportAsciiDlg, UpdateTextHdl, ScCsvTableBox&, void)
|
||||||
{
|
{
|
||||||
// Checking the separator can only be done once for the very first time
|
sal_Unicode cDetectSep = 0xffff;
|
||||||
// when the dialog wasn't already presented to the user.
|
|
||||||
// As a side effect this has the benefit that the check is only done on the
|
|
||||||
// first set of visible lines.
|
|
||||||
mbDetectSep = (mbDetectSep && !mxRbFixed->get_active()
|
|
||||||
&& (!mxCkbTab->get_active() || !mxCkbSemicolon->get_active()
|
|
||||||
|| !mxCkbComma->get_active() || !mxCkbSpace->get_active()));
|
|
||||||
sal_Unicode cDetectSep = (mbDetectSep ? 0 : 0xffff);
|
|
||||||
|
|
||||||
sal_Int32 nBaseLine = mxTableBox->GetGrid().GetFirstVisLine();
|
sal_Int32 nBaseLine = mxTableBox->GetGrid().GetFirstVisLine();
|
||||||
sal_Int32 nRead = mxTableBox->GetGrid().GetVisLineCount();
|
sal_Int32 nRead = mxTableBox->GetGrid().GetVisLineCount();
|
||||||
@@ -958,24 +978,6 @@ IMPL_LINK_NOARG(ScImportAsciiDlg, UpdateTextHdl, ScCsvTableBox&, void)
|
|||||||
for (; i < CSV_PREVIEW_LINES; i++)
|
for (; i < CSV_PREVIEW_LINES; i++)
|
||||||
maPreviewLine[i].clear();
|
maPreviewLine[i].clear();
|
||||||
|
|
||||||
if (mbDetectSep)
|
|
||||||
{
|
|
||||||
mbDetectSep = false;
|
|
||||||
if (cDetectSep)
|
|
||||||
{
|
|
||||||
// Expect separator to be appended by now so all subsequent
|
|
||||||
// GetLine()/ReadCsvLine() actually used it.
|
|
||||||
assert(maFieldSeparators.endsWith(OUStringChar(cDetectSep)));
|
|
||||||
// Preselect separator in UI.
|
|
||||||
switch (cDetectSep)
|
|
||||||
{
|
|
||||||
case '\t': mxCkbTab->set_active(true); break;
|
|
||||||
case ';': mxCkbSemicolon->set_active(true); break;
|
|
||||||
case ',': mxCkbComma->set_active(true); break;
|
|
||||||
case ' ': mxCkbSpace->set_active(true); break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
mxTableBox->GetGrid().Execute( CSVCMD_SETLINECOUNT, mnRowPosCount);
|
mxTableBox->GetGrid().Execute( CSVCMD_SETLINECOUNT, mnRowPosCount);
|
||||||
bool bMergeSep = mxCkbAsOnce->get_active();
|
bool bMergeSep = mxCkbAsOnce->get_active();
|
||||||
|
@@ -1354,7 +1354,7 @@ bool ScDocShell::ConvertFrom( SfxMedium& rMedium )
|
|||||||
|
|
||||||
if ( const SfxStringItem* pOptionsItem = rMedium.GetItemSet().GetItemIfSet( SID_FILE_FILTEROPTIONS ) )
|
if ( const SfxStringItem* pOptionsItem = rMedium.GetItemSet().GetItemIfSet( SID_FILE_FILTEROPTIONS ) )
|
||||||
{
|
{
|
||||||
aOptions.ReadFromString( pOptionsItem->GetValue() );
|
aOptions.ReadFromString( pOptionsItem->GetValue(), rMedium.GetInStream() );
|
||||||
bOptInit = true;
|
bOptInit = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -52,7 +52,7 @@ public:
|
|||||||
|
|
||||||
static const sal_Unicode cDefaultTextSep = '"';
|
static const sal_Unicode cDefaultTextSep = '"';
|
||||||
|
|
||||||
void ReadFromString( std::u16string_view rString );
|
void ReadFromString( std::u16string_view rString, SvStream* pStream4Detect = nullptr );
|
||||||
OUString WriteToString() const;
|
OUString WriteToString() const;
|
||||||
|
|
||||||
rtl_TextEncoding GetCharSet() const { return eCharSet; }
|
rtl_TextEncoding GetCharSet() const { return eCharSet; }
|
||||||
|
@@ -72,10 +72,12 @@ public:
|
|||||||
|
|
||||||
// common table box handling ----------------------------------------------
|
// common table box handling ----------------------------------------------
|
||||||
public:
|
public:
|
||||||
|
void Refresh();
|
||||||
/** Sets the control to separators mode. */
|
/** Sets the control to separators mode. */
|
||||||
void SetSeparatorsMode();
|
void SetSeparatorsMode();
|
||||||
/** Sets the control to fixed width mode. */
|
/** Sets the control to fixed width mode. */
|
||||||
void SetFixedWidthMode();
|
void SetFixedWidthMode();
|
||||||
|
bool IsFixedWidthMode(){ return mbFixedMode; }
|
||||||
|
|
||||||
ScCsvRuler& GetRuler() { return *mxRuler; }
|
ScCsvRuler& GetRuler() { return *mxRuler; }
|
||||||
ScCsvGrid& GetGrid() { return *mxGrid; }
|
ScCsvGrid& GetGrid() { return *mxGrid; }
|
||||||
|
@@ -31,29 +31,34 @@ class SvxTextEncodingBox;
|
|||||||
|
|
||||||
class ScImportAsciiDlg : public weld::GenericDialogController
|
class ScImportAsciiDlg : public weld::GenericDialogController
|
||||||
{
|
{
|
||||||
SvStream* mpDatStream;
|
SvStream* mpDatStream;
|
||||||
sal_uLong mnStreamPos;
|
sal_uLong mnStreamPos;
|
||||||
|
sal_uLong mnStreamInitPos;
|
||||||
std::unique_ptr<sal_uLong[]> mpRowPosArray;
|
std::unique_ptr<sal_uLong[]> mpRowPosArray;
|
||||||
sal_uLong mnRowPosCount;
|
sal_uLong mnRowPosCount;
|
||||||
|
|
||||||
OUString maPreviewLine[ CSV_PREVIEW_LINES ];
|
OUString maPreviewLine[ CSV_PREVIEW_LINES ];
|
||||||
|
|
||||||
OUString maFieldSeparators; // selected field separators
|
OUString maFieldSeparators; // selected field separators
|
||||||
|
OUString maDetectedFieldSeps; // detected field seps
|
||||||
sal_Unicode mcTextSep;
|
sal_Unicode mcTextSep;
|
||||||
|
|
||||||
rtl_TextEncoding meCharSet; /// Selected char set.
|
rtl_TextEncoding meCharSet; /// Selected char set.
|
||||||
|
rtl_TextEncoding meDetectedCharSet; /// This is computed only once at initialization, so store it.
|
||||||
bool mbCharSetSystem; /// Is System char set selected?
|
bool mbCharSetSystem; /// Is System char set selected?
|
||||||
|
bool mbCharSetDetect; /// Should we autodetect character set ?
|
||||||
ScImportAsciiCall meCall; /// How the dialog is called (see asciiopt.hxx)
|
ScImportAsciiCall meCall; /// How the dialog is called (see asciiopt.hxx)
|
||||||
bool mbDetectSep; /// Whether to detect a possible separator.
|
|
||||||
|
|
||||||
std::unique_ptr<weld::Label> mxFtCharSet;
|
std::unique_ptr<weld::Label> mxFtCharSet;
|
||||||
std::unique_ptr<SvxTextEncodingBox> mxLbCharSet;
|
std::unique_ptr<SvxTextEncodingBox> mxLbCharSet;
|
||||||
|
std::unique_ptr<weld::Label> mxFtDetectedCharSet;
|
||||||
std::unique_ptr<weld::Label> mxFtCustomLang;
|
std::unique_ptr<weld::Label> mxFtCustomLang;
|
||||||
std::unique_ptr<SvxLanguageBox> mxLbCustomLang;
|
std::unique_ptr<SvxLanguageBox> mxLbCustomLang;
|
||||||
|
|
||||||
std::unique_ptr<weld::Label> mxFtRow;
|
std::unique_ptr<weld::Label> mxFtRow;
|
||||||
std::unique_ptr<weld::SpinButton> mxNfRow;
|
std::unique_ptr<weld::SpinButton> mxNfRow;
|
||||||
|
|
||||||
|
std::unique_ptr<weld::RadioButton> mxRbDetectSep;
|
||||||
std::unique_ptr<weld::RadioButton> mxRbFixed;
|
std::unique_ptr<weld::RadioButton> mxRbFixed;
|
||||||
std::unique_ptr<weld::RadioButton> mxRbSeparated;
|
std::unique_ptr<weld::RadioButton> mxRbSeparated;
|
||||||
|
|
||||||
@@ -83,8 +88,7 @@ class ScImportAsciiDlg : public weld::GenericDialogController
|
|||||||
public:
|
public:
|
||||||
ScImportAsciiDlg(
|
ScImportAsciiDlg(
|
||||||
weld::Window* pParent, std::u16string_view aDatName,
|
weld::Window* pParent, std::u16string_view aDatName,
|
||||||
SvStream* pInStream, ScImportAsciiCall eCall,
|
SvStream* pInStream, ScImportAsciiCall eCall);
|
||||||
const ScAsciiOptions* aOptions = nullptr );
|
|
||||||
virtual ~ScImportAsciiDlg() override;
|
virtual ~ScImportAsciiDlg() override;
|
||||||
|
|
||||||
void GetOptions( ScAsciiOptions& rOpt );
|
void GetOptions( ScAsciiOptions& rOpt );
|
||||||
@@ -98,6 +102,8 @@ private:
|
|||||||
void SetSeparators( sal_Unicode cSep );
|
void SetSeparators( sal_Unicode cSep );
|
||||||
/** Returns all separator characters in a string. */
|
/** Returns all separator characters in a string. */
|
||||||
OUString GetSeparators() const;
|
OUString GetSeparators() const;
|
||||||
|
OUString GetActiveSeparators() const;
|
||||||
|
void DetectCsvSeparators();
|
||||||
|
|
||||||
/** Enables or disables all separator checkboxes and edit fields. */
|
/** Enables or disables all separator checkboxes and edit fields. */
|
||||||
void SetupSeparatorCtrls();
|
void SetupSeparatorCtrls();
|
||||||
|
@@ -179,25 +179,15 @@ sal_Int16 SAL_CALL ScFilterOptionsObj::execute()
|
|||||||
{
|
{
|
||||||
// ascii import is special...
|
// ascii import is special...
|
||||||
|
|
||||||
ScAsciiOptions aInOptions, *pInOptions = nullptr;
|
|
||||||
INetURLObject aURL( aFileName );
|
INetURLObject aURL( aFileName );
|
||||||
// tdf#132421 - don't URL encode filename for the import ASCII dialog title
|
// tdf#132421 - don't URL encode filename for the import ASCII dialog title
|
||||||
OUString aPrivDatName(aURL.GetLastName(INetURLObject::DecodeMechanism::Unambiguous));
|
OUString aPrivDatName(aURL.GetLastName(INetURLObject::DecodeMechanism::Unambiguous));
|
||||||
std::unique_ptr<SvStream> pInStream;
|
std::unique_ptr<SvStream> pInStream;
|
||||||
if ( xInputStream.is() )
|
if ( xInputStream.is() )
|
||||||
{
|
|
||||||
pInStream = utl::UcbStreamHelper::CreateStream( xInputStream );
|
pInStream = utl::UcbStreamHelper::CreateStream( xInputStream );
|
||||||
|
|
||||||
if (aFilterOptions.isEmpty())
|
|
||||||
aFilterOptions = "DETECT,34,DETECT,,,,,,,,,,,,";
|
|
||||||
SfxObjectShell::DetectCsvFilterOptions(*pInStream, aFilterOptions);
|
|
||||||
|
|
||||||
aInOptions.ReadFromString(aFilterOptions);
|
|
||||||
pInOptions = &aInOptions;
|
|
||||||
}
|
|
||||||
|
|
||||||
ScopedVclPtr<AbstractScImportAsciiDlg> pDlg(pFact->CreateScImportAsciiDlg(Application::GetFrameWeld(xDialogParent), aPrivDatName,
|
ScopedVclPtr<AbstractScImportAsciiDlg> pDlg(pFact->CreateScImportAsciiDlg(Application::GetFrameWeld(xDialogParent), aPrivDatName,
|
||||||
pInStream.get(), SC_IMPORTFILE, pInOptions));
|
pInStream.get(), SC_IMPORTFILE));
|
||||||
if ( pDlg->Execute() == RET_OK )
|
if ( pDlg->Execute() == RET_OK )
|
||||||
{
|
{
|
||||||
ScAsciiOptions aOptions;
|
ScAsciiOptions aOptions;
|
||||||
|
@@ -1040,6 +1040,7 @@ void ScCellShell::ExecuteDB( SfxRequest& rReq )
|
|||||||
ScImportExport::SetNoEndianSwap( aStream );
|
ScImportExport::SetNoEndianSwap( aStream );
|
||||||
aExport.ExportStream( aStream, OUString(), SotClipboardFormatId::STRING );
|
aExport.ExportStream( aStream, OUString(), SotClipboardFormatId::STRING );
|
||||||
|
|
||||||
|
aStream.Seek(0);
|
||||||
ScAbstractDialogFactory* pFact = ScAbstractDialogFactory::Create();
|
ScAbstractDialogFactory* pFact = ScAbstractDialogFactory::Create();
|
||||||
ScopedVclPtr<AbstractScImportAsciiDlg> pDlg(pFact->CreateScImportAsciiDlg(
|
ScopedVclPtr<AbstractScImportAsciiDlg> pDlg(pFact->CreateScImportAsciiDlg(
|
||||||
pTabViewShell->GetFrameWeld(), OUString(), &aStream, SC_TEXTTOCOLUMNS));
|
pTabViewShell->GetFrameWeld(), OUString(), &aStream, SC_TEXTTOCOLUMNS));
|
||||||
|
@@ -137,7 +137,7 @@
|
|||||||
</object>
|
</object>
|
||||||
<packing>
|
<packing>
|
||||||
<property name="left-attach">0</property>
|
<property name="left-attach">0</property>
|
||||||
<property name="top-attach">1</property>
|
<property name="top-attach">2</property>
|
||||||
</packing>
|
</packing>
|
||||||
</child>
|
</child>
|
||||||
<child>
|
<child>
|
||||||
@@ -151,7 +151,7 @@
|
|||||||
</object>
|
</object>
|
||||||
<packing>
|
<packing>
|
||||||
<property name="left-attach">0</property>
|
<property name="left-attach">0</property>
|
||||||
<property name="top-attach">2</property>
|
<property name="top-attach">3</property>
|
||||||
</packing>
|
</packing>
|
||||||
</child>
|
</child>
|
||||||
<child>
|
<child>
|
||||||
@@ -169,6 +169,18 @@
|
|||||||
<property name="top-attach">0</property>
|
<property name="top-attach">0</property>
|
||||||
</packing>
|
</packing>
|
||||||
</child>
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkLabel" id="textdetectedcharset">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can-focus">False</property>
|
||||||
|
<property name="halign">start</property>
|
||||||
|
<property name="label" translatable="no" context="textimportcsv|textcharset"></property>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="left-attach">1</property>
|
||||||
|
<property name="top-attach">1</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkComboBoxText" id="language">
|
<object class="GtkComboBoxText" id="language">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
@@ -181,7 +193,7 @@
|
|||||||
</object>
|
</object>
|
||||||
<packing>
|
<packing>
|
||||||
<property name="left-attach">1</property>
|
<property name="left-attach">1</property>
|
||||||
<property name="top-attach">1</property>
|
<property name="top-attach">2</property>
|
||||||
</packing>
|
</packing>
|
||||||
</child>
|
</child>
|
||||||
<child>
|
<child>
|
||||||
@@ -200,7 +212,7 @@
|
|||||||
</object>
|
</object>
|
||||||
<packing>
|
<packing>
|
||||||
<property name="left-attach">1</property>
|
<property name="left-attach">1</property>
|
||||||
<property name="top-attach">2</property>
|
<property name="top-attach">3</property>
|
||||||
</packing>
|
</packing>
|
||||||
</child>
|
</child>
|
||||||
</object>
|
</object>
|
||||||
@@ -252,7 +264,7 @@
|
|||||||
<property name="receives-default">False</property>
|
<property name="receives-default">False</property>
|
||||||
<property name="use-underline">True</property>
|
<property name="use-underline">True</property>
|
||||||
<property name="draw-indicator">True</property>
|
<property name="draw-indicator">True</property>
|
||||||
<property name="group">toseparatedby</property>
|
<property name="group">todetectseparator</property>
|
||||||
<child internal-child="accessible">
|
<child internal-child="accessible">
|
||||||
<object class="AtkObject" id="tofixedwidth-atkobject">
|
<object class="AtkObject" id="tofixedwidth-atkobject">
|
||||||
<property name="AtkObject::accessible-description" translatable="yes" context="textimportcsv|extended_tip|tofixedwidth">Separates fixed-width data (equal number of characters) into columns.</property>
|
<property name="AtkObject::accessible-description" translatable="yes" context="textimportcsv|extended_tip|tofixedwidth">Separates fixed-width data (equal number of characters) into columns.</property>
|
||||||
@@ -272,8 +284,8 @@
|
|||||||
<property name="can-focus">True</property>
|
<property name="can-focus">True</property>
|
||||||
<property name="receives-default">False</property>
|
<property name="receives-default">False</property>
|
||||||
<property name="use-underline">True</property>
|
<property name="use-underline">True</property>
|
||||||
<property name="active">True</property>
|
|
||||||
<property name="draw-indicator">True</property>
|
<property name="draw-indicator">True</property>
|
||||||
|
<property name="group">todetectseparator</property>
|
||||||
<child internal-child="accessible">
|
<child internal-child="accessible">
|
||||||
<object class="AtkObject" id="toseparatedby-atkobject">
|
<object class="AtkObject" id="toseparatedby-atkobject">
|
||||||
<property name="AtkObject::accessible-description" translatable="yes" context="textimportcsv|extended_tip|toseparatedby">Select the separator used in your data.</property>
|
<property name="AtkObject::accessible-description" translatable="yes" context="textimportcsv|extended_tip|toseparatedby">Select the separator used in your data.</property>
|
||||||
@@ -286,6 +298,27 @@
|
|||||||
<property name="position">1</property>
|
<property name="position">1</property>
|
||||||
</packing>
|
</packing>
|
||||||
</child>
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkRadioButton" id="todetectseparator">
|
||||||
|
<property name="label" translatable="yes" context="textimportcsv|todetectseparator">Detected</property>
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can-focus">True</property>
|
||||||
|
<property name="receives-default">False</property>
|
||||||
|
<property name="use-underline">True</property>
|
||||||
|
<property name="active">True</property>
|
||||||
|
<property name="draw-indicator">True</property>
|
||||||
|
<child internal-child="accessible">
|
||||||
|
<object class="AtkObject" id="todetectseparator-atkobject">
|
||||||
|
<property name="AtkObject::accessible-description" translatable="yes" context="textimportcsv|extended_tip|todetectseparator">Use detected separator.</property>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="expand">False</property>
|
||||||
|
<property name="fill">True</property>
|
||||||
|
<property name="position">2</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
</object>
|
</object>
|
||||||
<packing>
|
<packing>
|
||||||
<property name="expand">False</property>
|
<property name="expand">False</property>
|
||||||
|
@@ -119,7 +119,6 @@
|
|||||||
#include "objstor.hxx"
|
#include "objstor.hxx"
|
||||||
#include "exoticfileloadexception.hxx"
|
#include "exoticfileloadexception.hxx"
|
||||||
#include <unicode/ucsdet.h>
|
#include <unicode/ucsdet.h>
|
||||||
#include <unicode/ucnv.h>
|
|
||||||
#include <o3tl/string_view.hxx>
|
#include <o3tl/string_view.hxx>
|
||||||
|
|
||||||
using namespace ::com::sun::star;
|
using namespace ::com::sun::star;
|
||||||
@@ -960,7 +959,7 @@ void SfxObjectShell::DetectCsvSeparators(SvStream& stream, rtl_TextEncoding& eCh
|
|||||||
std::vector<std::unordered_map<sal_Unicode, sal_uInt32>> aLinesCharsCount;
|
std::vector<std::unordered_map<sal_Unicode, sal_uInt32>> aLinesCharsCount;
|
||||||
std::unordered_map<sal_Unicode, sal_uInt32> aCharsCount;
|
std::unordered_map<sal_Unicode, sal_uInt32> aCharsCount;
|
||||||
std::unordered_map<sal_Unicode, std::pair<sal_uInt32, sal_uInt32>> aStats;
|
std::unordered_map<sal_Unicode, std::pair<sal_uInt32, sal_uInt32>> aStats;
|
||||||
constexpr sal_uInt32 nMaxLinesToProcess = 20;
|
constexpr sal_uInt32 nTimeout = 500; // Timeout for detection in ms
|
||||||
sal_uInt32 nLinesCount = 0;
|
sal_uInt32 nLinesCount = 0;
|
||||||
OUString sInitSeps;
|
OUString sInitSeps;
|
||||||
OUString sCommonSeps = u",\t;:| \\/"_ustr;//Sorted by importance
|
OUString sCommonSeps = u",\t;:| \\/"_ustr;//Sorted by importance
|
||||||
@@ -970,17 +969,18 @@ void SfxObjectShell::DetectCsvSeparators(SvStream& stream, rtl_TextEncoding& eCh
|
|||||||
sal_uInt32 nMaxLinesSameChar = 0;
|
sal_uInt32 nMaxLinesSameChar = 0;
|
||||||
sal_uInt32 nMinDiffs = 0xFFFFFFFF;
|
sal_uInt32 nMinDiffs = 0xFFFFFFFF;
|
||||||
sal_uInt64 nInitPos = stream.Tell();
|
sal_uInt64 nInitPos = stream.Tell();
|
||||||
|
sal_uInt64 nStartTime = tools::Time::GetSystemTicks();
|
||||||
|
|
||||||
if (!cStringDelimiter)
|
if (!cStringDelimiter)
|
||||||
cStringDelimiter = '\"';
|
cStringDelimiter = '\"';
|
||||||
|
|
||||||
for (sal_Int32 nComSepIdx = sCommonSeps.getLength() - 1; nComSepIdx >= 0; nComSepIdx --)
|
for (sal_Int32 nComSepIdx = sCommonSeps.getLength() - 1; nComSepIdx >= 0; nComSepIdx --)
|
||||||
usetCommonSeps.insert(sCommonSeps[nComSepIdx]);
|
usetCommonSeps.insert(sCommonSeps[nComSepIdx]);
|
||||||
aLinesCharsCount.reserve(nMaxLinesToProcess);
|
aLinesCharsCount.reserve(128);
|
||||||
separators = "";
|
separators = "";
|
||||||
|
|
||||||
stream.StartReadingUnicodeText(eCharSet);
|
stream.StartReadingUnicodeText(eCharSet);
|
||||||
while (stream.ReadUniOrByteStringLine(sLine, eCharSet) && aLinesCharsCount.size() < nMaxLinesToProcess)
|
while (stream.ReadUniOrByteStringLine(sLine, eCharSet) && (tools::Time::GetSystemTicks() - nStartTime < nTimeout))
|
||||||
{
|
{
|
||||||
if (sLine.isEmpty())
|
if (sLine.isEmpty())
|
||||||
continue;
|
continue;
|
||||||
@@ -1034,7 +1034,7 @@ void SfxObjectShell::DetectCsvSeparators(SvStream& stream, rtl_TextEncoding& eCh
|
|||||||
{
|
{
|
||||||
auto aCurStats = aStats.find(aCurLineChar->first);
|
auto aCurStats = aStats.find(aCurLineChar->first);
|
||||||
if (aCurStats == aStats.cend())
|
if (aCurStats == aStats.cend())
|
||||||
aStats.insert(std::pair<sal_Unicode, std::pair<sal_uInt32, sal_uInt32>>(aCurLineChar->first, std::pair<sal_uInt32, sal_uInt32>(1, 1)));
|
aCurStats = aStats.insert(std::pair<sal_Unicode, std::pair<sal_uInt32, sal_uInt32>>(aCurLineChar->first, std::pair<sal_uInt32, sal_uInt32>(1, 1))).first;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
aCurStats->second.first ++;// Increment number of lines that contain the current character
|
aCurStats->second.first ++;// Increment number of lines that contain the current character
|
||||||
@@ -1048,17 +1048,19 @@ void SfxObjectShell::DetectCsvSeparators(SvStream& stream, rtl_TextEncoding& eCh
|
|||||||
}
|
}
|
||||||
if (aPrevLineChar == aLinesCharsCount.cend())
|
if (aPrevLineChar == aLinesCharsCount.cend())
|
||||||
aCurStats->second.second ++;// Increment number of different number of occurrences.
|
aCurStats->second.second ++;// Increment number of different number of occurrences.
|
||||||
|
|
||||||
// Update the maximum of number of lines that contain the same character. This is a global value.
|
|
||||||
if (nMaxLinesSameChar < aCurStats->second.first)
|
|
||||||
nMaxLinesSameChar = aCurStats->second.first;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Update the maximum of number of lines that contain the same character. This is a global value.
|
||||||
|
if (nMaxLinesSameChar < aCurStats->second.first)
|
||||||
|
nMaxLinesSameChar = aCurStats->second.first;
|
||||||
}
|
}
|
||||||
|
|
||||||
aLinesCharsCount.emplace_back();
|
aLinesCharsCount.emplace_back();
|
||||||
aLinesCharsCount[aLinesCharsCount.size() - 1].swap(aCharsCount);
|
aLinesCharsCount[aLinesCharsCount.size() - 1].swap(aCharsCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SAL_INFO("sfx.doc", "" << nLinesCount << " lines processed in " << tools::Time::GetSystemTicks() - nStartTime << " ms while detecting separator.");
|
||||||
|
|
||||||
// Compute the global minimum of different number of occurrences.
|
// Compute the global minimum of different number of occurrences.
|
||||||
// But only for characters which occur in a maximum number of lines (previously computed).
|
// But only for characters which occur in a maximum number of lines (previously computed).
|
||||||
for (auto it=aStats.cbegin(); it != aStats.cend(); it++)
|
for (auto it=aStats.cbegin(); it != aStats.cend(); it++)
|
||||||
@@ -1086,8 +1088,6 @@ void SfxObjectShell::DetectCsvSeparators(SvStream& stream, rtl_TextEncoding& eCh
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (nInitSepIdx >= 0)
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
stream.Seek(nInitPos);
|
stream.Seek(nInitPos);
|
||||||
@@ -1133,9 +1133,9 @@ void SfxObjectShell::DetectCsvFilterOptions(SvStream& stream, OUString& aFilterO
|
|||||||
|
|
||||||
|
|
||||||
//Detect separators
|
//Detect separators
|
||||||
aFilterOptions = "";
|
|
||||||
if (aSeps == aDetect)
|
if (aSeps == aDetect)
|
||||||
{
|
{
|
||||||
|
aFilterOptions = "";
|
||||||
OUString separators;
|
OUString separators;
|
||||||
DetectCsvSeparators(stream, eCharSet, separators, static_cast<sal_Unicode>(o3tl::toInt32(aDelimiter)));
|
DetectCsvSeparators(stream, eCharSet, separators, static_cast<sal_Unicode>(o3tl::toInt32(aDelimiter)));
|
||||||
|
|
||||||
@@ -1198,7 +1198,6 @@ ErrCode SfxObjectShell::HandleFilter( SfxMedium* pMedium, SfxObjectShell const *
|
|||||||
// FilterOptions should not be detected here (the detection is done before entering
|
// FilterOptions should not be detected here (the detection is done before entering
|
||||||
// interactive state). For now this is focused on CSV files.
|
// interactive state). For now this is focused on CSV files.
|
||||||
DetectFilterOptions(pMedium);
|
DetectFilterOptions(pMedium);
|
||||||
//::sleep(30);
|
|
||||||
|
|
||||||
if ( !pData && (bTiledRendering || !pOptions) )
|
if ( !pData && (bTiledRendering || !pOptions) )
|
||||||
{
|
{
|
||||||
|
Reference in New Issue
Block a user