# GUISaveFile.py
# $Id: GUISaveFile.py,v 1.15 2001/07/05 17:16:53 s2mdalle Exp $
# Written by David Allen <mda@idatar.com>
#
# This class asks users graphically which filename they'd like to save certain
# files into. This is generally used for downloaded files that don't have
# associations bound to them, and that also can't be displayed, because
# they're binary data or otherwise ugly to look at as text. :) (e.g.
# *.zip, *.tar.gz, *.tgz, binhex, etc.
#
# Since this is a last resort, this module will try to import the Python
# Imaging Library (PIL) to display images if it is present. Note that this
# requires that there be no association for the image files, since if there
# is, it won't even get as far as creating a GUISaveFile object to display.
#
# 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.
#
# 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., 675 Mass Ave, Cambridge, MA 02139, USA.
##############################################################################
from Tkinter import *
from gopher import *
from string import *
import os
import tkFileDialog
import Pmw
import re
import Options
import ContentFrame
import GopherResource
import GopherResponse
import Dialogs
try:
import PIL
import Image
import ImageTk
except:
print "Bummer dude! You don't have the PIL installed on your machine!"
print "That means that the \"Use PIL\" option is going to be irrelevant"
print "for you."
class PILImage(Label):
# This was borrowed and adapted from the PIL programming examples.
def __init__(self, master, im):
if im.mode == "1":
# bitmap image
self.image = ImageTk.BitmapImage(im, foreground="white")
Label.__init__(self, master, image=self.image, bg="black", bd=0)
else:
# Photo image object would be better...
self.image = ImageTk.PhotoImage(im)
Label.__init__(self, master, image=self.image, bd=0)
class GUISaveFile(ContentFrame.ContentFrame, Frame):
verbose = None
def __init__(self, parent_widget, parent_object, resp,
resource, filename):
Frame.__init__(self, parent_widget) # Superclass constructor
self.r1 = None
self.r2 = None
self.filename = filename[:]
self.parent = parent_object
self.response = resp
self.resource = resource
# Don't even try to use the PIL unless the option is set
# to allow it.
usePIL = Options.program_options.getOption("use_PIL")
if usePIL and self.canDisplay():
try:
self.packImageContent()
except Exception, errstr:
self.packSaveContent()
else:
self.packSaveContent()
print "Packed save content"
return None
def packImageContent(self, *args):
self.createPopup()
self.image = Image.open(self.filename)
self.scrframe = Pmw.ScrolledFrame(self)
imgwidget = PILImage(self.scrframe.interior(), self.image)
imgwidget.pack()
imgwidget.bind('<Button-3>', self.popupMenu)
self.scrframe.pack(fill='both', expand=1)
# Return and DON'T display the save file as box only if the
# file had no problems. Otherwise an exception was raised.
return None
def revertToSaveDialog(self, *args):
self.scrframe.pack_forget() # Unpack the scrolled frame
self.scrframe = None # Lose the ref to the scrolled frame
self.image = None # Lose the ref to the image object.
self.packSaveContent() # Go back to the "Save File" content
self.pack_content()
return None
def imageInfo(self, *args):
try:
if not self.image:
return None
except:
return None
info = "Bands: %s" % join(self.image.getbands(), ", ")
size = self.image.size
info = "%s\nWidth: %d pixels\nHeight: %d pixels" % (info,
size[0], size[1])
info = "%s\nMode: %s" % (info, self.image.mode)
for key in self.image.info.keys():
info = "%s\n%s = %s" % (info, key, self.image.info[key])
d = Dialogs.ErrorDialog(self, errstr=info,
title='Image Information (PIL)')
return None
def createPopup(self):
"""Pop-up menu on right click on a message"""
self.popup = Menu(self)
self.popup['tearoff'] = FALSE
self.popup.add_command(label='Save',
command=self.revertToSaveDialog)
self.popup.add_command(label='Info',
command=self.imageInfo)
def popupMenu(self, event):
"""Display pop-up menu on right click on a message"""
self.popup.tk_popup(event.x_root, event.y_root)
def canDisplay(self):
try:
fn = Image.open
except:
return None
s = self.filename
ind = rfind(s, ".")
if ind != -1 and ind != (len(s)-1):
fileExtension = lower(s[ind:])
return 1
def find(self, term, caseSensitive=None, lastIdentifier=None):
self.parent.genericError("Error: Save Dialogs\n" +
"are not searchable.")
return None
def pack_content(self, *args):
return None
def packSaveContent(self, *args):
# Explicit copy - damn python and its ability to trip me up with all
# that "everything's a reference" stuff. :)
default_filename = self.filename[:]
for char in ['/', ':', ' ', '\\']:
strtofind = "%" + "%d;" % ord(char)
default_filename = re.sub(strtofind, char, default_filename)
for separator in ['/', ':', '\\']:
ind = rfind(default_filename, separator)
if ind != -1:
default_filename = default_filename[ind+len(separator):]
break
if self.useStatusLabels:
labeltext = "%s:%d" % (resource.getHost(), int(resource.getPort()))
if resource.getName() != '' and resource.getLocator() != '':
label2 = "\"%s\" ID %s" % (resource.getName(),
resource.getLocator())
else:
label2 = " "
if len(label2) > 50:
label2 = label2[0:47] + "..."
Label(self, text=labeltext).pack(expand=0, fill='x')
Label(self, text=label2).pack(expand=0, fill='x')
Label(self, text=" ").pack() # Empty line.
Label(self,
text="Please enter a filename to save this file as:").pack()
cframe = Frame(self)
cframe.pack(expand=1, fill='both')
Label(cframe, text="Filename:").pack(side='left')
self.filenameEntry = Entry(cframe)
self.filenameEntry.insert('end', default_filename)
self.filenameEntry.pack(side='left', expand=1, fill='x')
self.filenameEntry.bind("<Return>", self.save)
Button(cframe, text="Browse", command=self.browse).pack(side='right')
self.saveButton = Button(cframe, text="Save", command=self.save)
self.saveButton.pack(side='right')
return None
def browse(self, *args):
dir = os.path.abspath(os.getcwd())
filename = tkFileDialog.asksaveasfilename(initialdir=dir)
if filename:
self.filenameEntry.delete(0, 'end')
self.filenameEntry.insert('end', filename)
return None
def save(self, *args):
filename = self.filenameEntry.get()
try:
fp = open(filename, "w")
fp.write(self.response.getData())
fp.flush()
fp.close()
except IOError, errstr:
self.parent.genericError("Couldn't save file\n%s:\n%s" % (filename,
errstr))
return None
if self.r1:
self.r1.destroy()
if self.r2:
self.r2.destroy()
self.r1 = Label(self, text="File successfully saved into").pack()
self.r2 = Label(self, text=filename).pack()
return None
syntax highlighted by Code2HTML, v. 0.9.1