##############################################################################
# ThanCad 0.0.9 "DoesSomething": 2dimensional CAD with raster support for engineers.
#
# Copyright (c) 2001-2009 Thanasis Stamos, August 23, 2009
# URL: http://thancad.sourceforge.net
# e-mail: cyberthanasis@excite.com
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details (www.gnu.org/licenses/gpl.html).
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
##############################################################################
"""\
ThanCad 0.0.9 "DoesSomething": 2dimensional CAD with raster support for engineers.
Package which processes commands entered by the user.
This module processes file related commands.
"""
import cPickle, bz2, gzip
from tkMessageBox import ERROR
from p_ggen import path
import p_gtkuti, p_gdxf
import thanvers, thandr, thanimp, thantkgui, thantkdia, thansupport
from thantrans import T
from thanvar import Canc,thanfiles,ThanImportError
mm = p_gtkuti.thanGudModalMessage
def thanFileNew(proj):
"Creates a new drawing and its drawing window."
projnew = thanFileNewDo(proj)
proj[2].thanGudCommandEnd(T["New drawing has been created."], "info")
projnew[2].thanGudCommandEnd()
projnew[2].thanTkSetFocus()
def thanFileNewDo(proj, mes=None):
"Creates a new drawing and its drawing window - does the job."
fpath = thanfiles.thanFilTemp()
dr = thandr.ThanDrawing()
win = thantkgui.ThanTkGuiWinDraw(fpath, dr)
projnew = win.thanProj
thanfiles.thanFilUpdateOpened(projnew)
thanfiles.thanFilUpdateRecent(projnew)
thanfiles.thanFilAddOpened(projnew)
projnew[2].thanTkSetFocus()
return projnew
def thanFileOpen(proj):
"""Opens a file which contains thancad drawing.
The following are not saved, but they are automatically rebuilt when
the drawing is restored, via the __setstate__, __getstate__ functions:
self.thanLayerTree.dilay: because it contains weak references:
elem.image: (elem is a ThanImage) because it is too big
The following are not saved, but they are rebuilt via the dw.thanRegen()
where dw is the window which shows the drawing:
elem.imagez: (elem is a ThanImage) because it is Tk object
"""
fildir = thanfiles.thanFilGetFiledir()
while True:
fn = p_gtkuti.thanGudGetReadFile(proj[2], ".thc", T["Choose ThanCad file"],
initialdir=fildir)
if fn == None: proj[2].thanGudCommandCan(); return # Open cancelled
fn = path(fn)
try:
fr = bz2.BZ2File(fn, "r", 0, 1)
s = fr.read() # Uncompress (in case of error it raises IOError)
fr.close()
dr = cPickle.loads(s) # Unpickle. (in case of error it raises PickleError)
except (IOError, cPickle.PickleError, ImportError), why: # ImportError happens if BZ2file can not import its base class
why = str(why) + "\n\n" + T["(This might be an old, no longer supported, drawing file)"]
mm(proj[2], why, T["Open failed"], ERROR) # (Gu)i (d)ependent
else: break
__openHouse(proj, fn, dr, T["Existing drawing has been opened (into another window)."])
if (not proj[1].thanIsModified()) and thanfiles.thanFilIsTemp1(proj[0].basename()):
proj[2].after(250, __doFileClose, proj) # Hack for windows (it crashes python)
# Yeah, Windows "just works"
def __openHouse(proj, fn, dr, mes):
"House keeping for file open."
fn = fn.abspath()
thanfiles.thanFilSetFiledir(fn.parent)
#---create a new drawing
win = thantkgui.ThanTkGuiWinDraw(fn, dr)
projnew = win.thanProj
#---Save drawing in active drawings
thanfiles.thanFilUpdateOpened(projnew)
thanfiles.thanFilUpdateRecent(projnew)
thanfiles.thanFilAddOpened(projnew)
thanfiles.thanFilAddRecent(fn)
v = projnew[1].viewPort
v[:] = projnew[2].thanGudZoomWin(v) # In case that the file defined other viewport
projnew[1].thanResetModified() # In case the file was saved with the modified variable set to true
projnew[2].thanGudCommandBegin("regen")
proj[2].thanGudCommandEnd(mes, "info")
projnew[2].thanTkSetFocus()
return projnew
def thanFileOpenPath(proj, fn):
"""Opens a file with known path.
This is needed to implement opening of recent files (as shown in the menus)."""
fn = path(fn)
try:
fr = bz2.BZ2File(fn, "r", 0, 1)
s = fr.read() # Uncompress (in case of error it raises IOError)
fr.close()
dr = cPickle.loads(s) # Unpickle. (in case of error it raises PickleError)
except (IOError, cPickle.PickleError, ImportError), why: # ImportError happens if BZ2file can not import its base class
why = str(why) + "\n\n"+T["(This might be an old, no longer supported, drawing file)"]
mm(proj[2], why, T["Open failed"], ERROR) # (Gu)i (d)ependent
return proj[2].thanGudCommandEnd("Open failed")
__openHouse(proj, fn, dr, T["Existing drawing has been opened (into another window)."])
if (not proj[1].thanIsModified()) and thanfiles.thanFilIsTemp1(proj[0].basename()):
proj[2].after(250, __doFileClose, proj) # Hack for windows (it crashes python)
# Yeah, Windows "just works" :(
def thanFileSave(proj):
"""Saves a drawing into a file.
The following are not saved, but they are automatically rebuilt when
the drawing is restored, via the __setstate__, __getstate__ functions:
self.thanLayerTree.dilay: because it contains weak references:
elem.image: (elem is a ThanImage) because it is too big
The following are not saved, but they are rebuilt via the dw.thanRegen()
where dw is the window which shows the drawing:
elem.imagez: (elem is a ThanImage) because it is Tk object
"""
fildir = thanfiles.thanFilGetFiledir()
while True:
fn = p_gtkuti.thanGudGetSaveFile(proj[2], ".thc", T["Save drawing to a file"],
initialfile=proj[0].namebase, initialdir=fildir)
if fn == None: proj[2].thanGudCommandCan(); return # Save cancelled
fn = path(fn)
try:
fw = bz2.BZ2File(fn, "w", 0, 1)
s = cPickle.dumps(proj[1])
fw.write(s)
fw.close()
except (IOError, cPickle.PickleError, ImportError), why: # ImportError happens if BZ2file can not import its base class
mm(proj[2], why, T["Save failed"], ERROR) # (Gu)i (d)ependent
else: break
#-------Save drawing in active drawings
thanfiles.thanFilDelOpened(proj)
proj[0] = fn
proj[2].thanTitle = thanvers.thanCadName + " - " + proj[0].namebase
proj[2].title(proj[2].thanTitle)
proj[1].thanResetModified()
# thanfiles.thanFilUpdateOpened(projnew)
# thanfiles.thanFilUpdateRecent(projnew)
fn = fn.abspath()
thanfiles.thanFilSetFiledir(fn.parent)
thanfiles.thanFilAddOpened(proj)
thanfiles.thanFilAddRecent(fn)
proj[2].thanGudCommandEnd(T["Drawing has been saved."], "info")
def __doFileClose(proj):
"Closes a drawing (deletes dr, win and alters modified, recent list) but warns if it is modified."
if proj[1].thanIsModified():
a = p_gtkuti.thanGudAskOkCancel(proj[2], T["Drawing modified, OK to close?"], proj[0], default="cancel")
if not a: return Canc # Close cancelled
thanfiles.thanFilDelOpened(proj)
proj[1].thanDestroy()
proj[2].destroy()
return True
def thanFileClose(proj):
"Closes a drawing and prints cancelled id appropriate."
if __doFileClose(proj) == Canc:
proj[2].thanGudCommandCan() # Close cancelled
#===========================================================================
def thanFileImpSyn(proj): thanFileImpXXX(proj, ".syn", thanimp.ThanImportSyn)
def thanFileImpSyk(proj): thanFileImpXXX(proj, ".syk", thanimp.ThanImportSyk)
def thanFileImpBrk(proj): thanFileImpXXX(proj, ".brk", thanimp.ThanImportBrk)
def thanFileImpDxf(proj): thanFileImpXXX(proj, ".dxf", thanimp.ThanImportDxf)
def thanFileImpXXX(proj, suf, ImportClass):
"Imports a file whose suffix is suf; e.g. suf='.dxf'."
fildir = thanfiles.thanFilGetFiledir()
choose = "%s %s %s" % (T["Choose "], suf, T["file"])
success = "%s %s" % (suf, T["file has been successfully imported (into another window)."])
fail = "%s %s %s" % (T["Open"], suf, T["failed"])
while True:
fildxf = p_gtkuti.thanGudGetReadFile(proj[2], suf, choose, initialdir=fildir)
if fildxf == None: proj[2].thanGudCommandCan(); return # Import cancelled
fildxf = path(fildxf)
try: finp = fildxf.open()
except IOError, why: mm(proj[2], why, "%s: %s" % (fildxf.name, fail), ERROR) # (Gu)i (d)ependent
else: break
#-------create a new drawing
fpath = fildxf.parent / (fildxf.namebase + ".thc")
dr = thandr.ThanDrawing()
#-------import
ts = thanimp.ThanCadDrSave(dr, proj[2].thanPrt)
imp = ImportClass(finp, ts)
try:
imp.thanImport()
except ThanImportError, why:
del imp
finp.close()
dr.thanDestroy()
mm(proj[2], why, "%s: %s" % (fildxf.name, fail), ERROR) # (Gu)i (d)ependent
proj[2].thanGudCommandEnd(T["Import failed"], "can")
return
del imp
finp.close()
ts.thanAfterImport()
dr.thanLayerTree.thanDictRebuild()
#-------Save drawing in active drawings
projnew = __openHouse(proj, fpath, dr, success)
projnew[1].thanTouch() # .thc file has not been saved
if (not proj[1].thanIsModified()) and thanfiles.thanFilIsTemp1(proj[0].basename()):
proj[2].after(250, __doFileClose, proj) # Hack for windows (it crashes python)
# Yeah, Windows "just works"
def thanFileImpMhk(proj):
"Imports a .mhk section file."
fildir = thanfiles.thanFilGetFiledir()
while True:
fildxf = p_gtkuti.thanGudGetReadFile(proj[2], ".mhk", T["Choose mhk file"],
initialdir=fildir)
if fildxf == None: proj[2].thanGudCommandCan(); return # Import cancelled
fildxf = path(fildxf)
try: finp = fildxf.open()
except IOError, why: mm(proj[2], why, T["Open mhk failed"], ERROR) # (Gu)i (d)ependent
else: break
#-------create a new drawing
fpath = fildxf.parent / (fildxf.namebase + ".thc")
dr = thandr.ThanDrawing()
#-------import
from thanpackages.thanmhk import thanMainTcad
ts = thanimp.ThanCadDrSave(dr, proj[2].thanPrt)
dxf = thansupport.ThanDxfEmu()
dxf.thanDxfPlots1(ts)
thanMainTcad(fildxf.abspath(), dxf, proj[2].thanPrt)
icod = 0
del dxf, ts
finp.close()
if icod == -1:
dr.thanDestroy()
mm(proj[2], text, T["Import failed"], ERROR) # (Gu)i (d)ependent
proj[2].thanGudCommandEnd(T["Import failed"], "can")
return
# ts.thanAfterImport()
dr.thanLayerTree.thanDictRebuild()
#-------Save drawing in active drawings
projnew = __openHouse(proj, fpath, dr, T["Mhk file has been successfully imported (into another window)."])
projnew[1].thanTouch() # .thc file has not been saved
if (not proj[1].thanIsModified()) and thanfiles.thanFilIsTemp1(proj[0].basename()):
proj[2].after(250, __doFileClose, proj) # Hack for windows (it crashes python)
def thanTxtopen(proj, mes, suf=".txt"):
"Opens a text file for reading something."
fildir = thanfiles.thanFilGetFiledir()
while True:
fildxf = p_gtkuti.thanGudGetReadFile(proj[2], suf, mes,
proj[0].namebase, initialdir=fildir)
if fildxf == None: proj[2].thanGudCommandCan(); return Canc # Export cancelled
fildxf = path(fildxf)
try: fout = fildxf.open("r")
except IOError, why: mm(proj[2], why, T["Open failed"], ERROR) # (Gu)i (d)ependent
else: break
return fout
def thanCofopen(proj):
"Tries to read the coefficients from a file."
from p_gmath import Projection
while True:
fr = thanTxtopen(proj, T["Open file with 1st approximation coefficients"], suf=".cof")
if fr == Canc: return Canc # Match was cancelled
try:
for dline in fr:
dl = dline.strip()
if len(dl) > 0 and dl[0] != "#": break
dl1 = dl.split()[0]
icodp = int(dl1)
L = Projection(icodp)()
L.read(fr, skipicod=True)
except Exception, why:
raise
why = str(why)
mm(proj[2], why, T["Reading failed"], ERROR) # (Gu)i (d)ependent
fr.close()
else:
break
fr.close()
return L
def thanFileExpDxf(proj):
"Exports a dxf file."
fildir = thanfiles.thanFilGetFiledir()
while True:
fildxf = p_gtkuti.thanGudGetSaveFile(proj[2], ".dxf", T["Save dxf file"],
proj[0].namebase, initialdir=fildir)
if fildxf == None: proj[2].thanGudCommandCan(); return # Export cancelled
fildxf = path(fildxf)
try: fout = fildxf.open("w")
except IOError, why: p_gtkuti.thanGudModalMessage(proj[2], T["Open failed"]) # (Gu)i (d)ependent
else: break
#-------export
dxf = p_gdxf.ThanDxfPlot()
icod = proj[1].thanExpDxf(dxf, fout)
dxf.thanDxfPlot(0,0,999)
fout.close()
if icod == -1:
mm(proj[2], text, T["Export failed"], ERROR) # (Gu)i (d)ependent
proj[2].thanGudCommandEnd(T["Export failed"])
return
proj[2].thanGudCommandEnd(T["Dxf has been exported."], "info")
def thanFileExpSyk(proj):
"Exports a syk file."
fildir = thanfiles.thanFilGetFiledir()
while True:
fildxf = p_gtkuti.thanGudGetSaveFile(proj[2], ".syk", T["Save syk file"],
proj[0].namebase, initialdir=fildir)
if fildxf == None: proj[2].thanGudCommandCan(); return # Export cancelled
fildxf = path(fildxf)
try: fout = fildxf.open("w")
except IOError, why: mm(proj[2], why, T["Open failed"], ERROR) # (Gu)i (d)ependent
else: break
#-------export
icod = proj[1].thanExpSyk(fout)
fout.close()
if icod == -1:
mm(proj[2], text, T["Export failed"], ERROR) # (Gu)i (d)ependent
proj[2].thanGudCommandEnd(T["Export failed"])
return
proj[2].thanGudCommandEnd(T["Syk has been exported."], "info")
def thanFileExpBrk(proj):
"Exports a brk file."
fildir = thanfiles.thanFilGetFiledir()
while True:
fildxf = p_gtkuti.thanGudGetSaveFile(proj[2], ".brk", T["Save syk file"],
proj[0].namebase, initialdir=fildir)
if fildxf == None: proj[2].thanGudCommandCan(); return # Export cancelled
fildxf = path(fildxf)
try: fout = fildxf.open("w")
except IOError, why: mm(proj[2], why, T["Open failed"], ERROR) # (Gu)i (d)ependent
else: break
#-------export
icod = proj[1].thanExpBrk(fout)
fout.close()
if icod == -1:
mm(proj[2], text, T["Export failed"], ERROR) # (Gu)i (d)ependent
proj[2].thanGudCommandEnd(T["Export failed"])
return
proj[2].thanGudCommandEnd(T["Brk has been exported."], "info")
def thanTxtsave(proj, mes, suf=".txt"):
"Opens a text file for saving something."
fildir = thanfiles.thanFilGetFiledir()
while True:
fildxf = p_gtkuti.thanGudGetSaveFile(proj[2], suf, mes,
proj[0].namebase, initialdir=fildir)
if fildxf == None: proj[2].thanGudCommandCan(); return Canc # Export cancelled
fildxf = path(fildxf)
try: fout = fildxf.open("w")
except IOError, why: mm(proj[2], why, T["Open failed"], ERROR) # (Gu)i (d)ependent
else: break
return fout
def thanPlotPdf(proj):
"Plots drawing to pdf file."
fildir = thanfiles.thanFilGetFiledir()
than = None
while True:
fildxf = p_gtkuti.thanGudGetSaveFile(proj[2], ".pdf", T["Plot to pdf file"],
proj[0].namebase, initialdir=fildir)
if fildxf == None: del than; proj[2].thanGudCommandCan(); return # Export cancelled
fildxf = path(fildxf)
try:
fout = fildxf.open("w")
fout.close()
except IOError, why:
mm(proj[2], why, T["Open failed"], ERROR) # (Gu)i (d)ependent
continue
if than == None: than = proj[1].thanPlotPdf(1.0)
try:
than.dc.writePDFfile(fildxf)
except IOError, why:
mm(proj[2], why, T["Write failed"], ERROR) # (Gu)i (d)ependent
continue
break
del than
proj[2].thanGudCommandEnd(T["Pdf file has been created."], "info")
def thanFileExit(proj):
"Terminates the program."
for proj in thanfiles.thanFilGetOpened(): # Close each open window
if proj == thanfiles.ThanCad: continue
if __doFileClose(proj) == Canc: # abort if an open window is not closed
proj[2].thanTkSetFocus()
proj[2].thanGudCommandCan(T["Quit cancelled"])
return
thanfiles.ThanCad[2].destroy()
def thanPlotPil(proj):
"Exports to PIL image."
fpath = proj[0].parent / proj[0].namebase + ".bmp"
win = thantkdia.ThanTkExppil(proj[2], fpath, title="Export to Image: specifications")
if win.result == None: proj[2].thanGudCommandCan(); return # Export cancelled
fpath, mode, width, height, drwin = win.result
proj[1].thanExpPil(fpath, mode, width, height, drwin)
proj[2].thanGudCommandEnd(T["Image has been exported."], "info")
|