# -*- coding: ISO-8859-1 -*-
""" capella script (c) Paul Villiger
>>> Fix SVG file

    Dieses Skript entfernt aus einer SVG Datei den Hintergrundrahmen
    Ursache: Beim Export von SVG Dateien generiert capella einen Rahmen in Seitengrösse,
    welcher für gewisse Anwendungen unerwünscht ist.

    Nach dem starten des Skripts werden die notwendigen Parameter abgefragt:
    inkscape Verzeichnis, Einzeldatei oder SVG Verzeichnis
    Diese Parameter werden gespeichert.
    
<<<

History: 22.11.2017 - Erstausgabe
         07.12.2017 - viewbox Ramen mit inkscape ermitteln
         08.12.2017 - Behandlung von Einzeldateien
         09.12.2017 - unter Win7 inkscape.com verwenden

Für Bemerkungen oder Änderungswünsche bitte Mail an villpaul(at)bluewin.ch

"""

from xml.dom.minidom import parseString
import subprocess

def fixSvgFile(fname, inkscape):
    svgFile = file(fname,'r')
    svgString = svgFile.read()
    svgFile.close()

    doc = parseString(svgString)

    for s in doc.getElementsByTagName('svg'):
        svg = s
        break

    viewBox = svg.getAttribute('viewBox')
    vbl = viewBox.split(' ')
    vbMinX = eval(vbl[0])
    vbMinY = eval(vbl[1])
    vbWidth = eval(vbl[2])
    vbHeight = eval(vbl[3])

    # remove rect with same size as viewbox
    for rect in doc.getElementsByTagName('rect'):
        if not rect.hasAttribute('width'):
            continue
        if not rect.hasAttribute('height'):
            continue
        width = eval(rect.getAttribute('width'))
        height = eval(rect.getAttribute('height'))
        
        if ( abs( vbWidth - width) < 10.0 ) and ( abs( vbHeight-height) < 10.0 ):
            g1 = rect.parentNode
            g2 = g1.parentNode
            g2.removeChild(g1)
            # print width, height


    svgFile = file(fname,'w')
    svgFile.write(doc.toxml('UTF-8'))
    svgFile.flush()
    svgFile.close()

    x = subprocess.check_output('"%s" -S "%s"' % (inkscape, fname) )

    svgEntries = x.split('\r\n')

    (s, x,y,width,height) = svgEntries[0].split(',')

    # 
    x1 = float(x) * 2540.0 / 96.0
    y1 = float(y) * 2540.0 / 96.0
    width1 = float(width) * 2540.0 / 96.0
    height1 = float(height) * 2540.0 / 96.0
    
    svg.setAttribute('viewBox','%f %f %f %f' % (x1 + vbMinX, y1 + vbMinY, width1, height1) )
    
    # set width and height in mm
    svg.setAttribute('width', '%fmm' % (width1 / 100))
    svg.setAttribute('height', '%fmm' % (height1/100))

    svgFile = file(fname,'w')
    svgFile.write(doc.toxml('UTF-8'))
    svgFile.flush()
    svgFile.close()

def selectSvgPath(path):
    dlg = FileDialog()
    dlg.__init__(bOpen=False)
    dlg.setTitle('*** Bitte SVG Verzeichnis auswählen ***')
    dlg.setStartPath(path)
    dlg.setStartFile('$$BitteNichtAendern$$')

    if dlg.run():
        svgPath, name = os.path.split( dlg.filePath() )
        svgPath = os.path.abspath(svgPath)
        drive, tail = os.path.splitdrive(svgPath)
        svgPath = os.path.join(drive.upper(), tail)
        return svgPath
    else:
        return ''

def selectInkscape(inkscape):
    dir,tail = os.path.split(inkscape)
    dlg = FileDialog()
    dlg.__init__(bOpen=True)
    dlg.setTitle('*** Bitte inkscape.exe auswählen ***')
    dlg.setStartPath(dir)
    dlg.setStartFile(tail)

    if dlg.run():
        inks = dlg.filePath()
        if not os.path.isfile(inks):
            inks = ''
    else:
        inks = ''
    return inks

def selectSingleFile(name):
    dir,tail = os.path.split(name)
    dlg = FileDialog()
    dlg.__init__(bOpen=True)
    dlg.setTitle('*** Bitte SVG Datei auswählen ***')
    dlg.setStartPath(dir)
    dlg.setStartFile(tail)

    if dlg.run():
        singleFile = dlg.filePath()
        if not os.path.isfile(singleFile):
            singleFile = ''
    else:
        singleFile = ''
    return singleFile
    
    
ok = True    
options = ScriptOptions() 
opt = options.get()

inkscape = opt.get('editInkscape','')
if not os.path.isfile(inkscape):
    inkscape = selectInkscape(inkscape)
    if inkscape:
        opt['editInkscape'] = inkscape
        options.set(opt)
    else:
        ok = False

if ok:
    svgPath = opt.get('editSvgPath','')
    if not os.path.isdir(svgPath):
        svgPath = selectSvgPath(svgPath)
        if svgPath and os.path.isdir(svgPath):
            opt['editSvgPath'] = svgPath
            options.set(opt)
        else:
            ok = False

if ok:
    singleFile = opt.get('singleFile','')

    batchConversion = eval(opt.get('batchConversion', 'False'))
    checkBatchConversion = CheckBox('Ganzes SVG Verzeichnis konvertieren?', value = batchConversion)
    

    checkSingleFile = CheckBox('Einzeldatei auswählen', value = False, padding = 8)
    
    checkSvgPath = CheckBox('SVG Verzeichnis ändern', value = False, padding = 8)
    
    checkInkscape = CheckBox('Inkscape EXE ändern', value = False, padding = 8)

    dlg = Dialog('Fix Svg File',
                 VBox([checkBatchConversion,
                       Label('SVG Einzeldazei:'),
                       HBox([Label(' ', width = 3), Label(singleFile) ]),
                       HBox([Label(' ', width = 3 ), checkSingleFile ] ),
                       Label('SVG Verzeichnis:'),
                       HBox([Label(' ', width = 3), Label(svgPath) ]),
                       HBox([Label(' ', width = 3 ), checkSvgPath ] ),
                       Label('Inkscape EXE Datei:'),
                       HBox([Label(' ', width = 3 ), Label(inkscape, width = 50) ] ),
                       HBox([Label(' ', width = 3 ), checkInkscape ] ),
                       Label('Wenn Fehler mit "inkscape.exe", dann "inkscape.com" verwenden (Win7)')
                       
                     ], padding = 6 )
                 )

    if dlg.run():
        checkSvgPath = checkSvgPath.value()
        checkInkscape = checkInkscape.value()
        checkSingleFile = checkSingleFile.value()
        batchConversion = checkBatchConversion.value()
        opt['batchConversion'] = batchConversion == 1
        options.set(opt)

    else:
        ok = False
        
if ok and checkInkscape:                          
    inkscape = selectInkscape(inkscape)
    if inkscape:
        opt['editInkscape'] = inkscape
        options.set(opt)
    else:
        ok = False

if ok and not batchConversion:
    if checkSingleFile or not os.path.isfile(singleFile):
        singleFile = selectSingleFile(singleFile)
        if singleFile and os.path.isfile(singleFile):
            opt['singleFile'] = singleFile
            options.set(opt)
        else:
            ok = False
    if ok:
        fixSvgFile(singleFile, inkscape)
        # terminate procedure
        ok = False


if ok and checkSvgPath:
    svgPath = selectSvgPath(svgPath)
    if svgPath and os.path.isdir(svgPath):
        opt['editSvgPath'] = svgPath
        options.set(opt)
    else:
        ok = False


if ok:
    dirlist = os.listdir(svgPath)
    dirlist.sort()

    for svgFile in dirlist:
        head, tail = os.path.splitext(svgFile)
        if tail.lower() not in  ['.svg']:
            continue
    
        fileName = os.path.join(svgPath,svgFile)
        if not os.path.isfile(fileName):
            continue

        fixSvgFile(fileName, inkscape)

