Top > OOoBasic > Generic > XTransferable

XTransferable Edit

コピーしたりドラッグ&ドロップしたりするときに利用されている com.sun.star.datatransfer.XTransferable インターフェース。

ドキュメントから利用できる XTransferable インターフェースや、ドキュメントのコントローラからエクスポートされている com.sun.star.datatransfer.XTransferableSupplier インターフェースはドキュメント間での選択範囲のコピーに利用できます。

クリップボード関連について知っているのであればそれと同じです。

種類とデータ Edit

XTransferable インターフェースの三つのメソッド。

  • any getTransferData( [in] DataFlavor f )
  • []DataFlavor getTransferDataFlavors()
  • boolean isDataFlavorSupported( [in] DataFlavor f )

XTransferable インターフェースは一つまたは複数のデータを提供し、その種類を com.sun.star.datatransfer.DataFlavor struct で示します。サポートしている種類を知るには getTransferDataFlavors メソッドから DataFlavor を取得します。

DataFlavor の要素は次のものです。

  • MimeType 種類
  • HumanPresentableName 可読フォーマットでの種類
  • DataType データ (Stream など?)

サポートされている種類のデータを取得するには getTransferData メソッドの引数に MimeType を指定した DataFlavor を与えて呼び出します。

取得できるデータの形式

  • text/plain: テキスト (text/plain から始まるもの)
  • それ以外: bytes

MimeType は http://www.iana.org/ に登録されているものが利用されます。

ドキュメントオブジェクトと Edit

ドキュメントオブジェクトでエクスポートされている XTransferable インターフェースで取得できるデータはいくつかあります。

形式説明
GDIMetaFile現在のシートで使用されている範囲のベクトル形式でのセルの画像。ハイコントラストのものもある
Image EMF同上 EMF 形式
Image WMF同上 WMF 形式
Bitmap同上 bitmap 形式
png同上 png 形式
Star Object Descriptor (XML)不可。表示されるがデータが取得できない
Star Embed Source (XML)不可。表示されるがデータが取得できない

Impress および Draw ではうまくいきません。

選択範囲と Edit

範囲を選択した状態でドキュメントのコントローラからエクスポートされている XTransferable インターフェースからは次のようなデータが取得できます。

Writer でテキストを選択しているとき。

形式 (Writer)説明
text/richtextrichtext 形式
text/htmlHTML 形式
text/plain;...utf-16utf-16 エンコードでのテキスト
LinkDDE リンク情報
Star Embed Source (XML)選択範囲のみのデータを含む ODT 形式でのデータ
Star Object Descriptor (XML)Embed Source の description

Calc でセル範囲を選択しているとき。

形式 (Calc)説明
image/bmpbmp 形式での範囲の画像
GDIMetaFileGDI 形式
Image WMFWMF 形式
Image EMFEMF 形式
SylkSylk 形式
DIFDIF 形式
text/richtextrichtext 形式での表
text/htmlHTML 形式の表
text/plain;...utf-16utf-16 エンコードでのテキスト。タブ、改行区切り
LinkDDE リンク情報
Star Embed Source (XML)選択範囲のみのデータを含む ODT 形式でのデータ
Star Object Descriptor (XML)Embed Source の description

図形描写オブジェクトを選択している状態のとき。

形式 (図形描写)説明
Drawing Format図形描写オブジェクト。その図形描写オブジェクトのみが含まれる contents.xml のみのデータ。
GDIMetaFileGDI フォーマット
Image EMF同上 EMF 形式
Image WMF同上 WMF 形式
Bitmap同上 bitmap 形式
png同上 png 形式

チャートを選択しているとき。

形式 (チャート)説明
Star Embed Source (XML)チャートのデータを含む ODF 形式でのデータ
Star Object Descriptor (XML)Embed Source の description
GDIMetaFileGDI 形式
Image EMFEMF 形式
Image WMFWMF 形式

他のものも下記のツールで調べられます。

クリップボードと Edit

選択範囲のものと同じなので割愛。

コピーとペースト Edit

ドキュメント間やドキュメント内でフォーマットを保ったままコピーペーストする場合に XTransferable インターフェースが利用できます。

このとき、選択されているオブジェクトがコピー、ペーストされます。

Writer -> Writer Edit

Writer から別の Writer ドキュメントへ。

  0
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 Sub Transferable_Writer2Writer_1
  oDoc = ThisComponent
  oController = oDoc.getCurrentController()
  ' コピーする範囲を選択
  oVisCursor = oController.getViewCursor()
  oVisCursor.gotoStart(False)
  oVisCursor.goRight(10,True)
  
  oTransferable = oController.getTransferable()
  
  Dim aArgs(0) As New com.sun.star.beans.PropertyValue
  aArgs(0).Name = "Hidden"
  aArgs(0).Value = False'True
  oNewDoc = StarDesktop.loadComponentFromURL( _
      "private:factory/swriter", "_blank", 0, aArgs )
  
  oNewDoc_Controller = oNewDoc.getCurrentController()
  oNewDoc_Controller.insertTransferable( oTransferable )
 End Sub

同じドキュメント内。

  0
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 Sub Transferable_Writer2Writer_2
  oDoc = ThisComponent
  oController = oDoc.getCurrentController()
  ' コピーする範囲を選択
  oVisCursor = oController.getViewCursor()
  oVisCursor.gotoStart(False)
  oVisCursor.goRight(10,True)
  oTransferable = oController.getTransferable()
  
  oVisCursor.goRight(1,False)
  oController.insertTransferable(oTransferable)
 End Sub

Calc -> Calc Edit

Calc から Calc のセル範囲コピー。

  0
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 Sub Transferable_Calc2Calc_1
  oDoc = ThisComponent
  oController = oDoc.getCurrentController()
  ' コピーする範囲を選択
  oController.select( _
      oDoc.getSheets().getByIndex(0).getCellRangeByPosition(0,0,1,2) )
  
  oTransferable = oController.getTransferable()
  
  Dim aArgs(0) As New com.sun.star.beans.PropertyValue
  aArgs(0).Name = "Hidden"
  aArgs(0).Value = False'True
  oNewDoc = StarDesktop.loadComponentFromURL( _
      "private:factory/scalc", "_blank", 0, aArgs )
  
  oNewDoc_Controller = oNewDoc.getCurrentController()
  ' 貼り付け先範囲を指定
  oNewDoc_Controller.select( _
      oNewDoc.getSheets().getByIndex(0).getCellByPosition(1,1) )
  
  oNewDoc_Controller.insertTransferable( oTransferable )
  
  oNewDoc.storeAsURL("file:///C:/usr/out.ods",Array())
  oNewDoc.close(True)
 End Sub

同じドキュメント内。

  0
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 Sub Transferable_Calc2Calc_2
  oDoc = ThisComponent
  oSheet = oDoc.getSheets().getByIndex(0)
  oController = oDoc.getCurrentController()
  ' コピーする範囲を選択
  oController.select( _
      oSheet.getCellRangeByPosition(0,0,1,2) )
  oTransferable = oController.getTransferable()
  
  oController.select( _
      oSheet.getCellByPosition(0,9) )
  oController.insertTransferable(oTransferable)
 End Sub

Writer -> Calc Edit

Writer から Calc へ。改行は次の行にテキストが入力されます。

  0
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 Sub Transferable_Writer2Calc_1
  oDoc = ThisComponent
  oController = oDoc.getCurrentController()
  ' コピーする範囲を選択
  oVisCursor = oController.getViewCursor()
  oVisCursor.gotoStart(False)
  oVisCursor.goRight(15,True)
  
  oTransferable = oController.getTransferable()
  
  Dim aArgs(0) As New com.sun.star.beans.PropertyValue
  aArgs(0).Name = "Hidden"
  aArgs(0).Value = False'True
  oNewDoc = StarDesktop.loadComponentFromURL( _
      "private:factory/scalc", "_blank", 0, aArgs )
  
  oNewDoc_Controller = oNewDoc.getCurrentController()
  oNewDoc_Controller.insertTransferable( oTransferable )
 End Sub

