|
Server : Apache/2.2.2 (Fedora) System : Linux App1.pathumtani.go.th 2.6.20-1.2320.fc5smp #1 SMP Tue Jun 12 19:40:16 EDT 2007 i686 User : apache ( 48) PHP Version : 5.2.9 Disable Function : NONE Directory : /usr/share/printconf/util/ |
Upload File : |
#!/usr/bin/python
## system-config-printer
## Edit Queue dialog implementation
## Copyright (C) 2001-2005 Red Hat, Inc.
## Copyright (C) 2002-2005 Tim Waugh <twaugh@redhat.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.
## 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.
import gettext
import gtk
import gtk.glade
import gnome
import gobject
import os
import pyalchemist
import re
import string
domain = 'printconf'
from rhpl.translate import _, N_
gtk.glade.bindtextdomain (domain, '/usr/share/locale')
busy_cursor = gtk.gdk.Cursor(gtk.gdk.WATCH)
ready_cursor = gtk.gdk.Cursor(gtk.gdk.LEFT_PTR)
import locale
def C_float(fstr):
"""
Convert a floating point number expressed as a string that
uses '.' as the radix char into a float.
"""
return float (str (fstr).
replace (".", locale.nl_langinfo (locale.RADIXCHAR)))
def complain (window, msg):
"""Put up an error message dialog."""
d = gtk.MessageDialog (window, 0, gtk.MESSAGE_ERROR, gtk.BUTTONS_OK, msg)
d.set_transient_for (window)
d.set_position (gtk.WIN_POS_CENTER_ON_PARENT)
d.run ()
d.destroy ()
class editQueue:
"""The dialog implementation for editing an existing queue."""
def __init__ (self, parent, xml):
self.parent = parent
k = {"columns": _("Number of columns on a page"),
"cpi": _("Characters per inch"),
"fitplot": _("Scale to fit (%s or %s)") % \
("true", "false"),
"job-billing": _("Billing label"),
"job-hold-until": _("HH:MM:SS or '%s'.\n"
"Use GMT.") % "indefinite",
"job-sheets": _("Banner pages (start,end):\n"
"for example, '%s'") % "standard",
"landscape": _("Landscape (%s or %s)") % ("true",
"false"),
"lpi": _("Lines per inch"),
"number-up": _("Number of document pages per\n"
"printed page: 1, 2, 4, 6, 9, or 16"),
"page-top": _("Top margin in pt (1/72 in)"),
"page-left": _("Left margin in pt (1/72 in)"),
"page-right": _("Right margin in pt (1/72 in)"),
"page-bottom": _("Bottom margin in pt (1/72 in)"),
"page-border": _("'%s', '%s', '%s'\n"
"'%s' or '%s'") % ("none",
"single",
"single-thick",
"double",
"double-thick"),
"page-label": _("Page label"),
"prettyprint": _("Pretty-print text (%s or %s)") % \
("true", "false"),
"scaling": _("Scaling (percentage)"),
"wrap": _("Word-wrapping (%s or %s)") % ("true",
"false")}
self.known_options = k
self.sheet_types = [ "none",
"standard",
"classified",
"confidential",
"secret",
"topsecret",
"unclassified" ]
# Widgets.
self.window = xml.get_widget ('editQueueDialog')
self.notebook = xml.get_widget ('edit_queue_notebook')
self.type_menu = xml.get_widget ('edit_queue_type_menu')
self.type_notebook = xml.get_widget ('edit_queue_type_notebook')
self.name_entry = xml.get_widget ('edit_queue_name_entry')
self.desc_entry = xml.get_widget ('edit_queue_description_entry')
self.device_view = xml.get_widget ('edit_queue_device_view')
self.ipp_server_entry = xml.get_widget ('edit_queue_ipp_server_entry')
self.ipp_path_entry = xml.get_widget ('edit_queue_ipp_path_entry')
self.lpd_server_entry = xml.get_widget ('edit_queue_lpd_server_entry')
self.lpd_queue_entry = xml.get_widget ('edit_queue_lpd_queue_entry')
self.rfc1179_cb = xml.get_widget ('edit_queue_lpd_rfc1179_checkbutton')
self.smb_share_entry = xml.get_widget ('edit_queue_smb_share_entry')
self.smb_user_entry = xml.get_widget ('edit_queue_smb_user_entry')
self.smb_host_entry = xml.get_widget ('edit_queue_smb_host_entry')
self.smb_passwd_entry = xml.get_widget ('edit_queue_smb_passwd_entry')
self.smb_group_entry = xml.get_widget ('edit_queue_smb_group_entry')
self.smb_lf_cb = xml.get_widget ('edit_queue_smb_lf_checkbutton')
self.ncp_server_entry = xml.get_widget ('edit_queue_ncp_server_entry')
self.ncp_user_entry = xml.get_widget ('edit_queue_ncp_user_entry')
self.ncp_queue_entry = xml.get_widget ('edit_queue_ncp_queue_entry')
self.ncp_passwd_entry = xml.get_widget ('edit_queue_ncp_passwd_entry')
self.jd_printer_entry = xml.get_widget ('edit_queue_jd_printer_entry')
self.jd_port_entry = xml.get_widget ('edit_queue_jd_port_entry')
self.start_banner_menu = xml.get_widget ('start_banner_menu')
self.end_banner_menu = xml.get_widget ('end_banner_menu')
self.imageable_top_spinbutton = xml.get_widget \
('imageable_top_spinbutton')
self.imageable_left_spinbutton = xml.get_widget \
('imageable_left_spinbutton')
self.imageable_right_spinbutton = xml.get_widget \
('imageable_right_spinbutton')
self.imageable_bottom_spinbutton = xml.get_widget \
('imageable_bottom_spinbutton')
self.options_view = xml.get_widget ('edit_queue_options_view')
self.opt_edit_button = xml.get_widget ('queue_options_edit_button')
self.opt_remove_button = xml.get_widget ('queue_options_remove_button')
self.mfr_menu = xml.get_widget ('edit_queue_mfr_menu')
self.printer_view = xml.get_widget ('edit_queue_printer_view')
self.drivers_menu = xml.get_widget ('drivers_menu')
self.recommended_label = xml.get_widget ('recommended_label')
self.notes_button = xml.get_widget ('edit_queue_notes_button')
self.options_table = xml.get_widget ('edit_queue_driver_options_table')
self.custom_dialog = xml.get_widget ('customDeviceDialog')
self.custom_device_entry = xml.get_widget ('device_entry')
self.option_dialog = xml.get_widget ('optionDialog')
self.option_combo = xml.get_widget ('queue_option_combo')
self.option_value_label = xml.get_widget ('queue_option_value_label')
self.option_value_entry = xml.get_widget ('queue_option_value_entry')
self.margin_widgets = { "top": self.imageable_top_spinbutton,
"left": self.imageable_left_spinbutton,
"right": self.imageable_right_spinbutton,
"bottom": self.imageable_bottom_spinbutton }
# Storage for the device list.
self.device_store = gtk.TreeStore (str, str)
self.device_store.set_sort_column_id (0, gtk.SORT_ASCENDING)
self.device_view.set_model (self.device_store)
self.device_view.set_search_column (0)
# Device list columns.
col = gtk.TreeViewColumn (_("Device"), gtk.CellRendererText (),
text=0)
col.set_resizable (True)
col.set_sort_column_id (0)
self.device_view.append_column (col)
col = gtk.TreeViewColumn (_("Description"), gtk.CellRendererText (),
text=1)
col.set_resizable (True)
col.set_sort_column_id (1)
self.device_view.append_column (col)
# Storage for the queue options list.
self.options_store = gtk.TreeStore (str, str)
self.options_view.set_model (self.options_store)
# Queue options list columns.
col = gtk.TreeViewColumn (_("Option name"), gtk.CellRendererText (),
text = 0)
col.set_resizable (True)
col.set_sort_column_id (0)
self.options_view.append_column (col)
col = gtk.TreeViewColumn (_("Value"), gtk.CellRendererText (),
text = 1)
col.set_resizable (True)
self.options_view.append_column (col)
self.options_store.set_sort_column_id (0, gtk.SORT_ASCENDING)
# Storage for the printer list.
self.printer_store = gtk.TreeStore (str, gobject.TYPE_PYOBJECT)
self.printer_view.set_model (self.printer_store)
# Printer list columns.
col = gtk.TreeViewColumn (_("Model"), gtk.CellRendererText (),
text=0)
col.set_resizable (True)
col.set_sort_column_id (0)
self.printer_view.append_column (col)
# Printer select function
slct = self.printer_view.get_selection ()
slct.set_select_function (self.printer_select_function)
# Signals.
self.window.connect ('destroy', self.destroy)
xml.signal_connect ('on_edit_queue_type_menu_changed',
self.type_menu_changed)
xml.signal_connect ('on_edit_queue_rescan_devices_button_clicked',
self.rescan_devices_button_clicked)
xml.signal_connect ('on_edit_queue_custom_button_clicked',
self.custom_button_clicked)
xml.signal_connect ('on_autoselect_driver_button_clicked',
self.autoselect_driver)
xml.signal_connect ('on_queue_options_add_button_clicked',
self.add_queue_option)
xml.signal_connect ('on_queue_options_edit_button_clicked',
self.edit_queue_option)
xml.signal_connect ('on_queue_options_remove_button_clicked',
self.remove_queue_option)
xml.signal_connect ('on_queue_options_defaults_button_clicked',
self.default_queue_options)
xml.signal_connect ('on_options_view_cursor_changed',
self.option_cursor_changed)
xml.signal_connect ('on_options_view_row_activated',
self.edit_queue_option)
xml.signal_connect ('on_queue_option_combo_list_selection_changed',
self.option_combo_list_selection_changed)
xml.signal_connect ('on_edit_queue_mfr_menu_changed',
self.mfr_menu_changed)
xml.signal_connect ('on_edit_queue_printer_view_cursor_changed',
self.printer_model_selected)
xml.signal_connect ('on_drivers_menu_changed',
self.drivers_menu_changed)
xml.signal_connect ('on_edit_queue_notes_button_clicked',
self.notes_button_clicked)
xml.signal_connect ('on_edit_queue_notebook_switch_page',
self.notebook_switch_page)
# -------------------------------
# Handle the window being deleted
# -------------------------------
def destroy (self, dialog):
"""Callback for the window being deleted."""
dialog.hide ()
# ---------------------------
# Greying-out the main window
# ---------------------------
def busy (self):
"""Set the dialog window insensitive."""
self.window.set_sensitive (False)
self.window.window.set_cursor (busy_cursor)
while gtk.events_pending():
gtk.main_iteration()
def ready (self):
"""Set the dialog window sensitive."""
self.window.window.set_cursor (ready_cursor)
self.window.set_sensitive (True)
#---------------
# Run the dialog
#---------------
def editQueueDialog (self, iter):
"""
Run a dialog for editing the queue.
iter: Iter from queue tree.
"""
# Set main notebook to first page.
self.notebook.set_current_page (0)
# Fill in the name page.
self.queue_tree_iter = iter
name = self.parent.queue_store.get_value (iter, 1)
self.queue = self.parent.name_dict[name]["queue"]
self.name_entry.set_text (name)
try:
self.desc_entry.set_text (self.queue["queue_description"].value)
except:
self.desc_entry.set_text ('')
# Fill in the type page.
# Local device tab
self.rescan_devices ()
# IPP tab defaults
self.ipp_server_entry.set_text ('')
self.ipp_path_entry.set_text ('/printers/queue1')
# LPD tab defaults
self.lpd_server_entry.set_text ('')
self.lpd_queue_entry.set_text ('')
self.rfc1179_cb.set_active (False)
# SMB tab defaults
self.smb_share_entry.set_text ('')
self.smb_user_entry.set_text ('')
self.smb_host_entry.set_text ('')
self.smb_passwd_entry.set_text ('')
self.smb_group_entry.set_text ('')
self.smb_lf_cb.set_active (False)
# NCP tab defaults
self.ncp_server_entry.set_text ('')
self.ncp_user_entry.set_text ('')
self.ncp_queue_entry.set_text ('')
self.ncp_passwd_entry.set_text ('')
# JetDirect tab defaults
self.jd_printer_entry.set_text ('')
self.jd_port_entry.set_text ('9100')
# Set type values from configuration
type = self.queue["queue_type"].value
data = self.queue["queue_data"]
if type == "LOCAL":
# If it's a currently visible device we've already selected it
# (in rescan_devices). So we just need to deal with devices
# that we didn't already see.
selection = self.device_view.get_selection ()
store, iter = selection.get_selected ()
if not iter:
# This is a device we don't know about.
dev = data["local_printer_device"].value
iter = store.append (None)
store.set_value (iter, 0, dev)
store.set_value (iter, 1, _("Custom device"))
selection.select_iter (iter)
elif type == "IPP":
self.ipp_server_entry.set_text (data["ipp_server"].value)
self.ipp_path_entry.set_text (data["ipp_path"].value)
elif type == "LPD":
self.lpd_server_entry.set_text (data["lpd_server"].value)
self.lpd_queue_entry.set_text (data["lpd_queue"].value)
self.rfc1179_cb.set_active (data["lpd_strict_rfc1179"].value)
elif type == "SMB":
self.smb_share_entry.set_text (data["smb_share"].value)
self.smb_user_entry.set_text (data["smb_user"].value)
self.smb_host_entry.set_text (data["smb_ip"].value)
self.smb_passwd_entry.set_text (data["smb_password"].value)
self.smb_group_entry.set_text (data["smb_workgroup"].value)
self.smb_lf_cb.set_active (data["smb_translate"].value)
elif type == "NCP":
self.ncp_server_entry.set_text (data["ncp_server"].value)
self.ncp_user_entry.set_text (data["ncp_user"].value)
self.ncp_queue_entry.set_text (data["ncp_queue"].value)
self.ncp_passwd_entry.set_text (data["ncp_password"].value)
elif type == "JETDIRECT":
self.jd_printer_entry.set_text (data["jetdirect_ip"].value)
self.jd_port_entry.set_text (data["jetdirect_port"].value)
self.typedata = self.parent.conf.NameSpace ()
self.parent.conf.typespace_setup (self.queue, self.typedata)
self.type_menu.set_history (self.parent.queue_type_names.
index(self.queue["queue_type"].value))
self.type_menu_changed (self.type_menu)
# Fill in the queue options page.
# banner sheets
try:
jobsheets = self.queue["jobsheets"]
except:
pass
sheets = { "start": self.start_banner_menu,
"end": self.end_banner_menu }
for each in sheets.keys ():
menu = sheets[each]
try:
sheet = jobsheets[each].value
menu.set_history (self.sheet_types.index (sheet))
except:
menu.set_history (0)
# imageable area margins
m = {}
try:
margins = self.queue["margins"]
m["left"] = margins["left"].value
m["top"] = margins["top"].value
m["right"] = margins["right"].value
m["bottom"] = margins["bottom"].value
except:
m = self.parent.conf.conf.default_margins
for each in self.margin_widgets.keys ():
self.margin_widgets[each].set_value (m[each])
# filter options
try:
lpoptions = self.queue["lpoptions"]
except:
lpoptions = {}
store = self.options_store
store.clear ()
for opt in lpoptions.keys ():
iter = store.append (None)
store.set_value (iter, 0, opt)
store.set_value (iter, 1, lpoptions[opt])
for b in [self.opt_edit_button, self.opt_remove_button]:
b.set_sensitive (False)
# Prepare the driver options page.
self.driver_namespace = self.parent.conf.NameSpace ()
self.parent.conf.driverspace_setup (self.queue, self.driver_namespace)
self.write_driver_options ()
self.driver_options_up_to_date = 1
# Fill in the driver page.
self.mfr_list = self.parent.populate_mfr_optionmenu (self.mfr_menu,
self.queue)
self.id_to_iter = {}
iter = self.parent.populate_model_store (self.printer_store,
self.queue,
id_dict = self.id_to_iter,
window = self.window.window)
self.select_printer_iter (iter)
# Run the dialog.
self.window.set_transient_for (self.parent.toplevel)
self.window.set_position (gtk.WIN_POS_NONE)
self.parent.ready ()
backup_ctx = self.parent.conf.queue_edit.dynamic_queue_ctx.copy ()
while 1:
response = self.window.run ()
# Deal with the consequences.
if response == gtk.RESPONSE_OK:
if (self.validate_name_and_pull () or
self.validate_type_and_pull () or
self.validate_options_and_pull () or
self.validate_driver ()):
continue
if not self.driver_options_up_to_date:
self.window.set_sensitive (False)
while gtk.events_pending():
gtk.main_iteration()
self.write_driver_options ()
self.window.set_sensitive (True)
self.read_driver_options ()
self.parent.conf.driverspace_apply (self.queue,
self.driver_namespace)
# Adjust the queue tree to reflect the new name if it's
# changed.
name = self.parent.conf.demangle_queue_name (self.queue.name)
self.parent.queue_store.set_value (self.queue_tree_iter, 1,
name)
self.parent.queue_store.set_value (self.queue_tree_iter, 2,
self.
queue["queue_description"])
break
elif (response == gtk.RESPONSE_CANCEL or
response == gtk.RESPONSE_DELETE_EVENT):
self.parent.conf.dynamic_queue_ctx = backup_ctx
break
elif response == gtk.RESPONSE_HELP:
page = self.notebook.get_current_page ()
if page == 1:
html = "printconf-modify.html#S2-PRINTING-EDIT-QUEUETYPE"
elif page == 2:
html = "printconf-modify.html#S2-PRINTING-EDIT-DRIVER"
elif page == 3:
html = "printconf-modify.html#S2-PRINTING-EDIT-DRIVER-OPTIONS"
else:
html = "printconf-modify.html#S2-PRINTING-EDIT-NAMES"
gnome.url_show ("file://%s/%s" %
(self.parent.conf.conf.printconf_help_dir,
html))
elif response == 1: # 'Sharing...' button
# Make the dialog transient for us, not the main window.
parent_window = self.parent.toplevel
self.parent.toplevel = self.window
self.parent.sharing_button_clicked ()
self.parent.toplevel = parent_window
self.destroy (self.window)
return response == gtk.RESPONSE_OK
#-------------------------------------
# Helper functions used by this module
#-------------------------------------
def select_printer_iter (self, iter):
"""
Select iter, scrolling to the newly-selected row. Call
self.printer_model_selected.
"""
self.printer_view.get_selection ().select_iter (iter)
path = self.printer_store.get_path (iter)
col = self.printer_view.get_column (0)
self.printer_view.scroll_to_cell (path, col, True, 0.5, 0)
self.printer_model_selected (self.printer_view)
def rescan_devices (self, force = None):
"""
Rescan the local printer devices.
force: true if we want to force a rescan.
"""
select = None
try:
if self.queue["queue_type"].value == "LOCAL":
select = self.queue["queue_data"]["local_printer_device"].value
except:
pass
self.populate_device_view (select, force)
def show_driver_page (self):
"""Set the notebook to the driver page."""
self.notebook.set_current_page (3)
def populate_device_view (self, select = None, force = None):
"""
Populate the list of local printer devices.
force: true if a scan should be forced.
"""
self.local_devs = self.parent.conf.scan_local_printer_devices (force)
store = self.device_store
store.clear ()
for dev in self.local_devs.keys ():
iter = store.append (None)
store.set_value (iter, 0, dev)
try:
auto = self.local_devs[dev]["auto"]
description = auto.get("desc")
if not description:
description = "%s %s" % (auto["manufacturer"],
auto["model"])
except:
description = ""
store.set_value (iter, 1, description)
if dev == select:
self.device_view.get_selection ().select_iter (iter)
#----------------
# Queue type page
#----------------
def rescan_devices_button_clicked (self, button):
"""Handle the rescan button."""
self.rescan_devices (force = 1)
def custom_button_clicked (self, button):
"""Handle the custom device button."""
dialog = self.custom_dialog
self.custom_device_entry.set_text ('')
dialog.set_transient_for (self.window)
dialog.set_position (gtk.WIN_POS_CENTER_ON_PARENT)
response = dialog.run ()
device = self.custom_device_entry.get_text ()
dialog.hide ()
if response != gtk.RESPONSE_OK or not device:
return
if not os.access (device, os.W_OK):
complain (self.window,
_("'%s' does not exist, or is not writable.") % device)
return
iter = self.device_store.append (None)
self.device_store.set_value (iter, 0, device)
self.device_store.set_value (iter, 1, _("Custom device"))
self.device_view.get_selection ().select_iter (iter)
def autoselect_driver (self, button):
"""Handler for the autoselect button."""
selection = self.device_view.get_selection ()
store, iter = selection.get_selected ()
if not iter:
return
dev = store.get_value (iter, 0)
try:
mfr = string.lower (self.local_devs[dev]["auto"]["manufacturer"])
mdl = string.lower (self.local_devs[dev]["auto"]["model"])
except:
complain (self.window, _("Can't determine the printer model "
"attached to this device."))
return
p = self.parent.conf.foomatic_match_printer (mfr, mdl)
if p:
id = p.id
else:
complain (self.window, _("I don't know enough about this "
"printer model to choose a driver."))
return
mfr = self.parent.conf.foomatic.id_dict[id].make
self.mfr_menu.set_history (self.mfr_list.index (mfr))
iter = self.id_to_iter[id]
self.select_printer_iter (iter)
self.show_driver_page ()
def type_menu_changed (self, optionmenu):
"""Set the notebook page to match the optionmenu."""
index = optionmenu.get_history ()
self.type_notebook.set_current_page (index)
self.typedata.queue_type_space = self.parent.queue_types[index]
#-------------------
# Queue options page
#-------------------
def add_or_edit_queue_option (self, iter = None):
"""Run the queue option dialog.
iter: None if adding option, otherwise options_store iter of item
to be edited."""
store = self.options_store
d = self.option_dialog
known_options = []
current_options = []
try:
this_name = store.get_value (iter, 0)
except:
this_name = None
for row in store:
i = store.get_iter (row.path)
name = store.get_value (i, 0)
if this_name == name:
continue
current_options.append (store.get_value (i, 0))
for opt in self.known_options.keys ():
try:
if current_options.index (opt):
continue
except:
known_options.append (opt)
known_options.sort ()
self.option_combo.set_popdown_strings (known_options)
if iter:
d.set_title (_("Edit queue option"))
self.option_combo.entry.set_text (this_name)
self.option_value_entry.set_text (store.get_value (iter, 1))
self.option_value_entry.grab_focus ()
else:
d.set_title (_("Add queue option"))
self.option_combo.entry.set_text ('')
self.option_value_entry.set_text ('')
d.set_transient_for (self.window)
d.set_position (gtk.WIN_POS_CENTER_ON_PARENT)
while 1:
response = d.run ()
if response == gtk.RESPONSE_OK:
# Validate
option = self.option_combo.entry.get_text ()
value = self.option_value_entry.get_text ()
valid_option_re = re.compile ("^[a-zA-Z_][-a-zA-Z0-9_]*$")
if not valid_option_re.match (option):
complain (d, _("Invalid option name"))
self.option_combo.entry.grab_focus ()
continue
if value == "":
value = "true"
valid_value_re = re.compile ("^[-a-zA-Z0-9_.]*$")
if not valid_value_re.match (value):
complain (d, _("Invalid value"))
self.option_value_entry.grab_focus ()
continue
if not iter:
# Check for duplicates and remove if necessary
for row in store:
iter = store.get_iter (row.path)
if store.get_value (iter, 0) == option:
store.remove (iter)
# Add the new option
iter = store.append (None)
store.set_value (iter, 0, option)
store.set_value (iter, 1, value)
self.options_view.get_selection ().select_iter (iter)
for b in [self.opt_edit_button, self.opt_remove_button]:
b.set_sensitive (True)
break
elif (response == gtk.RESPONSE_CANCEL or
response == gtk.RESPONSE_DELETE_EVENT):
break
elif response == gtk.RESPONSE_HELP:
gnome.url_show ("file://%s/index.html" %
self.parent.conf.conf.printconf_help_dir)
d.hide ()
def add_queue_option (self, button):
"""Handler for queue options add button."""
self.add_or_edit_queue_option ()
def edit_queue_option (self, *args):
"""Handler for queue options edit button."""
store, iter = self.options_view.get_selection ().get_selected ()
self.add_or_edit_queue_option (iter)
def remove_queue_option (self, button):
"""Handler for queue options remove button."""
store, iter = self.options_view.get_selection ().get_selected ()
store.remove (iter)
for b in [self.opt_edit_button, self.opt_remove_button]:
b.set_sensitive (False)
def default_queue_options (self, button):
"""Handler for queue options defaults button."""
store = self.options_store
store.clear ()
lpoptions = self.parent.conf.conf.default_lpoptions
for option in lpoptions.keys ():
iter = store.append (None)
store.set_value (iter, 0, option)
store.set_value (iter, 1, lpoptions[option])
for b in [self.opt_edit_button, self.opt_remove_button]:
b.set_sensitive (False)
def option_cursor_changed (self, treeview):
"""Handler for options treeview cursor changed."""
for b in [self.opt_edit_button, self.opt_remove_button]:
b.set_sensitive (True)
def option_combo_list_selection_changed (self, list):
"""Handler for queue option combo list selection changed."""
k = self.option_combo.entry.get_text ()
if self.known_options.has_key (k):
label = self.known_options[k]
else:
label = _("Value for this option")
self.option_value_label.set_text (label)
#--------------------------
# Printer model/driver page
#--------------------------
def printer_select_function (self, path):
"""Don't allow this path to be selected unless it is a leaf."""
iter = self.printer_store.get_iter (path)
return not self.printer_store.iter_has_child (iter)
def mfr_menu_changed (self, menu):
"""Update the model list."""
try:
mfr = self.mfr_list[menu.get_history ()]
except:
return
self.id_to_iter = {}
iter = self.parent.populate_model_store (self.printer_store,
self.queue,
id_dict = self.id_to_iter,
mfr = mfr,
window = self.window.window)
if not iter:
iter = self.printer_store.get_iter_first ()
self.select_printer_iter (iter)
def printer_model_selected (self, treeview):
"""A printer model has been selected. Fill in the driver menu."""
make = self.mfr_list[self.mfr_menu.get_history ()]
selection = treeview.get_selection ()
store, model_iter = selection.get_selected ()
d, id = store.get_value (model_iter, 1)
if id:
model = store.get_value (model_iter, 0)
menu = gtk.Menu ()
try:
if (self.parent.conf.foomatic.make_model_dict_dict
[make][model].id ==
self.queue["filter_data"]["printer_id"].value):
this_driver = self.queue["filter_data"]["gs_driver"].value
else:
this_driver = None
except:
this_driver = None
self.drivers = (self.parent.conf.foomatic.
make_model_dict_dict[make][model].drivers)
try:
recommended = (self.parent.conf.foomatic.
make_model_dict_dict[make][model].driver)
# Cope with inconsistencies.
if not recommended in self.drivers:
recommended = self.drivers[0]
except:
recommended = self.drivers[0]
driver_index = None
for driver in self.drivers:
menuitem = gtk.MenuItem (driver)
menu.add (menuitem)
menuitem.show ()
menuitem.set_sensitive (True)
n = self.drivers.index (driver)
if driver == recommended:
self.recommended_driver = n
if this_driver != None:
if driver == this_driver:
driver_index = n
elif driver == recommended:
driver_index = n
if driver_index == None:
driver_index = self.recommended_driver
self.drivers_menu.set_sensitive (True)
self.drivers_menu.set_menu (menu)
if driver_index != None:
self.drivers_menu.set_history (driver_index)
self.notes_button.set_sensitive (True)
else:
self.notes_button.set_sensitive (False)
self.recommended_driver = -1
self.drivers_menu.set_sensitive (False)
menu = gtk.Menu ()
menuitem = gtk.MenuItem (_("None"))
menu.add (menuitem)
menuitem.show ()
menuitem.set_sensitive (True)
self.drivers_menu.set_menu (menu)
self.drivers_menu_changed (self.drivers_menu)
def drivers_menu_changed (self, optionmenu):
"""Determine whether this is the recommended driver."""
try:
if self.recommended_driver == optionmenu.get_history ():
self.recommended_label.\
set_label (_('(this is the\nrecommended driver)'))
else:
self.recommended_label.\
set_label (_('(recommended\ndriver is %s)')
% self.drivers[self.recommended_driver])
except:
self.recommended_label.set_label ('')
selection = self.printer_view.get_selection ()
store, iter = selection.get_selected ()
type, printer_id = store.get_value (iter, 1)
# Update self.driver_namespace to reflect the current settings.
self.driver_namespace.f_type = type.filter_type
try:
self.driver_namespace.foomatic.mf_type = type.mf_type
except:
pass
if type == self.parent.conf.drivers.foomatic:
gs_driver = self.drivers[optionmenu.get_history ()]
self.driver_namespace.foomatic.printer_id = printer_id
self.driver_namespace.foomatic.gs_driver = gs_driver
else:
self.recommended_label.set_label ('')
# Driver options need redoing now.
self.driver_options_up_to_date = 0
def notes_button_clicked (self, button):
"""Handler for the notes button."""
selection = self.printer_view.get_selection ()
store, iter = selection.get_selected ()
type, printer_id = store.get_value (iter, 1)
if printer_id:
selected_driver = self.drivers_menu.get_history ()
driver = self.drivers[selected_driver]
self.parent.show_notes (printer_id, driver, self)
#--------------------
# Driver options page
#--------------------
def wipe_driver_options (self):
# Clear out the current options.
for child in self.options_table.get_children ():
self.options_table.remove (child)
self.options_table.resize (1, 2)
self.widget_list = []
def write_driver_options (self):
self.wipe_driver_options ()
option_list = (self.parent.conf.
generate_option_list (self.driver_namespace))
self.widget_list = []
if not option_list:
option_list = []
for option_tuple in option_list:
(opt_type, en_shortname,
prettyname, dict, default, type_data) = option_tuple
def_val = dict.get ((en_shortname, opt_type), default)
label_widget = gtk.Label (prettyname)
label_widget.set_alignment (0.0, 0.5)
if opt_type == "bool":
data_widget = gtk.CheckButton ()
data_widget.set_active (self.parent.conf.strtobool (def_val))
elif opt_type == "int":
(max, min) = type_data
val = int (def_val)
adjustment = gtk.Adjustment (val, lower = int (min),
upper = int (max),
step_incr = 1, page_incr = 10)
data_widget = gtk.SpinButton (adjustment)
data_widget.set_digits (0)
elif opt_type == "float":
(max, min) = type_data
val = C_float (def_val)
adjustment = gtk.Adjustment (val, lower = C_float (min),
upper = C_float (max),
step_incr = 0.1, page_incr = 1)
data_widget = gtk.SpinButton (adjustment)
data_widget.set_digits (1)
elif opt_type == "enum":
val_list = type_data
store = gtk.ListStore (str, str)
data_widget = gtk.ComboBox (store)
cell = gtk.CellRendererText()
data_widget.pack_start (cell, True)
data_widget.set_attributes (cell, text = 0)
set = def_val
for (val, val_label) in val_list:
iter = store.append (None)
store.set_value (iter, 0, val_label)
store.set_value (iter, 1, val)
if set != None:
# Make sure one is selected even if the selected
# option value no longer exists.
data_widget.set_active_iter (iter)
if val == set:
data_widget.set_active_iter (iter)
set = None
else:
raise RuntimeError, "unknown type %s" % opt_type
self.widget_list.append ((label_widget, data_widget, option_tuple))
if not len (self.widget_list):
# Need to beautify this.
label = gtk.Label (
_("There are no options available for this driver."))
self.options_table.resize (1, 1)
self.options_table.attach (label, 0, 1, 0, 1, gtk.FILL)
else:
self.options_table.resize (len (self.widget_list), 2)
for i in range (len (self.widget_list)):
(label_widget, data_widget) = self.widget_list[i][:2]
self.options_table.attach (label_widget, 0, 1, i, i+1,gtk.FILL)
self.options_table.attach (data_widget, 1, 2, i, i+1)
self.options_table.show_all ()
def read_driver_options (self):
for (label_widget, data_widget, option_tuple) in self.widget_list:
(opt_type, en_shortname,
prettyname, dict, default, type_data) = option_tuple
key = (en_shortname, opt_type)
is_default = 1
if opt_type == "bool":
dict[key] = data_widget.get_active ()
if self.parent.conf.strtobool (dict[key]) != \
self.parent.conf.strtobool (default):
is_default = 0
elif opt_type == "int":
dict[key] = data_widget.get_value_as_int ()
if int (dict[key]) != int (default):
is_default = 0
elif opt_type == "float":
dict[key] = data_widget.get_value ()
if C_float (dict[key]) != C_float (default):
is_default = 0
elif opt_type == "enum":
store = data_widget.get_model ()
iter = data_widget.get_active_iter ()
if iter:
dict[key] = store.get_value (iter, 1)
if dict[key] != default:
is_default = 0
#-------------------------
# Handle the main notebook
#-------------------------
def notebook_switch_page (self, notebook, cobject, pageindex):
"""Handler for the main notebook page-switch."""
if pageindex < 4:
return
# User flipped to driver options page.
# Did they change the driver since last time?
if self.driver_options_up_to_date:
return
notebook.set_sensitive (False)
while gtk.events_pending():
gtk.main_iteration()
self.write_driver_options ()
self.driver_options_up_to_date = 1
# Now safe to use.
notebook.set_sensitive (True)
#-----------
# Validation
#-----------
def validate_name_and_pull (self):
"""Returns true if validation failed."""
def grab ():
self.notebook.set_current_page (0)
self.name_entry.grab_focus ()
name = self.name_entry.get_text ()
# Is the name even valid at all?
if not self.parent.conf.valid_queue_name (name):
grab ()
complain (self.window, _("Invalid name"))
return 1
# Is there already a queue (or alias) of that name?
name_dict_dict, alias_dict_dict = self.parent.conf.get_queues ()
if (name_dict_dict.has_key (name) and
name_dict_dict[name]["queue"] != self.queue):
grab ()
complain (self.window,
_("There is already a queue with that name."))
return 1
if (alias_dict_dict.has_key (name) and
alias_dict_dict[name]["queue"] != self.queue):
grab ()
complain (self.window,
_("An existing queue has an alias of that name."))
return 1
self.queue.name = self.parent.conf.mangle_queue_name (name)
self.queue["queue_description"] = self.desc_entry.get_text ()
return 0
def show_type_page (self):
self.notebook.set_current_page (1)
def validate_type_and_pull (self):
"""Returns true if validation failed."""
# Check for missing packages.
if not self.typedata.queue_type_space.check ():
ask = gtk.MessageDialog (self.window, 0, gtk.MESSAGE_WARNING,
gtk.BUTTONS_YES_NO,
self.typedata.queue_type_space.message)
ask.set_transient_for (self.window)
ask.set_position (gtk.WIN_POS_CENTER_ON_PARENT)
response = ask.run ()
ask.destroy ()
if response != gtk.RESPONSE_YES:
self.show_type_page ()
return 1
types = self.parent.conf.queue_types
if self.typedata.queue_type_space == types.local:
if self.validate_local_type_and_pull ():
return 1
elif self.typedata.queue_type_space == types.ipp:
if self.validate_ipp_type_and_pull ():
return 1
elif self.typedata.queue_type_space == types.lpd:
if self.validate_lpd_type_and_pull ():
return 1
elif self.typedata.queue_type_space == types.smb:
if self.validate_smb_type_and_pull ():
return 1
elif self.typedata.queue_type_space == types.ncp:
if self.validate_ncp_type_and_pull ():
return 1
elif self.typedata.queue_type_space == types.jetdirect:
if self.validate_jetdirect_type_and_pull ():
return 1
# Push the type data back into the queue.
self.parent.conf.typespace_apply (self.queue, self.typedata)
return 0
def validate_local_type_and_pull (self):
"""Returns true if validation failed."""
selection = self.device_view.get_selection ()
store, iter = selection.get_selected ()
if not iter:
complain (self.window, _("You must select a device."))
self.show_type_page ()
self.device_view.grab_focus ()
return 1
local_printer_device = store.get_value (iter, 0)
self.typedata.data["local_printer_device"] = local_printer_device
return 0
def validate_ipp_type_and_pull (self):
"""Returns true if validation failed."""
ipp_server = self.ipp_server_entry.get_text ()
ipp_path = self.ipp_path_entry.get_text ()
if not ipp_server:
complain (self.window, _("You must specify a server."))
self.show_type_page ()
self.ipp_server_entry.grab_focus ()
return 1
if not ipp_path:
complain (self.window, _("You must specify a path."))
self.show_type_page ()
self.ipp_path_entry.grab_focus ()
return 1
self.typedata.data["ipp_server"] = ipp_server
self.typedata.data["ipp_port"] = "631"
self.typedata.data["ipp_path"] = ipp_path
return 0
def validate_lpd_type_and_pull (self):
"""Returns true if validation failed."""
lpd_server = self.lpd_server_entry.get_text ()
lpd_queue = self.lpd_queue_entry.get_text ()
rfc1179 = self.rfc1179_cb.get_active ()
if not lpd_server:
complain (self.window, _("You must specify a server."))
self.show_type_page ()
self.lpd_server_entry.grab_focus ()
return 1
if not lpd_queue:
complain (self.window, _("You must specify a queue."))
self.show_type_page ()
self.lpd_queue_entry.grab_focus ()
return 1
self.typedata.data["lpd_server"] = lpd_server
self.typedata.data["lpd_queue"] = lpd_queue
self.typedata.data["lpd_strict_rfc1179"] = rfc1179
return 0
def validate_smb_type_and_pull (self):
"""Returns true if validation failed."""
smb_share = self.smb_share_entry.get_text ()
smb_user = self.smb_user_entry.get_text ()
smb_ip = self.smb_host_entry.get_text ()
smb_password = self.smb_passwd_entry.get_text ()
smb_workgroup = self.smb_group_entry.get_text ()
smb_translate = self.smb_lf_cb.get_active ()
if not smb_share:
complain (self.window,
_("You must specify an SMB share to print to."))
self.show_type_page ()
self.smb_share_entry.grab_focus ()
return 1
self.typedata.data["smb_share"] = smb_share
self.typedata.data["smb_user"] = smb_user
self.typedata.data["smb_ip"] = smb_ip
self.typedata.data["smb_password"] = smb_password
self.typedata.data["smb_workgroup"] = smb_workgroup
self.typedata.data["smb_translate"] = smb_translate
return 0
def validate_ncp_type_and_pull (self):
"""Returns true if validation failed."""
ncp_server = self.ncp_server_entry.get_text ()
ncp_queue = self.ncp_queue_entry.get_text ()
ncp_user = self.ncp_user_entry.get_text ()
ncp_password = self.ncp_passwd_entry.get_text ()
if not ncp_server:
complain (self.window,
_("You must specify an NCP server to print to."))
self.show_type_page ()
self.ncp_server_entry.grab_focus ()
return 1
if not ncp_queue:
complain (self.window,
_("You must specify a queue on the NCP server."))
self.show_type_page ()
self.ncp_queue_entry.grab_focus ()
return 1
self.typedata.data["ncp_server"] = ncp_server
self.typedata.data["ncp_queue"] = ncp_queue
self.typedata.data["ncp_user"] = ncp_user
self.typedata.data["ncp_password"] = ncp_password
return 0
def validate_jetdirect_type_and_pull (self):
"""Returns true if validation failed."""
jetdirect_ip = self.jd_printer_entry.get_text ()
port = self.jd_port_entry.get_text ()
if not jetdirect_ip:
complain (self.window,
_("You must specify a JetDirect printer to print to."))
self.show_type_page ()
self.jd_printer_entry.grab_focus ()
return 1
try:
jetdirect_port = int (port)
except:
complain (self.window, _("You must specify an IP port number."))
self.show_type_page ()
self.jd_port_entry.grab_focus ()
return 1
self.typedata.data["jetdirect_ip"] = jetdirect_ip
self.typedata.data["jetdirect_port"] = jetdirect_port
return 0
def validate_options_and_pull (self):
"""Returns true if validation failed."""
# Actually validation was already done when options were added
# or edited. So just pull.
# banner pages
try:
self.queue["jobsheets"].unlink ()
except:
pass
jobsheets = self.queue.addData (pyalchemist.AdmListType, "jobsheets")
start = jobsheets.addData (pyalchemist.AdmStringType, "start")
start.value = self.sheet_types[self.start_banner_menu.get_history ()]
end = jobsheets.addData (pyalchemist.AdmStringType, "end")
end.value = self.sheet_types[self.end_banner_menu.get_history ()]
# imageable area margins
try:
self.queue["margins"].unlink ()
except:
pass
margins = self.queue.addData (pyalchemist.AdmListType, "margins")
for each in self.margin_widgets.keys ():
c = margins.addData (pyalchemist.AdmIntType, each)
c.value = self.margin_widgets[each].get_value ()
# filter options
try:
self.queue["lpoptions"].unlink ()
except:
pass
lpoptions = self.queue.addData (pyalchemist.AdmListType, "lpoptions")
store = self.options_store
for row in store:
iter = store.get_iter (row.path)
opt = lpoptions.addData (pyalchemist.AdmStringType,
store.get_value (iter, 0))
opt.value = store.get_value (iter, 1)
return False
def validate_driver (self):
"""Returns true if validation failed."""
# Check the blacklist.
try:
selected_driver = self.drivers_menu.get_history ()
driver = self.drivers[selected_driver]
blacklist = self.parent.conf.driver_blacklist
black = blacklist.dict[driver]
except:
return 0
if not black.check ():
ask = gtk.MessageDialog (self.window, 0, gtk.MESSAGE_WARNING,
gtk.BUTTONS_YES_NO, black.message)
ask.set_transient_for (self.window)
ask.set_position (gtk.WIN_POS_CENTER_ON_PARENT)
response = ask.run ()
ask.destroy ()
if response != gtk.RESPONSE_YES:
return 1
return 0
# Local Variables:
# py-indent-offset: 4
# End: