1#!/usr/local/bin/python3.8 2 3## Copyright (C) 2006, 2007, 2008, 2010, 2012, 2014 Red Hat, Inc. 4## Author: Tim Waugh <twaugh@redhat.com> 5 6## This program is free software; you can redistribute it and/or modify 7## it under the terms of the GNU General Public License as published by 8## the Free Software Foundation; either version 2 of the License, or 9## (at your option) any later version. 10 11## This program is distributed in the hope that it will be useful, 12## but WITHOUT ANY WARRANTY; without even the implied warranty of 13## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14## GNU General Public License for more details. 15 16## You should have received a copy of the GNU General Public License 17## along with this program; if not, write to the Free Software 18## Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 19 20from gi.repository import Gtk 21import os 22import subprocess 23 24class UserDefaultPrinter: 25 def __init__ (self): 26 try: 27 lpoptions = os.environ["HOME"] 28 except KeyError: 29 try: 30 lpoptions = "/home/" + os.environ["USER"] 31 except KeyError: 32 lpoptions = None 33 34 if lpoptions: 35 lpoptions += "/.cups/lpoptions" 36 37 self.lpoptions = lpoptions 38 39 def clear (self): 40 if not self.lpoptions: 41 return 42 43 try: 44 opt_file = open(self.lpoptions) 45 opts = opt_file.readlines () 46 except IOError: 47 return 48 49 for i in range (len (opts)): 50 if opts[i].startswith ("Default "): 51 opts[i] = "Dest " + opts[i][8:] 52 open (self.lpoptions, "w").writelines (opts) 53 54 def get (self): 55 if not self.lpoptions: 56 return None 57 58 try: 59 opt_file = open(self.lpoptions) 60 opts = opt_file.readlines () 61 except IOError: 62 return None 63 64 for i in range (len (opts)): 65 if opts[i].startswith ("Default "): 66 rest = opts[i][8:] 67 slash = rest.find ("/") 68 if slash != -1: 69 space = rest[:slash].find (" ") 70 else: 71 space = rest.find (" ") 72 return rest[:space] 73 return None 74 75 def set (self, default): 76 p = subprocess.Popen ([ "lpoptions", "-d", default ], 77 close_fds=True, 78 stdin=subprocess.DEVNULL, 79 stdout=subprocess.DEVNULL, 80 stderr=subprocess.PIPE) 81 (stdout, stderr) = p.communicate () 82 exitcode = p.wait () 83 if exitcode != 0: 84 raise RuntimeError (exitcode, stderr.decode ().strip ()) 85 return 86 87 def __repr__ (self): 88 return "<UserDefaultPrinter (%s)>" % repr (self.get ()) 89 90class UserDefaultPrompt: 91 def __init__ (self, 92 set_default_fn, 93 refresh_fn, 94 name, 95 title, 96 parent, 97 primarylabel, 98 systemwidelabel, 99 clearpersonallabel, 100 personallabel): 101 self.set_default_fn = set_default_fn 102 self.refresh_fn = refresh_fn 103 self.name = name 104 dialog = Gtk.Dialog (title=title, 105 transient_for=parent, 106 modal=True, 107 destroy_with_parent=True) 108 dialog.add_buttons (Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL, 109 Gtk.STOCK_OK, Gtk.ResponseType.OK) 110 dialog.set_default_response (Gtk.ResponseType.OK) 111 dialog.set_border_width (6) 112 dialog.set_resizable (False) 113 hbox = Gtk.HBox.new (False, 12) 114 hbox.set_border_width (6) 115 image = Gtk.Image () 116 image.set_from_stock (Gtk.STOCK_DIALOG_QUESTION, Gtk.IconSize.DIALOG) 117 image.set_alignment (0.0, 0.0) 118 hbox.pack_start (image, False, False, 0) 119 vboxouter = Gtk.VBox.new (False, 6) 120 primary = Gtk.Label () 121 primary.set_markup ('<span weight="bold" size="larger">' + 122 primarylabel + '</span>') 123 primary.set_line_wrap (True) 124 primary.set_alignment (0.0, 0.0) 125 vboxouter.pack_start (primary, False, False, 0) 126 vboxradio = Gtk.VBox.new (False, 0) 127 systemwide = Gtk.RadioButton.new_with_mnemonic (None, systemwidelabel) 128 vboxradio.pack_start (systemwide, False, False, 0) 129 clearpersonal = Gtk.CheckButton.new_with_mnemonic (clearpersonallabel) 130 alignment = Gtk.Alignment.new (0, 0, 0, 0) 131 alignment.set_padding (0, 0, 12, 0) 132 alignment.add (clearpersonal) 133 vboxradio.pack_start (alignment, False, False, 0) 134 vboxouter.pack_start (vboxradio, False, False, 0) 135 personal = Gtk.RadioButton.new_with_mnemonic_from_widget(systemwide, 136 personallabel) 137 vboxouter.pack_start (personal, False, False, 0) 138 hbox.pack_start (vboxouter, False, False, 0) 139 dialog.vbox.pack_start (hbox, False, False, 0) 140 systemwide.set_active (True) 141 clearpersonal.set_active (True) 142 self.userdef = UserDefaultPrinter () 143 clearpersonal.set_sensitive (self.userdef.get () is not None) 144 145 self.systemwide = systemwide 146 self.clearpersonal = clearpersonal 147 self.personal = personal 148 systemwide.connect ("toggled", self.on_toggled) 149 dialog.connect ("response", self.on_response) 150 dialog.show_all () 151 152 def on_toggled (self, button): 153 self.clearpersonal.set_sensitive (self.userdef.get () is not None and 154 self.systemwide.get_active ()) 155 156 def on_response (self, dialog, response_id): 157 if response_id != Gtk.ResponseType.OK: 158 dialog.destroy () 159 return 160 161 if self.systemwide.get_active (): 162 if self.clearpersonal.get_active (): 163 self.userdef.clear () 164 self.set_default_fn (self.name) 165 else: 166 try: 167 self.userdef.set (self.name) 168 except Exception as e: 169 print("Error setting default: %s" % repr (e)) 170 171 self.refresh_fn () 172 173 dialog.destroy () 174