Calc -> Writer Edit

そのまま行うと埋め込み型の OLE オブジェクトになってしまいます。

  • 案1:
    text/richtext のデータを取得、insertFromURL メソッドで挿入する。と枠線などが消えてしまう。
  • 案2:
    text/html データを利用する。フォーマットがぐちゃぐちゃになる。
  • 案3:
    ODF フォーマットの ods ファイルを開き、odt フォーマットに書き換える。結構面倒…。

案3による方法。

  1. 選択範囲を ODS ファイル形式のデータとしてコントローラオブジェクトの XTransferable インターフェースを通じて取得
  2. データをテンポラリファイルに書き込み、zip ファイルとして開く
  3. content.xml および META-INF/manifest.xml ファイルのデータを取得。zip ファイルを閉じる
  4. 再度書き込みで zip ファイルを開く
  5. mimetype、content.xml、META-INF/manifest.xml ファイルを修正
  6. settings.xml および styles.xml を空に
  7. zip ファイルを閉じる
  8. テンポラリファイルのデータを読み込み、BytesSequence から input stream を作成
  9. ドキュメントにファイルから挿入

そもそも、Writer のドキュメントは横幅に限りがあるが Calc のシートにはほぼ制限がない。そのため、Writer の表のように表の幅が contents.xml ファイルに記載されていない。そのため、挿入すると表の幅はドキュメントの幅と同じになってしまう。ods の contents.xml にもセルの幅は記載されているのでトータル幅を計算して書き換えれば幅を指定できるはず。(しかし、大きすぎる表を読み込もうとしたりする、といったことは Writer と Calc を区別して使わない理由がわからなので放置。) また、Calc のセルの文字がハードフォーマットされていない場合にはスタイル指定がないので文字のサイズなどが Writer のフォーマットになります。

  0
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
import uno, unohelper
import zipfile
import re
import tempfile
 
from com.sun.star.datatransfer import XTransferable
from com.sun.star.datatransfer import DataFlavor
from com.sun.star.beans import PropertyValue
 
mimetype_writer = "application/vnd.oasis.opendocument.text"
 
manifest_name = "META-INF/manifest.xml"
manifest_calc = '<manifest:file-entry manifest:media-type=' + \
    '"application/vnd.oasis.opendocument.spreadsheet" manifest:full-path="/"/>'
manifest_writer = '<manifest:file-entry manifest:media-type=' + \
    '"application/vnd.oasis.opendocument.text" manifest:full-path="/"/>'
 
content_name = "content.xml"
content_writer_starttag = '<office:text>'
content_writer_endtag = '</office:text>'
content_calc_starttag = '<office:spreadsheet>'
content_calc_endtag = '</office:spreadsheet>'
 
styles_name = "styles.xml"
settings_name = "settings.xml"
 
 
class transferable(unohelper.Base,XTransferable):
    """Keep clipboard data and provide them."""
    def __init__(self,mTypes,data):
        self.flavors = mTypes
        self.data = data
    
    def getTransferData(self,flavor):
        if not flavor: return
        mtype = flavor.MimeType
        for i,f in enumerate(self.flavors):
            if mtype == f.MimeType:
                return self.data[i]
    
    def getTransferDataFlavors(self):
        return tuple(self.flavors)
    
    def isDataFlavorSupported(self,flavor):
        if not flavor: return False
        mtype = flavor.MimeType
        for f in self.flavors:
            if mtype == f.MimeType:
                return True
        return False
 
