| Viewing file:  unloadform.py (18.12 KB)      -rwxr-xr-x Select action/file-type:
 
  (+) |  (+) |  (+) | Code (+) | Session (+) |  (+) | SDB (+) |  (+) |  (+) |  (+) |  (+) |  (+) | 
 
# -*- coding: utf-8 -*-#
 # (c) Copyright 2001-2006 Hewlett-Packard Development Company, L.P.
 #
 # 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
 #
 # Author: Don Welch
 #
 
 
 from base.g import *
 from base import utils, device, msg
 from prnt import cups
 from pcard import photocard
 
 import sys
 import os, os.path
 import socket
 
 from qt import *
 
 
 from unloadform_base import UnloadForm_base
 from imagepropertiesdlg import ImagePropertiesDlg
 
 progress_dlg = None
 
 class IconViewItem(QIconViewItem):
 def __init__(self, parent, dirname, fname, path, pixmap, mime_type, mime_subtype, size, exif_info={}):
 QIconViewItem.__init__(self, parent, fname, pixmap)
 self.mime_type = mime_type
 self.mime_subtype = mime_subtype
 self.path = path
 self.dirname = dirname
 self.filename = fname
 self.exif_info = exif_info
 self.size = size
 self.thumbnail_set = False
 
 
 
 class UnloadForm(UnloadForm_base):
 def __init__(self, bus='usb,par', device_uri=None, printer_name=None,
 parent=None, name=None, fl=0):
 
 UnloadForm_base.__init__(self,parent,name,fl)
 self.pc = None
 self.device_uri = device_uri
 self.printer_name = printer_name
 self.init_failed = False
 
 if self.device_uri and self.printer_name:
 log.error("You may not specify both a printer (-p) and a device (-d).")
 self.device_uri, self.printer_name = None, None
 
 if not self.device_uri and not self.printer_name:
 probed_devices = device.probeDevices(bus=bus, filter='pcard')
 cups_printers = cups.getPrinters()
 log.debug(probed_devices)
 log.debug(cups_printers)
 max_deviceid_size, x, devices = 0, 0, {}
 
 for d in probed_devices:
 if d.startswith('hp:'):
 printers = []
 for p in cups_printers:
 if p.device_uri == d:
 printers.append(p.name)
 devices[x] = (d, printers)
 x += 1
 max_deviceid_size = max(len(d), max_deviceid_size)
 
 if x == 0:
 from nodevicesform import NoDevicesForm
 self.failure(self.__tr("<p><b>No devices found that support photo card access.</b><p>Please make sure your device is properly installed and try again."))
 self.init_failed = True
 
 elif x == 1:
 log.info(utils.bold("Using device: %s" % devices[0][0]))
 self.device_uri = devices[0][0]
 
 else:
 from choosedevicedlg import ChooseDeviceDlg
 dlg = ChooseDeviceDlg(devices)
 if dlg.exec_loop() == QDialog.Accepted:
 self.device_uri = dlg.device_uri
 else:
 self.init_failed = True
 
 QTimer.singleShot(0, self.initialUpdate)
 
 
 def initialUpdate(self):
 if self.init_failed:
 self.cleanup(EVENT_PCARD_UNABLE_TO_MOUNT)
 return
 
 QApplication.setOverrideCursor(QApplication.waitCursor)
 
 try:
 self.pc = photocard.PhotoCard(None, self.device_uri, self.printer_name)
 except Error, e:
 log.error("An error occured: %s" % e[0])
 self.failure(self.__tr("<p><b>Unable to mount photocard.</b><p>Could not connect to device."))
 self.cleanup(EVENT_PCARD_UNABLE_TO_MOUNT)
 return
 
 if self.pc.device.device_uri is None and self.printer_name:
 log.error("Printer '%s' not found." % self.printer_name)
 self.failure(self.__tr("<p><b>Unable to mount photocard.</b><p>Device not found."))
 self.cleanup(EVENT_PCARD_JOB_FAIL)
 return
 
 if self.pc.device.device_uri is None and self.device_uri:
 log.error("Malformed/invalid device-uri: %s" % self.device_uri)
 self.failure(self.__tr("<p><b>Unable to mount photocard.</b><p>Malformed/invalid device-uri."))
 self.cleanup(EVENT_PCARD_JOB_FAIL)
 return
 
 try:
 self.pc.mount()
 except Error:
 log.error("Unable to mount photo card on device. Check that device is powered on and photo card is correctly inserted.")
 self.failure(self.__tr("<p><b>Unable to mount photocard.</b><p>Check that device is powered on and photo card is correctly inserted."))
 self.pc.umount()
 self.cleanup(EVENT_PCARD_UNABLE_TO_MOUNT)
 return
 
 self.pc.device.sendEvent(EVENT_START_PCARD_JOB)
 
 disk_info = self.pc.info()
 self.pc.write_protect = disk_info[8]
 
 if self.pc.write_protect:
 log.warning("Photo card is write protected.")
 
 log.info("Photocard on device %s mounted" % self.pc.device_uri)
 
 if not self.pc.write_protect:
 log.info("DO NOT REMOVE PHOTO CARD UNTIL YOU EXIT THIS PROGRAM")
 
 self.unload_dir = os.path.normpath(os.path.expanduser('~'))
 os.chdir(self.unload_dir)
 self.UnloadDirectoryEdit.setText(self.unload_dir)
 
 self.unload_list = self.pc.get_unload_list()
 self.DeviceText.setText(self.pc.device.device_uri)
 
 self.image_icon_map = {'tiff' : 'tif.png',
 'bmp'  : 'bmp.png',
 'jpeg' : 'jpg.png',
 'gif'  : 'gif.png',
 'unknown' : 'unknown.png',
 }
 self.video_icon_map = {'unknown' : 'movie.png',
 'mpeg'    : 'mpg.png',
 }
 
 self.total_number = 0
 self.total_size = 0
 
 self.removal_option = 0
 
 self.UpdateStatusBar()
 
 if self.pc.write_protect:
 self.FileRemovalGroup.setEnabled(False)
 self.LeaveAllRadio.setEnabled(False)
 self.RemoveSelectedRadio.setEnabled(False)
 self.RemoveAllRadio.setEnabled(False)
 
 # Item map disambiguates between files of the same
 # name that are on the pcard in more than one location
 self.item_map = {}
 
 QApplication.restoreOverrideCursor()
 
 self.load_icon_view(first_load=True)
 
 def closeEvent(self, event):
 if self.pc is not None:
 self.pc.device.sendEvent(EVENT_END_PCARD_JOB)
 
 event.accept()
 
 
 def CancelButton_clicked(self):
 self.cleanup()
 
 
 def cleanup(self, error=0):
 if self.pc is not None:
 if error > 0:
 self.pc.device.sendEvent(error, typ='error')
 
 self.close()
 
 
 def success(self):
 QMessageBox.information(self,
 self.caption(),
 self.__tr("<p><b>The operation completed successfully.</b>"),
 QMessageBox.Ok,
 QMessageBox.NoButton,
 QMessageBox.NoButton)
 
 def failure(self, error_text):
 QMessageBox.critical(self,
 self.caption(),
 error_text,
 QMessageBox.Ok,
 QMessageBox.NoButton,
 QMessageBox.NoButton)
 
 
 def load_icon_view(self, first_load):
 QApplication.setOverrideCursor(QApplication.waitCursor)
 self.first_load = first_load
 
 if first_load:
 self.IconView.clear()
 
 self.num_items = len(self.unload_list)
 
 self.pb = QProgressBar()
 self.pb.setTotalSteps(self.num_items)
 self.statusBar().addWidget(self.pb)
 self.pb.show()
 
 self.item_num = 0
 
 self.load_timer = QTimer(self, "ScanTimer")
 self.connect(self.load_timer, SIGNAL('timeout()'), self.continue_load_icon_view)
 self.load_timer.start(0)
 
 def continue_load_icon_view(self):
 
 if self.item_num == self.num_items:
 self.load_timer.stop()
 self.disconnect(self.load_timer, SIGNAL('timeout()'), self.continue_load_icon_view)
 self.load_timer = None
 del self.load_timer
 
 self.pb.hide()
 self.statusBar().removeWidget(self.pb)
 
 self.IconView.adjustItems()
 QApplication.restoreOverrideCursor()
 return
 
 f = self.unload_list[self.item_num]
 
 self.item_num += 1
 path, size = f[0], f[1]
 
 self.pb.setProgress(self.item_num)
 
 typ, subtyp = self.pc.classify_file(path).split('/')
 
 if not self.first_load and typ == 'image' and subtyp == 'jpeg':
 
 exif_info = self.pc.get_exif_path(path)
 
 if len(exif_info) > 0:
 
 if 'JPEGThumbnail' in exif_info:
 pixmap = QPixmap()
 pixmap.loadFromData(exif_info['JPEGThumbnail'], "JPEG")
 
 self.resizePixmap(pixmap)
 
 del exif_info['JPEGThumbnail']
 dname, fname=os.path.split(path)
 x = self.item_map[fname]
 
 if len(x) == 1:
 item = self.IconView.findItem(fname, 0)
 else:
 i = x.index(path)
 if i == 0:
 item = self.IconView.findItem(fname, 0)
 else:
 item = self.IconView.findItem(fname + " (%d)" % (i+1), 0)
 
 if item is not None:
 item.setPixmap(pixmap)
 item.thumbnail_set = True
 
 return
 
 #elif 'TIFFThumbnail' in exif_info:
 # can't handle TIFF in Qt?
 #    del exif_info['TIFFThumbnail']
 #    if first_load:
 #        IconViewItem( self.IconView, filename,
 #                      QPixmap( os.path.join( prop.image_dir, 'tif.png' ) ),
 #                      typ, subtyp, size, exif_info )
 #    else:
 #        pass
 
 #    continue
 
 
 elif self.first_load:
 if typ == 'image':
 f = os.path.join(prop.image_dir, self.image_icon_map.get(subtyp, 'unknown.png'))
 elif typ == 'video':
 f = os.path.join(prop.image_dir, self.video_icon_map.get(subtyp, 'movie.png'))
 elif typ == 'audio':
 f = os.path.join(prop.image_dir, 'sound.png')
 else:
 f = os.path.join(prop.image_dir, 'unknown.png')
 
 dirname, fname=os.path.split(path)
 num = 1
 try:
 self.item_map[fname]
 except:
 self.item_map[fname] = [path]
 else:
 self.item_map[fname].append(path)
 num = len(self.item_map[fname])
 
 if num == 1:
 IconViewItem(self.IconView, dirname, fname, path, QPixmap(f),
 typ, subtyp, size)
 else:
 IconViewItem(self.IconView, dirname, fname + " (%d)" % num,
 path, QPixmap(f), typ, subtyp, size)
 
 
 def resizePixmap(self, pixmap):
 w, h = pixmap.width(), pixmap.height()
 
 if h > 128 or w > 128:
 ww, hh = w - 128, h - 128
 if ww >= hh:
 pixmap.resize(128, int(float((w-ww))/w*h))
 else:
 pixmap.resize(int(float((h-hh))/h*w), 128)
 
 
 
 def UpdateStatusBar(self):
 if self.total_number == 0:
 self.statusBar().message(self.__tr("No files selected"))
 elif self.total_number == 1:
 self.statusBar().message(self.__tr("1 file selected, %s" % utils.format_bytes(self.total_size, True)))
 else:
 self.statusBar().message(self.__tr("%d files selected, %s" % (self.total_number, utils.format_bytes(self.total_size, True))))
 
 def SelectAllButton_clicked(self):
 self.IconView.selectAll(1)
 
 def SelectNoneButton_clicked(self):
 self.IconView.selectAll(0)
 
 def IconView_doubleClicked(self, a0):
 #self.Display( a0 )
 pass
 
 def UnloadDirectoryBrowseButton_clicked(self):
 old_dir = self.unload_dir
 self.unload_dir = str(QFileDialog.getExistingDirectory(self.unload_dir, self))
 
 if not len(self.unload_dir):
 return
 elif not utils.is_path_writable(self.unload_dir):
 self.failure(self.__tr("<p><b>The unload directory path you entered is not valid.</b><p>The directory must exist and you must have write permissions."))
 self.unload_dir = old_dir
 else:
 self.UnloadDirectoryEdit.setText(self.unload_dir)
 os.chdir(self.unload_dir)
 
 def UnloadButton_clicked(self):
 was_cancelled = False
 self.unload_dir = str(self.UnloadDirectoryEdit.text())
 dir_error = False
 
 try:
 os.chdir(self.unload_dir)
 except OSError:
 log.error("Directory not found: %s" % self.unload_dir)
 dir_error = True
 
 if dir_error or not utils.is_path_writable(self.unload_dir):
 self.failure(self.__tr("<p><b>The unload directory path is not valid.</b><p>Please enter a new path and try again."))
 return
 
 unload_list = []
 i = self.IconView.firstItem()
 total_size = 0
 while i is not None:
 
 if i.isSelected():
 unload_list.append((i.path, i.size, i.mime_type, i.mime_subtype))
 total_size += i.size
 i = i.nextItem()
 
 if total_size == 0:
 self.failure(self.__tr("<p><b>No files are selected to unload.</b><p>Please select one or more files to unload and try again."))
 return
 
 global progress_dlg
 progress_dlg = QProgressDialog(self.__tr("Unloading Files..."), self.__tr("Cancel"),
 total_size, self, 'progress', True)
 progress_dlg.setMinimumDuration(0)
 progress_dlg.show()
 
 if self.removal_option == 0:
 total_size, total_time, was_cancelled = \
 self.pc.unload(unload_list, self.UpdateUnloadProgressDlg, None, True)
 
 elif self.removal_option == 1: # remove selected
 total_size, total_time, was_cancelled = \
 self.pc.unload(unload_list, self.UpdateUnloadProgressDlg, None, False)
 
 else: # remove all
 total_size, total_time, was_cancelled = \
 self.pc.unload(unload_list, self.UpdateUnloadProgressDlg, None, False)
 # TODO: Remove remainder of files
 
 progress_dlg.close()
 
 self.pc.device.sendEvent(EVENT_PCARD_FILES_TRANSFERED)
 
 if was_cancelled:
 self.failure(self.__tr("<b>Unload cancelled at user request.</b>"))
 else:
 self.success()
 
 
 def UpdateUnloadProgressDlg(self, src, trg, size):
 global progress_dlg
 progress_dlg.setProgress(progress_dlg.progress() + size)
 progress_dlg.setLabelText(src)
 qApp.processEvents()
 
 return progress_dlg.wasCancelled()
 
 def IconView_rightButtonClicked(self, item, pos):
 popup = QPopupMenu(self)
 popup.insertItem("Properties", self.PopupProperties)
 
 if item is not None and \
 item.mime_type == 'image' and \
 item.mime_subtype == 'jpeg' and \
 not item.thumbnail_set:
 
 popup.insertItem("Show Thumbnail", self.showThumbNail)
 popup.popup(pos)
 
 
 def PopupDisplay(self):
 self.Display(self.IconView.currentItem())
 
 def PopupProperties(self):
 self.Properties(self.IconView.currentItem())
 
 def showThumbNail(self):
 item = self.IconView.currentItem()
 exif_info = self.pc.get_exif_path(item.path)
 
 if len(exif_info) > 0:
 if 'JPEGThumbnail' in exif_info:
 pixmap = QPixmap()
 pixmap.loadFromData(exif_info['JPEGThumbnail'], "JPEG")
 self.resizePixmap(pixmap)
 del exif_info['JPEGThumbnail']
 item.setPixmap(pixmap)
 
 self.IconView.adjustItems()
 
 else:
 self.failure(self.__tr("<p><b>No thumbnail found in image.</b>"))
 
 item.thumbnail_set = True
 
 def Display(self, item):
 pass
 # cp over file (does this even make sense to do this at this point?)
 # display with imagemagick?
 
 def Properties(self, item):
 if item is not None:
 if not item.exif_info:
 item.exif_info = self.pc.get_exif_path(item.path)
 
 ImagePropertiesDlg(item.filename, item.dirname,
 '/'.join([item.mime_type, item.mime_subtype]),
 utils.format_bytes(item.size, True),
 item.exif_info, self).exec_loop()
 
 
 
 def IconView_selectionChanged(self):
 self.total_number = 0
 self.total_size = 0
 i = self.IconView.firstItem()
 
 while i is not None:
 
 if i.isSelected():
 self.total_number += 1
 self.total_size += i.size
 
 i = i.nextItem()
 
 self.UpdateStatusBar()
 
 
 def IconView_clicked(self,a0,a1):
 pass
 
 def IconView_clicked(self,a0):
 pass
 
 def IconView_currentChanged(self,a0):
 pass
 
 def FileRemovalGroup_clicked(self, a0):
 self.removal_option = a0
 
 def ShowThumbnailsButton_clicked(self):
 self.ShowThumbnailsButton.setEnabled(False)
 self.load_icon_view(first_load=False)
 
 
 def __tr(self,s,c = None):
 return qApp.translate("UnloadForm",s,c)
 
 
 
 
 |