tdf#114200 : added 'Trim space' feature in 'Text Import'
made a checkbox to Trim extra white spaces from both ends while using seperators in 'Text Imort' Change-Id: Ib05d9b17525e3ebec380ec8b7eebfa35fff78f01 Reviewed-on: https://gerrit.libreoffice.org/46177 Tested-by: Jenkins <ci@libreoffice.org> Reviewed-by: Manuj Vashist <manujvashist@gmail.com> Reviewed-by: Heiko Tietze <tietze.heiko@gmail.com> Tested-by: Heiko Tietze <tietze.heiko@gmail.com>
This commit is contained in:
committed by
Heiko Tietze
parent
32b2a1831d
commit
d999b55e28
@@ -1088,6 +1088,13 @@
|
|||||||
</info>
|
</info>
|
||||||
<value>false</value>
|
<value>false</value>
|
||||||
</prop>
|
</prop>
|
||||||
|
<prop oor:name="RemoveSpace" oor:type="xs:boolean" oor:nillable="false">
|
||||||
|
<info>
|
||||||
|
<desc>If true, leading and trailing white spaces are trimmed off.</desc>
|
||||||
|
<label>RemoveSpace</label>
|
||||||
|
</info>
|
||||||
|
<value>false</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>
|
||||||
@@ -1163,6 +1170,13 @@
|
|||||||
</info>
|
</info>
|
||||||
<value>false</value>
|
<value>false</value>
|
||||||
</prop>
|
</prop>
|
||||||
|
<prop oor:name="RemoveSpace" oor:type="xs:boolean" oor:nillable="false">
|
||||||
|
<info>
|
||||||
|
<desc>If true, leading and trailing white spaces are trimmed off.</desc>
|
||||||
|
<label>RemoveSpace</label>
|
||||||
|
</info>
|
||||||
|
<value>false</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>
|
||||||
@@ -1245,6 +1259,13 @@
|
|||||||
</info>
|
</info>
|
||||||
<value>false</value>
|
<value>false</value>
|
||||||
</prop>
|
</prop>
|
||||||
|
<prop oor:name="RemoveSpace" oor:type="xs:boolean" oor:nillable="false">
|
||||||
|
<info>
|
||||||
|
<desc>If true, leading and trailing white spaces are trimmed off.</desc>
|
||||||
|
<label>RemoveSpace</label>
|
||||||
|
</info>
|
||||||
|
<value>false</value>
|
||||||
|
</prop>
|
||||||
<prop oor:name="Separators" oor:type="xs:string" oor:nillable="false">
|
<prop oor:name="Separators" oor:type="xs:string" oor:nillable="false">
|
||||||
<info>
|
<info>
|
||||||
<desc>List of Separators - as a String</desc>
|
<desc>List of Separators - as a String</desc>
|
||||||
|
@@ -29,9 +29,12 @@ ScAsciiOptions::ScAsciiOptions() :
|
|||||||
bFixedLen ( false ),
|
bFixedLen ( false ),
|
||||||
aFieldSeps ( OUString(';') ),
|
aFieldSeps ( OUString(';') ),
|
||||||
bMergeFieldSeps ( false ),
|
bMergeFieldSeps ( false ),
|
||||||
|
bRemoveSpace ( false ),
|
||||||
bQuotedFieldAsText(false),
|
bQuotedFieldAsText(false),
|
||||||
bDetectSpecialNumber(false),
|
bDetectSpecialNumber(false),
|
||||||
bSkipEmptyCells(false),
|
bSkipEmptyCells(false),
|
||||||
|
bSaveAsShown(true),
|
||||||
|
bSaveFormulas(false),
|
||||||
cTextSep ( cDefaultTextSep ),
|
cTextSep ( cDefaultTextSep ),
|
||||||
eCharSet ( osl_getThreadTextEncoding() ),
|
eCharSet ( osl_getThreadTextEncoding() ),
|
||||||
eLang ( LANGUAGE_SYSTEM ),
|
eLang ( LANGUAGE_SYSTEM ),
|
||||||
@@ -74,7 +77,12 @@ ScAsciiOptions& ScAsciiOptions::operator=( const ScAsciiOptions& rCpy )
|
|||||||
bFixedLen = rCpy.bFixedLen;
|
bFixedLen = rCpy.bFixedLen;
|
||||||
aFieldSeps = rCpy.aFieldSeps;
|
aFieldSeps = rCpy.aFieldSeps;
|
||||||
bMergeFieldSeps = rCpy.bMergeFieldSeps;
|
bMergeFieldSeps = rCpy.bMergeFieldSeps;
|
||||||
|
bRemoveSpace = rCpy.bRemoveSpace;
|
||||||
bQuotedFieldAsText = rCpy.bQuotedFieldAsText;
|
bQuotedFieldAsText = rCpy.bQuotedFieldAsText;
|
||||||
|
bDetectSpecialNumber = rCpy.bDetectSpecialNumber;
|
||||||
|
bSkipEmptyCells = rCpy.bSkipEmptyCells;
|
||||||
|
bSaveAsShown = rCpy.bSaveAsShown;
|
||||||
|
bSaveFormulas = rCpy.bSaveFormulas;
|
||||||
cTextSep = rCpy.cTextSep;
|
cTextSep = rCpy.cTextSep;
|
||||||
eCharSet = rCpy.eCharSet;
|
eCharSet = rCpy.eCharSet;
|
||||||
bCharSetSystem = rCpy.bCharSetSystem;
|
bCharSetSystem = rCpy.bCharSetSystem;
|
||||||
@@ -180,15 +188,34 @@ void ScAsciiOptions::ReadFromString( const OUString& rString )
|
|||||||
else
|
else
|
||||||
bDetectSpecialNumber = true; // default of versions that didn't add the parameter
|
bDetectSpecialNumber = true; // default of versions that didn't add the parameter
|
||||||
|
|
||||||
// 9th token is used for "Save as shown" in export options
|
// Token 8: used for "Save as shown" in export options
|
||||||
// 10th token is used for "Save cell formulas" in export options
|
if ( nPos >= 0 )
|
||||||
|
{
|
||||||
|
bSaveAsShown = rString.getToken(0, ',', nPos) == "true";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
bSaveAsShown = true; //default value
|
||||||
|
// Token 9: used for "Save cell formulas" in export options
|
||||||
|
if ( nPos >= 0 )
|
||||||
|
{
|
||||||
|
bSaveFormulas = rString.getToken(0, ',', nPos) == "true";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
bSaveFormulas = false;
|
||||||
|
// Token 10: Boolean for Trim spaces.
|
||||||
|
if (nPos >= 0)
|
||||||
|
{
|
||||||
|
bRemoveSpace = rString.getToken(0, ',', nPos) == "true";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
bRemoveSpace = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
OUString ScAsciiOptions::WriteToString() const
|
OUString ScAsciiOptions::WriteToString() const
|
||||||
{
|
{
|
||||||
OUString aOutStr;
|
OUString aOutStr;
|
||||||
|
|
||||||
// Field separator.
|
// Token 0: Field separator.
|
||||||
if ( bFixedLen )
|
if ( bFixedLen )
|
||||||
aOutStr += pStrFix;
|
aOutStr += pStrFix;
|
||||||
else if ( aFieldSeps.isEmpty() )
|
else if ( aFieldSeps.isEmpty() )
|
||||||
@@ -209,19 +236,19 @@ OUString ScAsciiOptions::WriteToString() const
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Text delimiter.
|
// Token 1: Text Quote character.
|
||||||
aOutStr += "," + OUString::number(cTextSep) + ",";
|
aOutStr += "," + OUString::number(cTextSep) + ",";
|
||||||
|
|
||||||
// Text encoding.
|
//Token 2: Text encoding.
|
||||||
if ( bCharSetSystem ) // force "SYSTEM"
|
if ( bCharSetSystem ) // force "SYSTEM"
|
||||||
aOutStr += ScGlobal::GetCharsetString( RTL_TEXTENCODING_DONTKNOW );
|
aOutStr += ScGlobal::GetCharsetString( RTL_TEXTENCODING_DONTKNOW );
|
||||||
else
|
else
|
||||||
aOutStr += ScGlobal::GetCharsetString( eCharSet );
|
aOutStr += ScGlobal::GetCharsetString( eCharSet );
|
||||||
|
|
||||||
// Number of start row.
|
//Token 3: Number of start row.
|
||||||
aOutStr += "," + OUString::number(nStartRow) + ",";
|
aOutStr += "," + OUString::number(nStartRow) + ",";
|
||||||
|
|
||||||
// Column info.
|
//Token 4: Column info.
|
||||||
for (size_t nInfo=0; nInfo<mvColStart.size(); nInfo++)
|
for (size_t nInfo=0; nInfo<mvColStart.size(); nInfo++)
|
||||||
{
|
{
|
||||||
if (nInfo)
|
if (nInfo)
|
||||||
@@ -235,16 +262,18 @@ OUString ScAsciiOptions::WriteToString() const
|
|||||||
// so new options must be added at the end, to remain compatible
|
// so new options must be added at the end, to remain compatible
|
||||||
|
|
||||||
aOutStr += "," +
|
aOutStr += "," +
|
||||||
// Language
|
//Token 5: Language
|
||||||
OUString::number(static_cast<sal_uInt16>(eLang)) + "," +
|
OUString::number(static_cast<sal_uInt16>(eLang)) + "," +
|
||||||
// Import quoted field as text.
|
//Token 6: Import quoted field as text.
|
||||||
OUString::boolean( bQuotedFieldAsText ) + "," +
|
OUString::boolean( bQuotedFieldAsText ) + "," +
|
||||||
// Detect special numbers.
|
//Token 7: Detect special numbers.
|
||||||
OUString::boolean( bDetectSpecialNumber );
|
OUString::boolean( bDetectSpecialNumber ) + "," +
|
||||||
|
// Token 8: used for "Save as shown" in export options
|
||||||
// 9th token is used for "Save as shown" in export options
|
OUString::boolean( bSaveAsShown ) + "," +
|
||||||
// 10th token is used for "Save cell formulas" in export options
|
// Token 9: used for "Save cell formulas" in export options
|
||||||
|
OUString::boolean( bSaveFormulas ) + "," +
|
||||||
|
//Token 10: Trim Space
|
||||||
|
OUString::boolean( bRemoveSpace );
|
||||||
return aOutStr;
|
return aOutStr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -734,7 +734,7 @@ void ScCsvGrid::DoSelectAction( sal_uInt32 nColIndex, sal_uInt16 nModifier )
|
|||||||
|
|
||||||
void ScCsvGrid::ImplSetTextLineSep(
|
void ScCsvGrid::ImplSetTextLineSep(
|
||||||
sal_Int32 nLine, const OUString& rTextLine,
|
sal_Int32 nLine, const OUString& rTextLine,
|
||||||
const OUString& rSepChars, sal_Unicode cTextSep, bool bMergeSep )
|
const OUString& rSepChars, sal_Unicode cTextSep, bool bMergeSep, bool bRemoveSpace )
|
||||||
{
|
{
|
||||||
if( nLine < GetFirstVisLine() ) return;
|
if( nLine < GetFirstVisLine() ) return;
|
||||||
|
|
||||||
@@ -756,7 +756,7 @@ void ScCsvGrid::ImplSetTextLineSep(
|
|||||||
bool bIsQuoted = false;
|
bool bIsQuoted = false;
|
||||||
bool bOverflowCell = false;
|
bool bOverflowCell = false;
|
||||||
pChar = ScImportExport::ScanNextFieldFromString( pChar, aCellText,
|
pChar = ScImportExport::ScanNextFieldFromString( pChar, aCellText,
|
||||||
cTextSep, pSepChars, bMergeSep, bIsQuoted, bOverflowCell );
|
cTextSep, pSepChars, bMergeSep, bIsQuoted, bOverflowCell, bRemoveSpace );
|
||||||
/* TODO: signal overflow somewhere in UI */
|
/* TODO: signal overflow somewhere in UI */
|
||||||
|
|
||||||
// update column width
|
// update column width
|
||||||
|
@@ -200,7 +200,7 @@ void ScCsvTableBox::MakePosVisible( sal_Int32 nPos )
|
|||||||
|
|
||||||
void ScCsvTableBox::SetUniStrings(
|
void ScCsvTableBox::SetUniStrings(
|
||||||
const OUString* pTextLines, const OUString& rSepChars,
|
const OUString* pTextLines, const OUString& rSepChars,
|
||||||
sal_Unicode cTextSep, bool bMergeSep )
|
sal_Unicode cTextSep, bool bMergeSep, bool bRemoveSpace )
|
||||||
{
|
{
|
||||||
// assuming that pTextLines is a string array with size CSV_PREVIEW_LINES
|
// assuming that pTextLines is a string array with size CSV_PREVIEW_LINES
|
||||||
// -> will be dynamic sometime
|
// -> will be dynamic sometime
|
||||||
@@ -212,7 +212,7 @@ void ScCsvTableBox::SetUniStrings(
|
|||||||
if( mbFixedMode )
|
if( mbFixedMode )
|
||||||
maGrid->ImplSetTextLineFix( nLine, *pString );
|
maGrid->ImplSetTextLineFix( nLine, *pString );
|
||||||
else
|
else
|
||||||
maGrid->ImplSetTextLineSep( nLine, *pString, rSepChars, cTextSep, bMergeSep );
|
maGrid->ImplSetTextLineSep( nLine, *pString, rSepChars, cTextSep, bMergeSep, bRemoveSpace );
|
||||||
}
|
}
|
||||||
EnableRepaint();
|
EnableRepaint();
|
||||||
}
|
}
|
||||||
|
@@ -42,6 +42,7 @@ ScImportOptions::ScImportOptions( const OUString& rStr )
|
|||||||
bSaveAsShown = true; // "true" if not in string (after CSV import)
|
bSaveAsShown = true; // "true" if not in string (after CSV import)
|
||||||
bQuoteAllText = false;
|
bQuoteAllText = false;
|
||||||
bSaveFormulas = false;
|
bSaveFormulas = false;
|
||||||
|
bRemoveSpace = false;
|
||||||
sal_Int32 nTokenCount = comphelper::string::getTokenCount(rStr, ',');
|
sal_Int32 nTokenCount = comphelper::string::getTokenCount(rStr, ',');
|
||||||
if ( nTokenCount >= 3 )
|
if ( nTokenCount >= 3 )
|
||||||
{
|
{
|
||||||
@@ -70,6 +71,8 @@ ScImportOptions::ScImportOptions( const OUString& rStr )
|
|||||||
bSaveAsShown = rStr.getToken(8, ',') == "true";
|
bSaveAsShown = rStr.getToken(8, ',') == "true";
|
||||||
if ( nTokenCount >= 10 )
|
if ( nTokenCount >= 10 )
|
||||||
bSaveFormulas = rStr.getToken(9, ',') == "true";
|
bSaveFormulas = rStr.getToken(9, ',') == "true";
|
||||||
|
if ( nTokenCount >= 11 )
|
||||||
|
bRemoveSpace = rStr.getToken(10, ',') == "true";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -89,7 +92,9 @@ OUString ScImportOptions::BuildString() const
|
|||||||
",true," + // "detect special numbers"
|
",true," + // "detect special numbers"
|
||||||
OUString::boolean( bSaveAsShown ) + // "save as shown": not in ScAsciiOptions
|
OUString::boolean( bSaveAsShown ) + // "save as shown": not in ScAsciiOptions
|
||||||
"," +
|
"," +
|
||||||
OUString::boolean( bSaveFormulas ); // "save formulas": not in ScAsciiOptions
|
OUString::boolean( bSaveFormulas ) + // "save formulas": not in ScAsciiOptions
|
||||||
|
"," +
|
||||||
|
OUString::boolean( bRemoveSpace ); // same as "Remove space" in ScAsciiOptions
|
||||||
|
|
||||||
return aResult;
|
return aResult;
|
||||||
}
|
}
|
||||||
|
@@ -58,6 +58,7 @@ enum CSVImportOptionsIndex
|
|||||||
CSVIO_Separators,
|
CSVIO_Separators,
|
||||||
CSVIO_TextSeparators,
|
CSVIO_TextSeparators,
|
||||||
CSVIO_FixedWidth,
|
CSVIO_FixedWidth,
|
||||||
|
CSVIO_RemoveSpace,
|
||||||
CSVIO_FromRow,
|
CSVIO_FromRow,
|
||||||
CSVIO_Text2ColSkipEmptyCells = CSVIO_FromRow,
|
CSVIO_Text2ColSkipEmptyCells = CSVIO_FromRow,
|
||||||
CSVIO_CharSet,
|
CSVIO_CharSet,
|
||||||
@@ -73,6 +74,7 @@ const ::std::vector<OUString> CSVImportOptionNames =
|
|||||||
"Separators",
|
"Separators",
|
||||||
"TextSeparators",
|
"TextSeparators",
|
||||||
"FixedWidth",
|
"FixedWidth",
|
||||||
|
"RemoveSpace",
|
||||||
"FromRow",
|
"FromRow",
|
||||||
"CharSet",
|
"CharSet",
|
||||||
"QuotedFieldAsText",
|
"QuotedFieldAsText",
|
||||||
@@ -144,16 +146,16 @@ void lcl_CreatePropertiesNames ( OUString& rSepPath, Sequence<OUString>& rNames,
|
|||||||
{
|
{
|
||||||
case SC_IMPORTFILE:
|
case SC_IMPORTFILE:
|
||||||
rSepPath = aSep_Path;
|
rSepPath = aSep_Path;
|
||||||
nProperties = 9;
|
nProperties = 10;
|
||||||
break;
|
break;
|
||||||
case SC_PASTETEXT:
|
case SC_PASTETEXT:
|
||||||
rSepPath = aSep_Path_Clpbrd;
|
rSepPath = aSep_Path_Clpbrd;
|
||||||
nProperties = 10;
|
nProperties = 11;
|
||||||
break;
|
break;
|
||||||
case SC_TEXTTOCOLUMNS:
|
case SC_TEXTTOCOLUMNS:
|
||||||
default:
|
default:
|
||||||
rSepPath = aSep_Path_Text2Col;
|
rSepPath = aSep_Path_Text2Col;
|
||||||
nProperties = 5;
|
nProperties = 6;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
rNames.realloc( nProperties );
|
rNames.realloc( nProperties );
|
||||||
@@ -162,6 +164,7 @@ void lcl_CreatePropertiesNames ( OUString& rSepPath, Sequence<OUString>& rNames,
|
|||||||
pNames[ CSVIO_Separators ] = CSVImportOptionNames[ CSVIO_Separators ];
|
pNames[ CSVIO_Separators ] = CSVImportOptionNames[ CSVIO_Separators ];
|
||||||
pNames[ CSVIO_TextSeparators ] = CSVImportOptionNames[ CSVIO_TextSeparators ];
|
pNames[ CSVIO_TextSeparators ] = CSVImportOptionNames[ CSVIO_TextSeparators ];
|
||||||
pNames[ CSVIO_FixedWidth ] = CSVImportOptionNames[ CSVIO_FixedWidth ];
|
pNames[ CSVIO_FixedWidth ] = CSVImportOptionNames[ CSVIO_FixedWidth ];
|
||||||
|
pNames[ CSVIO_RemoveSpace ] = CSVImportOptionNames[ CSVIO_RemoveSpace ];
|
||||||
if (eCall != SC_TEXTTOCOLUMNS)
|
if (eCall != SC_TEXTTOCOLUMNS)
|
||||||
{
|
{
|
||||||
pNames[ CSVIO_FromRow ] = CSVImportOptionNames[ CSVIO_FromRow ];
|
pNames[ CSVIO_FromRow ] = CSVImportOptionNames[ CSVIO_FromRow ];
|
||||||
@@ -181,7 +184,7 @@ void lcl_CreatePropertiesNames ( OUString& rSepPath, Sequence<OUString>& rNames,
|
|||||||
static void lcl_LoadSeparators( OUString& rFieldSeparators, OUString& rTextSeparators,
|
static void lcl_LoadSeparators( OUString& rFieldSeparators, OUString& rTextSeparators,
|
||||||
bool& rMergeDelimiters, bool& rQuotedAsText, bool& rDetectSpecialNum,
|
bool& rMergeDelimiters, bool& rQuotedAsText, bool& rDetectSpecialNum,
|
||||||
bool& rFixedWidth, sal_Int32& rFromRow, sal_Int32& rCharSet,
|
bool& rFixedWidth, sal_Int32& rFromRow, sal_Int32& rCharSet,
|
||||||
sal_Int32& rLanguage, bool& rSkipEmptyCells, ScImportAsciiCall eCall )
|
sal_Int32& rLanguage, bool& rSkipEmptyCells, bool& rRemoveSpace, ScImportAsciiCall eCall )
|
||||||
{
|
{
|
||||||
Sequence<Any>aValues;
|
Sequence<Any>aValues;
|
||||||
const Any *pProperties;
|
const Any *pProperties;
|
||||||
@@ -195,6 +198,9 @@ static void lcl_LoadSeparators( OUString& rFieldSeparators, OUString& rTextSepar
|
|||||||
if( pProperties[ CSVIO_MergeDelimiters ].hasValue() )
|
if( pProperties[ CSVIO_MergeDelimiters ].hasValue() )
|
||||||
rMergeDelimiters = ScUnoHelpFunctions::GetBoolFromAny( pProperties[ CSVIO_MergeDelimiters ] );
|
rMergeDelimiters = ScUnoHelpFunctions::GetBoolFromAny( pProperties[ CSVIO_MergeDelimiters ] );
|
||||||
|
|
||||||
|
if( pProperties[ CSVIO_RemoveSpace ].hasValue() )
|
||||||
|
rRemoveSpace = ScUnoHelpFunctions::GetBoolFromAny( pProperties[ CSVIO_RemoveSpace ] );
|
||||||
|
|
||||||
if( pProperties[ CSVIO_Separators ].hasValue() )
|
if( pProperties[ CSVIO_Separators ].hasValue() )
|
||||||
pProperties[ CSVIO_Separators ] >>= rFieldSeparators;
|
pProperties[ CSVIO_Separators ] >>= rFieldSeparators;
|
||||||
|
|
||||||
@@ -233,7 +239,7 @@ static void lcl_LoadSeparators( OUString& rFieldSeparators, OUString& rTextSepar
|
|||||||
static void lcl_SaveSeparators(
|
static void lcl_SaveSeparators(
|
||||||
const OUString& rSeparators, const OUString& rTxtSep, bool bMergeDelimiters, bool bQuotedAsText,
|
const OUString& rSeparators, const OUString& rTxtSep, bool bMergeDelimiters, bool bQuotedAsText,
|
||||||
bool bDetectSpecialNum, bool bFixedWidth, sal_Int32 nFromRow,
|
bool bDetectSpecialNum, bool bFixedWidth, sal_Int32 nFromRow,
|
||||||
sal_Int32 nCharSet, sal_Int32 nLanguage, bool bSkipEmptyCells, ScImportAsciiCall eCall )
|
sal_Int32 nCharSet, sal_Int32 nLanguage, bool bSkipEmptyCells, bool bRemoveSpace, ScImportAsciiCall eCall )
|
||||||
{
|
{
|
||||||
OUString sFieldSeparators = rSeparators;
|
OUString sFieldSeparators = rSeparators;
|
||||||
OUString sTextSeparators = rTxtSep;
|
OUString sTextSeparators = rTxtSep;
|
||||||
@@ -247,6 +253,7 @@ static void lcl_SaveSeparators(
|
|||||||
pProperties = aValues.getArray();
|
pProperties = aValues.getArray();
|
||||||
|
|
||||||
pProperties[ CSVIO_MergeDelimiters ] <<= bMergeDelimiters;
|
pProperties[ CSVIO_MergeDelimiters ] <<= bMergeDelimiters;
|
||||||
|
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_FixedWidth ] <<= bFixedWidth;
|
||||||
@@ -298,6 +305,7 @@ ScImportAsciiDlg::ScImportAsciiDlg( vcl::Window* pParent, const OUString& aDatNa
|
|||||||
get(pCkbSemicolon, "semicolon");
|
get(pCkbSemicolon, "semicolon");
|
||||||
get(pCkbComma, "comma");
|
get(pCkbComma, "comma");
|
||||||
get(pCkbSpace, "space");
|
get(pCkbSpace, "space");
|
||||||
|
get(pCkbRemoveSpace, "removespace");
|
||||||
get(pCkbOther, "other");
|
get(pCkbOther, "other");
|
||||||
get(pEdOther, "inputother");
|
get(pEdOther, "inputother");
|
||||||
get(pCkbAsOnce, "mergedelimiters");
|
get(pCkbAsOnce, "mergedelimiters");
|
||||||
@@ -335,12 +343,13 @@ ScImportAsciiDlg::ScImportAsciiDlg( vcl::Window* pParent, const OUString& aDatNa
|
|||||||
bool bQuotedFieldAsText = false;
|
bool bQuotedFieldAsText = false;
|
||||||
bool bDetectSpecialNum = true;
|
bool bDetectSpecialNum = true;
|
||||||
bool bSkipEmptyCells = true;
|
bool bSkipEmptyCells = true;
|
||||||
|
bool bRemoveSpace = 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;
|
||||||
lcl_LoadSeparators (sFieldSeparators, sTextSeparators, bMergeDelimiters,
|
lcl_LoadSeparators (sFieldSeparators, sTextSeparators, bMergeDelimiters,
|
||||||
bQuotedFieldAsText, bDetectSpecialNum, bFixedWidth, nFromRow,
|
bQuotedFieldAsText, bDetectSpecialNum, bFixedWidth, nFromRow,
|
||||||
nCharSet, nLanguage, bSkipEmptyCells, meCall);
|
nCharSet, nLanguage, bSkipEmptyCells, bRemoveSpace, meCall);
|
||||||
// load from saved settings
|
// load from saved settings
|
||||||
maFieldSeparators = sFieldSeparators;
|
maFieldSeparators = sFieldSeparators;
|
||||||
|
|
||||||
@@ -348,6 +357,8 @@ ScImportAsciiDlg::ScImportAsciiDlg( vcl::Window* pParent, const OUString& aDatNa
|
|||||||
pCkbAsOnce->Check();
|
pCkbAsOnce->Check();
|
||||||
if (bQuotedFieldAsText)
|
if (bQuotedFieldAsText)
|
||||||
pCkbQuotedAsText->Check();
|
pCkbQuotedAsText->Check();
|
||||||
|
if (bRemoveSpace)
|
||||||
|
pCkbRemoveSpace->Check();
|
||||||
if (bDetectSpecialNum)
|
if (bDetectSpecialNum)
|
||||||
pCkbDetectNumber->Check();
|
pCkbDetectNumber->Check();
|
||||||
if (bSkipEmptyCells)
|
if (bSkipEmptyCells)
|
||||||
@@ -427,6 +438,7 @@ ScImportAsciiDlg::ScImportAsciiDlg( vcl::Window* pParent, const OUString& aDatNa
|
|||||||
pCkbDetectNumber->SetClickHdl( aSeparatorClickHdl );
|
pCkbDetectNumber->SetClickHdl( aSeparatorClickHdl );
|
||||||
pCkbSkipEmptyCells->SetClickHdl( aSeparatorClickHdl );
|
pCkbSkipEmptyCells->SetClickHdl( aSeparatorClickHdl );
|
||||||
pCkbSpace->SetClickHdl( aSeparatorClickHdl );
|
pCkbSpace->SetClickHdl( aSeparatorClickHdl );
|
||||||
|
pCkbRemoveSpace->SetClickHdl( aSeparatorClickHdl );
|
||||||
pCkbOther->SetClickHdl( aSeparatorClickHdl );
|
pCkbOther->SetClickHdl( aSeparatorClickHdl );
|
||||||
pEdOther->SetModifyHdl( aSeparatorHdl );
|
pEdOther->SetModifyHdl( aSeparatorHdl );
|
||||||
|
|
||||||
@@ -532,6 +544,7 @@ void ScImportAsciiDlg::dispose()
|
|||||||
pCkbSemicolon.clear();
|
pCkbSemicolon.clear();
|
||||||
pCkbComma.clear();
|
pCkbComma.clear();
|
||||||
pCkbSpace.clear();
|
pCkbSpace.clear();
|
||||||
|
pCkbRemoveSpace.clear();
|
||||||
pCkbOther.clear();
|
pCkbOther.clear();
|
||||||
pEdOther.clear();
|
pEdOther.clear();
|
||||||
pCkbAsOnce.clear();
|
pCkbAsOnce.clear();
|
||||||
@@ -622,6 +635,7 @@ void ScImportAsciiDlg::GetOptions( ScAsciiOptions& rOpt )
|
|||||||
{
|
{
|
||||||
rOpt.SetFieldSeps( GetSeparators() );
|
rOpt.SetFieldSeps( GetSeparators() );
|
||||||
rOpt.SetMergeSeps( pCkbAsOnce->IsChecked() );
|
rOpt.SetMergeSeps( pCkbAsOnce->IsChecked() );
|
||||||
|
rOpt.SetRemoveSpace( pCkbRemoveSpace->IsChecked() );
|
||||||
rOpt.SetTextSep( lcl_CharFromCombo( *pCbTextSep, aTextSepList ) );
|
rOpt.SetTextSep( lcl_CharFromCombo( *pCbTextSep, aTextSepList ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -638,7 +652,7 @@ void ScImportAsciiDlg::SaveParameters()
|
|||||||
static_cast<sal_Int32>(pNfRow->GetValue()),
|
static_cast<sal_Int32>(pNfRow->GetValue()),
|
||||||
pLbCharSet->GetSelectedEntryPos(),
|
pLbCharSet->GetSelectedEntryPos(),
|
||||||
static_cast<sal_uInt16>(pLbCustomLang->GetSelectLanguage()),
|
static_cast<sal_uInt16>(pLbCustomLang->GetSelectLanguage()),
|
||||||
pCkbSkipEmptyCells->IsChecked(), meCall );
|
pCkbSkipEmptyCells->IsChecked(), pCkbRemoveSpace->IsChecked(), meCall );
|
||||||
}
|
}
|
||||||
|
|
||||||
void ScImportAsciiDlg::SetSeparators()
|
void ScImportAsciiDlg::SetSeparators()
|
||||||
@@ -693,6 +707,7 @@ void ScImportAsciiDlg::SetupSeparatorCtrls()
|
|||||||
pCkbSemicolon->Enable( bEnable );
|
pCkbSemicolon->Enable( bEnable );
|
||||||
pCkbComma->Enable( bEnable );
|
pCkbComma->Enable( bEnable );
|
||||||
pCkbSpace->Enable( bEnable );
|
pCkbSpace->Enable( bEnable );
|
||||||
|
pCkbRemoveSpace->Enable( bEnable );
|
||||||
pCkbOther->Enable( bEnable );
|
pCkbOther->Enable( bEnable );
|
||||||
pEdOther->Enable( bEnable );
|
pEdOther->Enable( bEnable );
|
||||||
pCkbAsOnce->Enable( bEnable );
|
pCkbAsOnce->Enable( bEnable );
|
||||||
@@ -811,7 +826,8 @@ IMPL_LINK_NOARG(ScImportAsciiDlg, UpdateTextHdl, ScCsvTableBox&, void)
|
|||||||
|
|
||||||
mpTableBox->Execute( CSVCMD_SETLINECOUNT, mnRowPosCount);
|
mpTableBox->Execute( CSVCMD_SETLINECOUNT, mnRowPosCount);
|
||||||
bool bMergeSep = pCkbAsOnce->IsChecked();
|
bool bMergeSep = pCkbAsOnce->IsChecked();
|
||||||
mpTableBox->SetUniStrings( maPreviewLine, maFieldSeparators, mcTextSep, bMergeSep);
|
bool bRemoveSpace = pCkbRemoveSpace->IsChecked();
|
||||||
|
mpTableBox->SetUniStrings( maPreviewLine, maFieldSeparators, mcTextSep, bMergeSep, bRemoveSpace );
|
||||||
}
|
}
|
||||||
|
|
||||||
IMPL_LINK( ScImportAsciiDlg, ColTypeHdl, ScCsvTableBox&, rTableBox, void )
|
IMPL_LINK( ScImportAsciiDlg, ColTypeHdl, ScCsvTableBox&, rTableBox, void )
|
||||||
|
@@ -1288,6 +1288,7 @@ bool ScImportExport::ExtText2Doc( SvStream& rStrm )
|
|||||||
const OUString& rSeps = pExtOptions->GetFieldSeps();
|
const OUString& rSeps = pExtOptions->GetFieldSeps();
|
||||||
const sal_Unicode* pSeps = rSeps.getStr();
|
const sal_Unicode* pSeps = rSeps.getStr();
|
||||||
bool bMerge = pExtOptions->IsMergeSeps();
|
bool bMerge = pExtOptions->IsMergeSeps();
|
||||||
|
bool bRemoveSpace = pExtOptions->IsRemoveSpace();
|
||||||
sal_uInt16 nInfoCount = pExtOptions->GetInfoCount();
|
sal_uInt16 nInfoCount = pExtOptions->GetInfoCount();
|
||||||
const sal_Int32* pColStart = pExtOptions->GetColStart();
|
const sal_Int32* pColStart = pExtOptions->GetColStart();
|
||||||
const sal_uInt8* pColFormat = pExtOptions->GetColFormat();
|
const sal_uInt8* pColFormat = pExtOptions->GetColFormat();
|
||||||
@@ -1406,7 +1407,7 @@ bool ScImportExport::ExtText2Doc( SvStream& rStrm )
|
|||||||
{
|
{
|
||||||
bool bIsQuoted = false;
|
bool bIsQuoted = false;
|
||||||
p = ScImportExport::ScanNextFieldFromString( p, aCell,
|
p = ScImportExport::ScanNextFieldFromString( p, aCell,
|
||||||
cStr, pSeps, bMerge, bIsQuoted, bOverflowCell );
|
cStr, pSeps, bMerge, bIsQuoted, bOverflowCell, bRemoveSpace );
|
||||||
|
|
||||||
sal_uInt8 nFmt = SC_COL_STANDARD;
|
sal_uInt8 nFmt = SC_COL_STANDARD;
|
||||||
for ( i=nInfoStart; i<nInfoCount; i++ )
|
for ( i=nInfoStart; i<nInfoCount; i++ )
|
||||||
@@ -1514,7 +1515,7 @@ void ScImportExport::EmbeddedNullTreatment( OUString & rStr )
|
|||||||
|
|
||||||
const sal_Unicode* ScImportExport::ScanNextFieldFromString( const sal_Unicode* p,
|
const sal_Unicode* ScImportExport::ScanNextFieldFromString( const sal_Unicode* p,
|
||||||
OUString& rField, sal_Unicode cStr, const sal_Unicode* pSeps, bool bMergeSeps, bool& rbIsQuoted,
|
OUString& rField, sal_Unicode cStr, const sal_Unicode* pSeps, bool bMergeSeps, bool& rbIsQuoted,
|
||||||
bool& rbOverflowCell )
|
bool& rbOverflowCell, bool bRemoveSpace )
|
||||||
{
|
{
|
||||||
rbIsQuoted = false;
|
rbIsQuoted = false;
|
||||||
rField.clear();
|
rField.clear();
|
||||||
@@ -1541,7 +1542,13 @@ const sal_Unicode* ScImportExport::ScanNextFieldFromString( const sal_Unicode* p
|
|||||||
// this field.
|
// this field.
|
||||||
if (p > p1)
|
if (p > p1)
|
||||||
{
|
{
|
||||||
if (!lcl_appendLineData( rField, p1, p))
|
const sal_Unicode* ptrim_f = p;
|
||||||
|
if ( bRemoveSpace )
|
||||||
|
{
|
||||||
|
while ( ptrim_f > p1 && ( *(ptrim_f - 1) == cBlank ) )
|
||||||
|
--ptrim_f;
|
||||||
|
}
|
||||||
|
if (!lcl_appendLineData( rField, p1, ptrim_f))
|
||||||
rbOverflowCell = true;
|
rbOverflowCell = true;
|
||||||
}
|
}
|
||||||
if( *p )
|
if( *p )
|
||||||
@@ -1552,7 +1559,16 @@ const sal_Unicode* ScImportExport::ScanNextFieldFromString( const sal_Unicode* p
|
|||||||
const sal_Unicode* p0 = p;
|
const sal_Unicode* p0 = p;
|
||||||
while ( *p && !ScGlobal::UnicodeStrChr( pSeps, *p ) )
|
while ( *p && !ScGlobal::UnicodeStrChr( pSeps, *p ) )
|
||||||
p++;
|
p++;
|
||||||
if (!lcl_appendLineData( rField, p0, p))
|
const sal_Unicode* ptrim_i = p0;
|
||||||
|
const sal_Unicode* ptrim_f = p; // [ptrim_i,ptrim_f) is cell data after trimming
|
||||||
|
if ( bRemoveSpace )
|
||||||
|
{
|
||||||
|
while ( *ptrim_i == cBlank )
|
||||||
|
++ptrim_i;
|
||||||
|
while ( ptrim_f > ptrim_i && ( *(ptrim_f - 1) == cBlank ) )
|
||||||
|
--ptrim_f;
|
||||||
|
}
|
||||||
|
if (!lcl_appendLineData( rField, ptrim_i, ptrim_f))
|
||||||
rbOverflowCell = true;
|
rbOverflowCell = true;
|
||||||
if( *p )
|
if( *p )
|
||||||
p++;
|
p++;
|
||||||
|
@@ -31,9 +31,12 @@ private:
|
|||||||
bool bFixedLen;
|
bool bFixedLen;
|
||||||
OUString aFieldSeps;
|
OUString aFieldSeps;
|
||||||
bool bMergeFieldSeps;
|
bool bMergeFieldSeps;
|
||||||
|
bool bRemoveSpace;
|
||||||
bool bQuotedFieldAsText;
|
bool bQuotedFieldAsText;
|
||||||
bool bDetectSpecialNumber;
|
bool bDetectSpecialNumber;
|
||||||
bool bSkipEmptyCells;
|
bool bSkipEmptyCells;
|
||||||
|
bool bSaveAsShown;
|
||||||
|
bool bSaveFormulas;
|
||||||
sal_Unicode cTextSep;
|
sal_Unicode cTextSep;
|
||||||
rtl_TextEncoding eCharSet;
|
rtl_TextEncoding eCharSet;
|
||||||
LanguageType eLang;
|
LanguageType eLang;
|
||||||
@@ -56,6 +59,7 @@ public:
|
|||||||
rtl_TextEncoding GetCharSet() const { return eCharSet; }
|
rtl_TextEncoding GetCharSet() const { return eCharSet; }
|
||||||
const OUString& GetFieldSeps() const { return aFieldSeps; }
|
const OUString& GetFieldSeps() const { return aFieldSeps; }
|
||||||
bool IsMergeSeps() const { return bMergeFieldSeps; }
|
bool IsMergeSeps() const { return bMergeFieldSeps; }
|
||||||
|
bool IsRemoveSpace() const { return bRemoveSpace; }
|
||||||
bool IsQuotedAsText() const { return bQuotedFieldAsText; }
|
bool IsQuotedAsText() const { return bQuotedFieldAsText; }
|
||||||
bool IsDetectSpecialNumber() const { return bDetectSpecialNumber; }
|
bool IsDetectSpecialNumber() const { return bDetectSpecialNumber; }
|
||||||
bool IsSkipEmptyCells() const { return bSkipEmptyCells; }
|
bool IsSkipEmptyCells() const { return bSkipEmptyCells; }
|
||||||
@@ -72,6 +76,7 @@ public:
|
|||||||
void SetFixedLen( bool bSet ) { bFixedLen = bSet; }
|
void SetFixedLen( bool bSet ) { bFixedLen = bSet; }
|
||||||
void SetFieldSeps( const OUString& rStr ) { aFieldSeps = rStr; }
|
void SetFieldSeps( const OUString& rStr ) { aFieldSeps = rStr; }
|
||||||
void SetMergeSeps( bool bSet ) { bMergeFieldSeps = bSet; }
|
void SetMergeSeps( bool bSet ) { bMergeFieldSeps = bSet; }
|
||||||
|
void SetRemoveSpace( bool bSet ) { bRemoveSpace = bSet; }
|
||||||
void SetQuotedAsText(bool bSet) { bQuotedFieldAsText = bSet; }
|
void SetQuotedAsText(bool bSet) { bQuotedFieldAsText = bSet; }
|
||||||
void SetDetectSpecialNumber(bool bSet) { bDetectSpecialNumber = bSet; }
|
void SetDetectSpecialNumber(bool bSet) { bDetectSpecialNumber = bSet; }
|
||||||
void SetSkipEmptyCells(bool bSet) { bSkipEmptyCells = bSet; }
|
void SetSkipEmptyCells(bool bSet) { bSkipEmptyCells = bSet; }
|
||||||
|
@@ -234,7 +234,7 @@ public:
|
|||||||
/** Fills all cells of a line with the passed text (separators mode). */
|
/** Fills all cells of a line with the passed text (separators mode). */
|
||||||
void ImplSetTextLineSep(
|
void ImplSetTextLineSep(
|
||||||
sal_Int32 nLine, const OUString& rTextLine,
|
sal_Int32 nLine, const OUString& rTextLine,
|
||||||
const OUString& rSepChars, sal_Unicode cTextSep, bool bMergeSep );
|
const OUString& rSepChars, sal_Unicode cTextSep, bool bMergeSep, bool bRemoveSpace = false );
|
||||||
/** Fills all cells of a line with the passed text (fixed width mode). */
|
/** Fills all cells of a line with the passed text (fixed width mode). */
|
||||||
void ImplSetTextLineFix( sal_Int32 nLine, const OUString& rTextLine );
|
void ImplSetTextLineFix( sal_Int32 nLine, const OUString& rTextLine );
|
||||||
|
|
||||||
|
@@ -101,7 +101,7 @@ public:
|
|||||||
/** Fills all cells of all lines with the passed texts (Unicode strings). */
|
/** Fills all cells of all lines with the passed texts (Unicode strings). */
|
||||||
void SetUniStrings(
|
void SetUniStrings(
|
||||||
const OUString* pTextLines, const OUString& rSepChars,
|
const OUString* pTextLines, const OUString& rSepChars,
|
||||||
sal_Unicode cTextSep, bool bMergeSep );
|
sal_Unicode cTextSep, bool bMergeSep, bool bRemoveSpace = false );
|
||||||
|
|
||||||
// column settings --------------------------------------------------------
|
// column settings --------------------------------------------------------
|
||||||
public:
|
public:
|
||||||
|
@@ -49,6 +49,7 @@ public:
|
|||||||
bSaveAsShown = rCpy.bSaveAsShown;
|
bSaveAsShown = rCpy.bSaveAsShown;
|
||||||
bQuoteAllText = rCpy.bQuoteAllText;
|
bQuoteAllText = rCpy.bQuoteAllText;
|
||||||
bSaveFormulas = rCpy.bSaveFormulas;
|
bSaveFormulas = rCpy.bSaveFormulas;
|
||||||
|
bRemoveSpace = rCpy.bRemoveSpace;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -64,6 +65,7 @@ public:
|
|||||||
bool bSaveAsShown;
|
bool bSaveAsShown;
|
||||||
bool bQuoteAllText;
|
bool bQuoteAllText;
|
||||||
bool bSaveFormulas;
|
bool bSaveFormulas;
|
||||||
|
bool bRemoveSpace;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // INCLUDED_SC_SOURCE_UI_INC_IMOPTDLG_HXX
|
#endif // INCLUDED_SC_SOURCE_UI_INC_IMOPTDLG_HXX
|
||||||
|
@@ -105,7 +105,7 @@ public:
|
|||||||
static bool IsFormatSupported( SotClipboardFormatId nFormat );
|
static bool IsFormatSupported( SotClipboardFormatId nFormat );
|
||||||
static const sal_Unicode* ScanNextFieldFromString( const sal_Unicode* p,
|
static const sal_Unicode* ScanNextFieldFromString( const sal_Unicode* p,
|
||||||
OUString& rField, sal_Unicode cStr, const sal_Unicode* pSeps,
|
OUString& rField, sal_Unicode cStr, const sal_Unicode* pSeps,
|
||||||
bool bMergeSeps, bool& rbIsQuoted, bool& rbOverflowCell );
|
bool bMergeSeps, bool& rbIsQuoted, bool& rbOverflowCell, bool bRemoveSpace = false );
|
||||||
static void WriteUnicodeOrByteString( SvStream& rStrm, const OUString& rString, bool bZero = false );
|
static void WriteUnicodeOrByteString( SvStream& rStrm, const OUString& rString, bool bZero = false );
|
||||||
static void WriteUnicodeOrByteEndl( SvStream& rStrm );
|
static void WriteUnicodeOrByteEndl( SvStream& rStrm );
|
||||||
|
|
||||||
|
@@ -63,6 +63,7 @@ class ScImportAsciiDlg : public ModalDialog
|
|||||||
VclPtr<CheckBox> pCkbTab;
|
VclPtr<CheckBox> pCkbTab;
|
||||||
VclPtr<CheckBox> pCkbSemicolon;
|
VclPtr<CheckBox> pCkbSemicolon;
|
||||||
VclPtr<CheckBox> pCkbComma;
|
VclPtr<CheckBox> pCkbComma;
|
||||||
|
VclPtr<CheckBox> pCkbRemoveSpace;
|
||||||
VclPtr<CheckBox> pCkbSpace;
|
VclPtr<CheckBox> pCkbSpace;
|
||||||
VclPtr<CheckBox> pCkbOther;
|
VclPtr<CheckBox> pCkbOther;
|
||||||
VclPtr<Edit> pEdOther;
|
VclPtr<Edit> pEdOther;
|
||||||
|
@@ -315,6 +315,24 @@
|
|||||||
<property name="width">4</property>
|
<property name="width">4</property>
|
||||||
</packing>
|
</packing>
|
||||||
</child>
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkCheckButton" id="removespace">
|
||||||
|
<property name="label" translatable="yes" context="textimportcsv|removespace">Tr_im spaces</property>
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">True</property>
|
||||||
|
<property name="receives_default">False</property>
|
||||||
|
<property name="halign">start</property>
|
||||||
|
<property name="hexpand">True</property>
|
||||||
|
<property name="use_underline">True</property>
|
||||||
|
<property name="xalign">0</property>
|
||||||
|
<property name="draw_indicator">True</property>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="left_attach">2</property>
|
||||||
|
<property name="top_attach">1</property>
|
||||||
|
<property name="width">4</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkCheckButton" id="comma">
|
<object class="GtkCheckButton" id="comma">
|
||||||
<property name="label" translatable="yes" context="textimportcsv|comma">_Comma</property>
|
<property name="label" translatable="yes" context="textimportcsv|comma">_Comma</property>
|
||||||
|
Reference in New Issue
Block a user