def calc2writer():
    ctx = XSCRIPTCONTEXT.getComponentContext()
    smgr = ctx.ServiceManager
    
    # XTransferable from CurrentController
    contents = XSCRIPTCONTEXT.getDocument().getCurrentController().getTransferable()
    if not contents: return
    
    fr = DataFlavor()
    fr.MimeType = u'application/x-openoffice-embed-source-xml;' + \
        'windows_formatname="Star Embed Source (XML)"'
    if not contents.isDataFlavorSupported(fr): return
    
    data = contents.getTransferData(fr)
    
    tmp = tempfile.TemporaryFile()
    tmp.write(data.value)
    
    # open zip file and read content.xml and manifest
    f = zipfile.ZipFile(tmp,'r')
    content = f.read(content_name)
    manifest = f.read(manifest_name)
    f.close()
    
    f = zipfile.ZipFile(tmp,'w')
    
    # replace mimetype file
    f.writestr("mimetype",mimetype_writer)
 
    # edit META-INF/manifest.xml file
    f.writestr(manifest_name,manifest.replace(manifest_calc,manifest_writer))
 
    # edit content.xml file
    f.writestr(content_name,
        re.sub("<table:table-row table:style-name=\".*?\">",'<table:table-row>',
        content.replace(content_calc_starttag,content_writer_starttag
        ).replace(content_calc_endtag,content_writer_endtag)
        ))
    # setting.xml and styles.xml to empty
    f.writestr(styles_name,"")
    f.writestr(settings_name,"")
    f.close()
    
    tmp.seek(0,0)
    data = tmp.read()
    d = uno.ByteSequence(data)
    tmp.close()
    
    # sequence to input
    seq_in = ctx.ServiceManager.createInstanceWithContext(
        "com.sun.star.io.SequenceInputStream", ctx )
    seq_in.initialize((d,))
    
    doc = XSCRIPTCONTEXT.getDesktop().loadComponentFromURL(
        "private:factory/swriter","_blank",0,())
    
    cursor = doc.getText().createTextCursor()
    
    arg = PropertyValue()
    arg.Name = "InputStream"
    arg.Value = seq_in
    arg2 = PropertyValue()
    arg2.Name = "FilterName"
    arg2.Value = "writer8"
    
    cursor.insertDocumentFromURL("",(arg,arg2))
    
    seq_in.closeInput()
 
 
g_exportedScripts = calc2writer,

ドキュメントの一部からドキュメントを Edit

ドキュメントの一部を選択、その選択中の部分のみを含むドキュメントを作成することができます。

クリップボードまたはドキュメントのコントローラから XTransferable インターフェースを取得、MimeType が Star Embed Source (XML) のデータを保存します。

下記のツール参照。

Writer ドキュメントをページごとのファイルに保存 Edit

Writer ファイルの各ページをページごとのファイルに保存します。表がページの最後に来ている場合には選択に失敗するのでそのページはうまく保存されません。

