448 lines
15 KiB
C++
448 lines
15 KiB
C++
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
|
/*
|
|
* This file is part of the LibreOffice project.
|
|
*
|
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
*
|
|
* This file incorporates work covered by the following license notice:
|
|
*
|
|
* Licensed to the Apache Software Foundation (ASF) under one or more
|
|
* contributor license agreements. See the NOTICE file distributed
|
|
* with this work for additional information regarding copyright
|
|
* ownership. The ASF licenses this file to you under the Apache
|
|
* License, Version 2.0 (the "License"); you may not use this file
|
|
* except in compliance with the License. You may obtain a copy of
|
|
* the License at http://www.apache.org/licenses/LICENSE-2.0 .
|
|
*/
|
|
|
|
#include <sal/config.h>
|
|
|
|
#include <optional>
|
|
#include <utility>
|
|
|
|
#include <hintids.hxx>
|
|
#include <rtl/textenc.h>
|
|
#include <i18nlangtag/mslangid.hxx>
|
|
#include <com/sun/star/i18n/ScriptType.hpp>
|
|
#include <unotools/lingucfg.hxx>
|
|
#include <unotools/viewoptions.hxx>
|
|
#include <sfx2/sfxsids.hrc>
|
|
#include <sfx2/printer.hxx>
|
|
#include <sfx2/docfile.hxx>
|
|
#include <svl/languageoptions.hxx>
|
|
#include <editeng/langitem.hxx>
|
|
#include <swtypes.hxx>
|
|
#include <ascfldlg.hxx>
|
|
#include <shellio.hxx>
|
|
#include <docsh.hxx>
|
|
#include <doc.hxx>
|
|
#include <IDocumentDeviceAccess.hxx>
|
|
|
|
#include <vcl/metric.hxx>
|
|
|
|
using namespace ::com::sun::star;
|
|
|
|
namespace
|
|
{
|
|
|
|
const sal_Unicode cDialogExtraDataClose = '}';
|
|
const char sDialogImpExtraData[] = "EncImpDlg:{";
|
|
const char sDialogExpExtraData[] = "EncExpDlg:{";
|
|
const sal_Int32 nDialogExtraDataLen = 11; // 12345678901
|
|
|
|
}
|
|
|
|
SwAsciiFilterDlg::SwAsciiFilterDlg( weld::Window* pParent, SwDocShell& rDocSh,
|
|
SvStream* pStream )
|
|
: SfxDialogController(pParent, u"modules/swriter/ui/asciifilterdialog.ui"_ustr, u"AsciiFilterDialog"_ustr)
|
|
, m_bSaveLineStatus(true)
|
|
, m_xCharSetLB(new SvxTextEncodingBox(m_xBuilder->weld_combo_box(u"charset"_ustr)))
|
|
, m_xFontFT(m_xBuilder->weld_label(u"fontft"_ustr))
|
|
, m_xFontLB(m_xBuilder->weld_combo_box(u"font"_ustr))
|
|
, m_xLanguageFT(m_xBuilder->weld_label(u"languageft"_ustr))
|
|
, m_xLanguageLB(new SvxLanguageBox(m_xBuilder->weld_combo_box(u"language"_ustr)))
|
|
, m_xCRLF_RB(m_xBuilder->weld_radio_button(u"crlf"_ustr))
|
|
, m_xCR_RB(m_xBuilder->weld_radio_button(u"cr"_ustr))
|
|
, m_xLF_RB(m_xBuilder->weld_radio_button(u"lf"_ustr))
|
|
, m_xIncludeBOM_CB(m_xBuilder->weld_check_button(u"includebom"_ustr))
|
|
{
|
|
m_xFontLB->make_sorted();
|
|
|
|
SwAsciiOptions aOpt;
|
|
{
|
|
SvtViewOptions aDlgOpt(EViewType::Dialog, m_xDialog->get_help_id());
|
|
if (aDlgOpt.Exists())
|
|
{
|
|
css::uno::Any aUserItem = aDlgOpt.GetUserItem(u"UserItem"_ustr);
|
|
aUserItem >>= m_sExtraData;
|
|
}
|
|
|
|
const SfxStringItem* pItem;
|
|
OUString sAsciiOptions;
|
|
if( rDocSh.GetMedium() != nullptr &&
|
|
(pItem = rDocSh.GetMedium()->GetItemSet().GetItemIfSet( SID_FILE_FILTEROPTIONS )))
|
|
{
|
|
sAsciiOptions = pItem->GetValue();
|
|
}
|
|
|
|
const OUString sFindNm = OUString::createFromAscii(
|
|
pStream ? sDialogImpExtraData
|
|
: sDialogExpExtraData);
|
|
sal_Int32 nStt = m_sExtraData.indexOf( sFindNm );
|
|
if( -1 != nStt )
|
|
{
|
|
nStt += nDialogExtraDataLen;
|
|
sal_Int32 nEnd = m_sExtraData.indexOf( cDialogExtraDataClose, nStt );
|
|
if( -1 != nEnd )
|
|
{
|
|
if(sAsciiOptions.isEmpty())
|
|
sAsciiOptions = m_sExtraData.copy(nStt, nEnd - nStt);
|
|
nStt -= nDialogExtraDataLen;
|
|
m_sExtraData = m_sExtraData.replaceAt(nStt, nEnd - nStt + 1, u"");
|
|
}
|
|
}
|
|
if(!sAsciiOptions.isEmpty())
|
|
aOpt.ReadUserData(sAsciiOptions);
|
|
}
|
|
|
|
// read the first chars and check the charset, (language - with L&H)
|
|
if( pStream )
|
|
{
|
|
char aBuffer[ 4098 ];
|
|
const sal_uInt64 nOldPos = pStream->Tell();
|
|
const size_t nBytesRead = pStream->ReadBytes(aBuffer, 4096);
|
|
pStream->Seek( nOldPos );
|
|
|
|
if( nBytesRead <= 4096 )
|
|
{
|
|
aBuffer[ nBytesRead ] = '0';
|
|
aBuffer[ nBytesRead+1 ] = '0';
|
|
}
|
|
|
|
bool bCR = false, bLF = false, bNullChar = false;
|
|
for( sal_uInt64 nCnt = 0; nCnt < nBytesRead; ++nCnt )
|
|
switch( aBuffer[ nCnt ] )
|
|
{
|
|
case 0x0: bNullChar = true; break;
|
|
case 0xA: bLF = true; break;
|
|
case 0xD: bCR = true; break;
|
|
case 0xC:
|
|
case 0x1A:
|
|
case 0x9: break;
|
|
default: break;
|
|
}
|
|
|
|
if( !bNullChar )
|
|
{
|
|
if( bCR )
|
|
{
|
|
if( bLF )
|
|
{
|
|
aOpt.SetParaFlags( LINEEND_CRLF );
|
|
}
|
|
else
|
|
{
|
|
aOpt.SetParaFlags( LINEEND_CR );
|
|
}
|
|
}
|
|
else if( bLF )
|
|
{
|
|
aOpt.SetParaFlags( LINEEND_LF );
|
|
}
|
|
}
|
|
|
|
const sal_uInt16 nAppScriptType = SvtLanguageOptions::GetI18NScriptTypeOfLanguage( GetAppLanguage() );
|
|
SwDoc* pDoc = rDocSh.GetDoc();
|
|
|
|
// initialize language
|
|
{
|
|
if( !aOpt.GetLanguage() )
|
|
{
|
|
if(pDoc)
|
|
{
|
|
const TypedWhichId<SvxLanguageItem> nWhich = GetWhichOfScript( RES_CHRATR_LANGUAGE, nAppScriptType);
|
|
const SvxLanguageItem& rLangItem = pDoc->GetDefault( nWhich );
|
|
aOpt.SetLanguage( rLangItem.GetLanguage() );
|
|
}
|
|
else
|
|
{
|
|
SvtLinguOptions aLinguOpt;
|
|
SvtLinguConfig().GetOptions( aLinguOpt );
|
|
switch(nAppScriptType)
|
|
{
|
|
case css::i18n::ScriptType::ASIAN:
|
|
aOpt.SetLanguage(MsLangId::resolveSystemLanguageByScriptType(aLinguOpt.nDefaultLanguage_CJK, css::i18n::ScriptType::ASIAN));
|
|
break;
|
|
case css::i18n::ScriptType::COMPLEX:
|
|
aOpt.SetLanguage(MsLangId::resolveSystemLanguageByScriptType(aLinguOpt.nDefaultLanguage_CTL, css::i18n::ScriptType::COMPLEX));
|
|
break;
|
|
//SvtScriptType::LATIN:
|
|
default:
|
|
aOpt.SetLanguage(MsLangId::resolveSystemLanguageByScriptType(aLinguOpt.nDefaultLanguage, css::i18n::ScriptType::LATIN));
|
|
}
|
|
}
|
|
}
|
|
|
|
m_xLanguageLB->SetLanguageList( SvxLanguageListFlags::ALL, true );
|
|
m_xLanguageLB->set_active_id(aOpt.GetLanguage());
|
|
}
|
|
|
|
{
|
|
bool bDelPrinter = false;
|
|
VclPtr<SfxPrinter> pPrt = pDoc ? pDoc->getIDocumentDeviceAccess().getPrinter(false) : nullptr;
|
|
if( !pPrt )
|
|
{
|
|
auto pSet = std::make_unique<SfxItemSetFixed
|
|
<SID_PRINTER_NOTFOUND_WARN, SID_PRINTER_NOTFOUND_WARN,
|
|
SID_PRINTER_CHANGESTODOC, SID_PRINTER_CHANGESTODOC>>( rDocSh.GetPool() );
|
|
pPrt = VclPtr<SfxPrinter>::Create( std::move(pSet) );
|
|
bDelPrinter = true;
|
|
}
|
|
|
|
// get the set of distinct available family names
|
|
std::set< OUString > aFontNames;
|
|
int nFontNames = pPrt->GetFontFaceCollectionCount();
|
|
for( int i = 0; i < nFontNames; i++ )
|
|
{
|
|
FontMetric aFontMetric( pPrt->GetFontMetricFromCollection( i ) );
|
|
aFontNames.insert( aFontMetric.GetFamilyName() );
|
|
}
|
|
|
|
// insert into listbox
|
|
for( const auto& rFontName : aFontNames )
|
|
{
|
|
m_xFontLB->append_text(rFontName);
|
|
}
|
|
|
|
if( aOpt.GetFontName().isEmpty() )
|
|
{
|
|
LanguageType eLang = aOpt.GetLanguage();
|
|
vcl::Font aTmpFont(OutputDevice::GetDefaultFont(DefaultFontType::FIXED, eLang, GetDefaultFontFlags::OnlyOne, pPrt));
|
|
aOpt.SetFontName(aTmpFont.GetFamilyName());
|
|
}
|
|
|
|
m_xFontLB->set_active_text(aOpt.GetFontName());
|
|
|
|
if( bDelPrinter )
|
|
pPrt.disposeAndClear();
|
|
}
|
|
|
|
// hide the unused Controls for Export
|
|
m_xIncludeBOM_CB->hide();
|
|
}
|
|
else
|
|
{
|
|
// hide the unused Controls for Export
|
|
m_xFontFT->hide();
|
|
m_xFontLB->hide();
|
|
m_xLanguageFT->hide();
|
|
m_xLanguageLB->hide();
|
|
|
|
|
|
SetIncludeBOM(aOpt.GetIncludeBOM());
|
|
m_xIncludeBOM_CB->save_state();
|
|
}
|
|
|
|
// initialize character set
|
|
m_xCharSetLB->FillFromTextEncodingTable( pStream != nullptr );
|
|
m_xCharSetLB->SelectTextEncoding( aOpt.GetCharSet() );
|
|
|
|
m_xCharSetLB->connect_changed( LINK( this, SwAsciiFilterDlg, CharSetSelHdl ));
|
|
m_xCRLF_RB->connect_toggled( LINK( this, SwAsciiFilterDlg, LineEndHdl ));
|
|
m_xLF_RB->connect_toggled( LINK( this, SwAsciiFilterDlg, LineEndHdl ));
|
|
m_xCR_RB->connect_toggled( LINK( this, SwAsciiFilterDlg, LineEndHdl ));
|
|
|
|
SetCRLF( aOpt.GetParaFlags() );
|
|
|
|
m_xCRLF_RB->save_state();
|
|
m_xLF_RB->save_state();
|
|
m_xCR_RB->save_state();
|
|
|
|
UpdateIncludeBOMSensitiveState();
|
|
}
|
|
|
|
SwAsciiFilterDlg::~SwAsciiFilterDlg()
|
|
{
|
|
SvtViewOptions aDlgOpt(EViewType::Dialog, m_xDialog->get_help_id());
|
|
aDlgOpt.SetUserItem(u"UserItem"_ustr, uno::Any(m_sExtraData));
|
|
}
|
|
|
|
void SwAsciiFilterDlg::FillOptions( SwAsciiOptions& rOptions )
|
|
{
|
|
sal_uLong nCCode = m_xCharSetLB->GetSelectTextEncoding();
|
|
OUString sFont;
|
|
LanguageType nLng = LANGUAGE_SYSTEM;
|
|
if (m_xFontLB->get_visible())
|
|
{
|
|
sFont = m_xFontLB->get_active_text();
|
|
nLng = m_xLanguageLB->get_active_id();
|
|
}
|
|
|
|
rOptions.SetFontName( sFont );
|
|
rOptions.SetCharSet( rtl_TextEncoding( nCCode ) );
|
|
rOptions.SetLanguage( nLng );
|
|
rOptions.SetParaFlags( GetCRLF() );
|
|
rOptions.SetIncludeBOM( GetIncludeBOM() );
|
|
|
|
// save the user settings
|
|
OUString sData;
|
|
rOptions.WriteUserData( sData );
|
|
if (sData.isEmpty())
|
|
return;
|
|
|
|
const OUString sFindNm = OUString::createFromAscii(
|
|
m_xFontLB->get_visible() ? sDialogImpExtraData
|
|
: sDialogExpExtraData);
|
|
sal_Int32 nStt = m_sExtraData.indexOf( sFindNm );
|
|
if( -1 != nStt )
|
|
{
|
|
// called twice, so remove "old" settings
|
|
sal_Int32 nEnd = m_sExtraData.indexOf( cDialogExtraDataClose,
|
|
nStt + nDialogExtraDataLen );
|
|
if( -1 != nEnd )
|
|
m_sExtraData = m_sExtraData.replaceAt( nStt, nEnd - nStt + 1, u"" );
|
|
}
|
|
m_sExtraData += sFindNm + sData + OUStringChar(cDialogExtraDataClose);
|
|
}
|
|
|
|
void SwAsciiFilterDlg::SetCRLF( LineEnd eEnd )
|
|
{
|
|
switch (eEnd)
|
|
{
|
|
case LINEEND_CR:
|
|
m_xCR_RB->set_active(true);
|
|
break;
|
|
case LINEEND_CRLF:
|
|
m_xCRLF_RB->set_active(true);
|
|
break;
|
|
case LINEEND_LF:
|
|
m_xLF_RB->set_active(true);
|
|
break;
|
|
}
|
|
}
|
|
|
|
LineEnd SwAsciiFilterDlg::GetCRLF() const
|
|
{
|
|
LineEnd eEnd;
|
|
if(m_xCR_RB->get_active())
|
|
eEnd = LINEEND_CR;
|
|
else if (m_xLF_RB->get_active())
|
|
eEnd = LINEEND_LF;
|
|
else
|
|
eEnd = LINEEND_CRLF;
|
|
return eEnd;
|
|
}
|
|
|
|
void SwAsciiFilterDlg::SetIncludeBOM( bool bIncludeBOM )
|
|
{
|
|
m_xIncludeBOM_CB->set_state(bIncludeBOM ? TRISTATE_TRUE : TRISTATE_FALSE);
|
|
}
|
|
|
|
bool SwAsciiFilterDlg::GetIncludeBOM() const
|
|
{
|
|
return m_xIncludeBOM_CB->get_state() != TRISTATE_FALSE;
|
|
}
|
|
|
|
void SwAsciiFilterDlg::UpdateIncludeBOMSensitiveState()
|
|
{
|
|
if (!m_xIncludeBOM_CB->get_visible())
|
|
return;
|
|
|
|
switch (m_xCharSetLB->GetSelectTextEncoding())
|
|
{
|
|
case RTL_TEXTENCODING_UTF8:
|
|
case RTL_TEXTENCODING_UCS2:
|
|
m_xIncludeBOM_CB->set_sensitive(true);
|
|
break;
|
|
default:
|
|
m_xIncludeBOM_CB->set_sensitive(false);
|
|
break;
|
|
}
|
|
}
|
|
|
|
IMPL_LINK_NOARG(SwAsciiFilterDlg, CharSetSelHdl, weld::ComboBox&, void)
|
|
{
|
|
LineEnd eOldEnd = GetCRLF();
|
|
std::optional<LineEnd> eEnd;
|
|
LanguageType nLng = m_xFontLB->get_visible()
|
|
? m_xLanguageLB->get_active_id()
|
|
: LANGUAGE_SYSTEM,
|
|
nOldLng = nLng;
|
|
|
|
rtl_TextEncoding nChrSet = m_xCharSetLB->GetSelectTextEncoding();
|
|
if( nChrSet == osl_getThreadTextEncoding() )
|
|
eEnd = GetSystemLineEnd();
|
|
else
|
|
{
|
|
switch( nChrSet )
|
|
{
|
|
case RTL_TEXTENCODING_MS_1252:
|
|
#ifdef UNX
|
|
eEnd = LINEEND_LF;
|
|
#else
|
|
eEnd = LINEEND_CRLF; // ANSI
|
|
#endif
|
|
break;
|
|
|
|
case RTL_TEXTENCODING_APPLE_ROMAN: // MAC
|
|
eEnd = LINEEND_CR;
|
|
break;
|
|
|
|
case RTL_TEXTENCODING_IBM_850: // DOS
|
|
eEnd = LINEEND_CRLF;
|
|
break;
|
|
|
|
case RTL_TEXTENCODING_APPLE_ARABIC:
|
|
case RTL_TEXTENCODING_APPLE_CENTEURO:
|
|
case RTL_TEXTENCODING_APPLE_CROATIAN:
|
|
case RTL_TEXTENCODING_APPLE_CYRILLIC:
|
|
case RTL_TEXTENCODING_APPLE_DEVANAGARI:
|
|
case RTL_TEXTENCODING_APPLE_FARSI:
|
|
case RTL_TEXTENCODING_APPLE_GREEK:
|
|
case RTL_TEXTENCODING_APPLE_GUJARATI:
|
|
case RTL_TEXTENCODING_APPLE_GURMUKHI:
|
|
case RTL_TEXTENCODING_APPLE_HEBREW:
|
|
case RTL_TEXTENCODING_APPLE_ICELAND:
|
|
case RTL_TEXTENCODING_APPLE_ROMANIAN:
|
|
case RTL_TEXTENCODING_APPLE_THAI:
|
|
case RTL_TEXTENCODING_APPLE_TURKISH:
|
|
case RTL_TEXTENCODING_APPLE_UKRAINIAN:
|
|
case RTL_TEXTENCODING_APPLE_CHINSIMP:
|
|
case RTL_TEXTENCODING_APPLE_CHINTRAD:
|
|
case RTL_TEXTENCODING_APPLE_JAPANESE:
|
|
case RTL_TEXTENCODING_APPLE_KOREAN:
|
|
eEnd = LINEEND_CR;
|
|
break;
|
|
}
|
|
}
|
|
|
|
m_bSaveLineStatus = false;
|
|
if( eEnd ) // changed?
|
|
{
|
|
if( eOldEnd != *eEnd )
|
|
SetCRLF( *eEnd );
|
|
}
|
|
else
|
|
{
|
|
// restore old user choice (not the automatic!)
|
|
m_xCRLF_RB->set_state(m_xCRLF_RB->get_saved_state());
|
|
m_xCR_RB->set_state(m_xCR_RB->get_saved_state());
|
|
m_xLF_RB->set_state(m_xLF_RB->get_saved_state());
|
|
}
|
|
m_bSaveLineStatus = true;
|
|
|
|
if (nOldLng != nLng && m_xFontLB->get_visible())
|
|
m_xLanguageLB->set_active_id(nLng);
|
|
|
|
UpdateIncludeBOMSensitiveState();
|
|
}
|
|
|
|
IMPL_LINK(SwAsciiFilterDlg, LineEndHdl, weld::Toggleable&, rBtn, void)
|
|
{
|
|
if (m_bSaveLineStatus)
|
|
rBtn.save_state();
|
|
}
|
|
|
|
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|