また、スタイル設定が含まれていないので元ファイルから読み込んでいます。さらに、オンラインレイアウト表示から印刷レイアウトに切り替えています。

  0
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 Sub Transferable_Writer2Page_1
  oDoc = ThisComponent
  oController = oDoc.getCurrentController()
  oSFA = CreateUnoService("com.sun.star.ucb.SimpleFileAccess")
  
  Dim aProps(0) As New com.sun.star.beans.PropertyValue
  aProps(0).Name = "Hidden"
  aProps(0).Value = True
 
  Dim aArgs(5) As New com.sun.star.beans.PropertyValue
  aArgs(0).Name = "LadCellStyles"
  aArgs(0).Value = True
  aArgs(1).Name = "LoadTextStyles"
  aArgs(1).Value = True
  aArgs(2).Name = "LoadFrameStyles"
  aArgs(2).Value = True
  aArgs(3).Name = "LoadPageStyles"
  aArgs(3).Value = True
  aArgs(4).Name = "LoadNumberingStyles"
  aArgs(4).Value = True
  aArgs(5).Name = "OverwriteStyles"
  aArgs(5).Value = True
  
  aType = CreateUnoStruct("com.sun.star.datatransfer.DataFlavor")
  aType.MimeType = _
    "application/x-openoffice-embed-source-xml;" & _
    "windows_formatname=""Star Embed Source (XML)"""
  
  oVisCursor = oController.getViewCursor()
  
  nPages = oController.PageCount
  
  'nPage = oVisCursor.getPage()
  
  For i = 1 To nPages step 1
    nPage = i
    
    oVisCursor.jumpToPage(nPage)
    
    Do
      nCursorPage = oVisCursor.getPage()
      If nCursorPage > nPage Then
        oVisCursor.goUp(1,True)
        oVisCursor.gotoEndOfLine(True)
        Exit Do
      End If
    
    Loop While oVisCursor.goDown(1,True)
    
    
    oTransferable = oController.getTransferable()
    
    If oTransferable.isDataFlavorSupported(aType) Then
      aData = oTransferable.getTransferData(aType)
      sFileURL = "file:///home/user/Desktop/out/n_" & nPage & ".odt"
      oOut = oSFA.openFileWrite(sFileURL)
      oOut.writeBytes(aData)
      oOut.flush()
      oOut.closeOutput()
 
      oNewDoc = StarDesktop.loadComponentFromURL( _
          sFileURL,"_blank",0,aProps)
      oNewDoc.getStyleFamilies()._
        loadStylesFromURL(oDoc.getURL(),aArgs)
      oNewDoc.getCurrentController().getViewSettings().ShowOnlineLayout = False
      oNewDoc.store()
      oNewDoc.close(True)
    End If
    
  Next
  
  oVisCursor.jumpToPage(1)
  Exit Sub
 End Sub

Calc から範囲を CSV に保存 Edit

シートのセル範囲の一部を CSV ファイルに保存します。ODS データをテンポラリファイルに保存、開いてから左上詰めでない範囲は左上にずらします。そして CSV ファイルに保存します。

  0
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
Sub Transferable_CalcSelection2CSV_1
  nStartColumn = 1
  nEndColumn = 4
  nStartRow = 1
  nEndRow = 4
 
  oDoc = ThisComponent
  oController = oDoc.getCurrentController()
  oRange = oDoc.getSheets().getByIndex(0)._
  getCellRangeByPosition(nStartColumn,nStartRow,nEndColumn,nEndRow)
  oController.select(oRange)
 
  oTransferable = oController.getTransferable()
 
  aType = CreateUnoStruct("com.sun.star.datatransfer.DataFlavor")
  aType.MimeType = _
  "application/x-openoffice-embed-source-xml;" & _
  "windows_formatname=""Star Embed Source (XML)"""
 
  If oTransferable.isDataFlavorSupported(aType) Then
    aData = oTransferable.getTransferData(aType)
    sFileURL = "file:///home/user/Desktop/out/out.csv" 
    'oSFA = CreateUnoService("com.sun.star.ucb.SimpleFileAccess")
    'oOut = CreateUnoService("com.sun.star.io.Pipe")
    'oOut = oSFA.openFileWrite(sFileURL)
    oTemp = CreateUnoService("com.sun.star.io.TempFile")
    oOut = oTemp.getOutputStream()
    oOut.writeBytes(aData)
    oOut.flush()
    'oOut.closeOutput()
 
    Dim aProps(1) As New com.sun.star.beans.PropertyValue
    aProps(0).Name = "Hidden"
    aProps(0).Value = True
    aProps(1).Name = "InputStream"
    aProps(1).Value = oOut
 
    oNewDoc = StarDesktop.loadComponentFromURL( _
    "private:stream","_blank",0,aProps)
 
    aCellAddress = CreateUnoStruct( _
        "com.sun.star.table.CellAddress")
    With aCellAddress
      .Sheet = 0
      .Column = 0
      .Row = 0
    End With
 
    aCellRangeAddress = CreateUnoStruct( _
        "com.sun.star.table.CellRangeAddress")
    With aCellRangeAddress
      .Sheet = 0
      .StartColumn = nStartColumn
      .EndColumn = nEndColumn
      .StartRow = nStartRow
      .EndRow = nEndRow
    End With
 
    oNewDoc.getSheets().getByIndex(0)._
        moveRange(aCellAddress,aCellRangeAddress)
 
    Dim aArgs(1) As New com.sun.star.beans.PropertyValue
    aArgs(0).Name = "FilterName"
    aArgs(0).Value = "Text - txt - csv (StarCalc)"
    aArgs(1).Name = "FilterOptions"
    aArgs(1).Value = "44,34,64,1,1"
 
    oNewDoc.storeAsURL(sFileURL,aArgs)
    oNewDoc.close(True)
  End If
 
  oTransferable = oController.getTransferable()
End Sub

MimeType Edit

とりわけよく見かける MimeType たち。

MimeType説明
application/x-openoffice-embed-source-xml;windows_formatname="Star Embed Source (XML)"ドキュメントの一部分で構成された ODF フォーマットデータ
application/x-openoffice-objectdescriptor-xml;windows_formatname="Star Object Descriptor (XML)"上記データの Description
text/plain;charset=utf16utf-16 でのテキスト
text/richtextリッチテキストフォーマット
text/htmlHTML
application/x-openoffice-link;windows_formatname="Link"DDE リンク
application/x-openoffice-sylk;windows_formatname="Sylk"Calc Sylk フォーマット
application/x-openoffice-dif;windows_formatname="DIF"Calc DIF フォーマット
application/x-openoffice-emf;windows_formatname="Image EMF"EMF フォーマット
application/x-openoffice-wmf;windows_formatname="Image WMF"WMF
application/x-openoffice-bitmap;windows_formatname="Bitmap"Bitmap
application/x-openoffice-drawing;windows_formatname="Drawing Format"
application/x-openoffice-gdimetafile;windows_formatname="GDIMetaFile"GDI フォーマット
application/x-openoffice-svxb;windows_formatname="SVXB (StarView Bitmap/Animation)"
application/x-openoffice-editengine;windows_formatname="EditEngineFormat"
application/vnd.sun.xml.dialogダイアログ xml ファイルデータ
application/vnd.sun.xml.dialogwithresourcexml データ + リソースデータ
image/pngPNG

ツール Edit

XTransferable インターフェースから getTransferData メソッドで取得できるデータを名前を付けて保存するスクリプト。12 - 20 行目付近のコメントアウトを変更してドキュメントやドキュメントコントローラ、クリップボードを切り替えます。

  0
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
import uno
import unohelper
from com.sun.star.ui.dialogs.ExecutableDialogResults import OK as EDR_OK
from com.sun.star.ui.dialogs.TemplateDescription import \
    FILESAVE_SIMPLE as TD_FILESAVE_SIMPLE
from com.sun.star.awt.PosSize import POSSIZE as PS_POSSIZE, SIZE as PS_SIZE
 
def saveclip():
    ctx = XSCRIPTCONTEXT.getComponentContext()
    smgr = ctx.ServiceManager
    
    # from Document Object
    #contents = XSCRIPTCONTEXT.getDocument()
    
    # XTransferable from CurrentController
    #contents = XSCRIPTCONTEXT.getDocument().getCurrentController().getTransferable()
    
    # from SystemClipboard service
    sc = smgr.createInstanceWithContext(
        "com.sun.star.datatransfer.clipboard.SystemClipboard",ctx)
    contents = sc.getContents()
    
    if not contents:
        message(ctx,"Empty.")
        return
    
    fs = contents.getTransferDataFlavors()
    type_list = [f.MimeType for f in fs]
    selected = select_type(ctx,tuple(type_list))
    if selected < 0: return
    
    f = fs[selected]
    try:
        if contents.isDataFlavorSupported(f):
            
            file_url = get_fileurl(ctx,smgr)
            if not file_url: return
            
            data = contents.getTransferData(f)
            
            if isinstance(data,basestring):
                p = unohelper.fileUrlToSystemPath(file_url)
                f = open(p,'wb')
                f.write(data)
                f.flush()
                f.close()
            else:
                sfa = smgr.createInstanceWithContext(
                    "com.sun.star.ucb.SimpleFileAccess", ctx)
                out = sfa.openFileWrite(file_url)
                out.writeBytes(data)
                out.flush()
                out.closeOutput()
        else:
            message(ctx,"This kind of the content is not supported.")
    except Exception,e:
        print e
 
def select_type(ctx,types):
    smgr = ctx.ServiceManager
    dlg_model = smgr.createInstanceWithContext(
        "com.sun.star.awt.UnoControlDialogModel",ctx)
    dlg = smgr.createInstanceWithContext(
        "com.sun.star.awt.UnoControlDialog",ctx)
    dlg.setModel(dlg_model)
    dlg.setPosSize(0,0,500,200,PS_SIZE)
    list_mt = createControl(smgr,ctx,"ListBox",0,0,500,150,
        (),())
    btn_ok = createControl(smgr,ctx,"Button",420,160,80,30,
        ("Label","PushButtonType"),("~OK",1))
    btn_cancel = createControl(smgr,ctx,"Button",330,160,80,30,
        ("Label","PushButtonType"),("~Cancel",2))
    
    dlg.addControl("list_mt",list_mt)
    dlg.addControl("btn_ok",btn_ok)
    dlg.addControl("btn_cancel",btn_cancel)
    
    list_mt.addItems(types,0)
    
    dlg.setVisible(True)
    item = -1
    if dlg.execute() == EDR_OK:
        item = list_mt.getSelectedItemPos()
    
    dlg.dispose()
    return item
 
def createControl(smgr,ctx,ctype,x,y,width,height,names,values):
    ctrl = smgr.createInstanceWithContext( 
        "com.sun.star.awt.UnoControl%s" % ctype,ctx)
    ctrl_model = smgr.createInstanceWithContext( 
        "com.sun.star.awt.UnoControl%sModel" % ctype,ctx)
    ctrl_model.setPropertyValues(names,values)
    ctrl.setModel(ctrl_model)
    ctrl.setPosSize(x,y,width,height,PS_POSSIZE)
    return ctrl
 
def get_fileurl(ctx,smgr):
    fp = smgr.createInstanceWithContext( 
        "com.sun.star.ui.dialogs.FilePicker",ctx)
    fp.initialize((TD_FILESAVE_SIMPLE,))
    fp.setMultiSelectionMode(False)
    fp.appendFilter("All Files (*.*)","*.*")
    fp.setCurrentFilter("All Files (*.*)")
    
    filepath = ""
    if fp.execute() == EDR_OK:
        filepaths = fp.getFiles()
        filepath = filepaths[0]
        return filepath
    else:
        return False
 
# needs OOo 2.2 or later
def message(ctx,msg="",title=""):
    desktop = ctx.ServiceManager.createInstanceWithContext(
        "com.sun.star.frame.Desktop",ctx)
    frame = desktop.getCurrentFrame()
    win = frame.getContainerWindow()
    toolkit = win.getToolkit()
    rect = uno.createUnoStruct("com.sun.star.awt.Rectangle")
    msgbox = toolkit.createMessageBox( 
        win,rect,"messbox",1,title,msg)
    msgbox.execute()
 
 
g_exportedScripts = saveclip,

Reload   New Lower page making Edit Freeze Diff Upload Copy Rename   Front page List of pages Search Recent changes Backup   Help   RSS of recent changes