1# -*- coding: utf-8 -*- 2# 3# (c) Copyright 2001-2015 HP Development Company, L.P. 4# 5# This program is free software; you can redistribute it and/or modify 6# it under the terms of the GNU General Public License as published by 7# the Free Software Foundation; either version 2 of the License, or 8# (at your option) any later version. 9# 10# This program is distributed in the hope that it will be useful, 11# but WITHOUT ANY WARRANTY; without even the implied warranty of 12# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13# GNU General Public License for more details. 14# 15# You should have received a copy of the GNU General Public License 16# along with this program; if not, write to the Free Software 17# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 18# 19# Author: Don Welch 20# 21 22# Std Lib 23 24# Local 25from base.g import * 26from prnt import cups 27from base import device 28from base.sixext import to_unicode 29from .ui_utils import load_pixmap 30 31# Qt 32from qt import * 33 34 35 36class Widget(QWidget): 37 def __init__(self, parent=None, name=None, fl=0): 38 QWidget.__init__(self, parent, name, fl) 39 self.control = None 40 41 def setControl(self, control): 42 self.control = control 43 44 45 46class ScrollView(QScrollView): 47 def __init__(self, service=None, parent=None, name=None, fl=0): 48 QScrollView.__init__(self, parent, name, fl) 49 50 self.service = service 51 self.items = {} 52 self.enableClipper(True) 53 self.viewport().setPaletteBackgroundColor(qApp.palette().color(QPalette.Active, QColorGroup.Background)) 54 self.cur_device = None 55 self.cur_printer = None 56 self.item_margin = 2 57 self.y = 0 58 self.printers = [] 59 self.maximize = None 60 self.orig_height = 0 61 self.content_padding = 20 62 63 if log.is_debug(): 64 self.heading_color = qApp.palette().color(QPalette.Active, QColorGroup.Base) 65 self.frame_shape = QFrame.Box 66 else: 67 self.heading_color = qApp.palette().color(QPalette.Active, QColorGroup.Background) 68 self.frame_shape = QFrame.NoFrame 69 70 def getWidget(self): 71 widget = Widget(self.viewport(),"widget") 72 widget.setPaletteBackgroundColor(qApp.palette().color(QPalette.Active, QColorGroup.Background)) 73 return widget 74 75 def viewportResizeEvent(self, e): 76 QScrollView.viewportResizeEvent(self, e) 77 78 total_height = 0 79 item_margin = self.item_margin 80 width = e.size().width() 81 82 for w in self.items: 83 height = self.items[w].size().height() 84 self.items[w].resize(width, height) 85 self.items[w].setMinimumWidth(width) 86 total_height += (height + item_margin) 87 88 if self.maximize is not None: 89 self.maximizeControl(total_height) 90 91 self.resizeContents(e.size().width(), total_height + self.content_padding) 92 93 def maximizeControl(self, total_height=0): 94 if self.maximize is not None: 95 try: 96 self.items[self.maximize] 97 except KeyError: 98 return 99 100 if total_height == 0: 101 item_margin = self.item_margin 102 for w in self.items: 103 total_height += (self.items[w].size().height() + item_margin) 104 105 if len(self.items) == 1: 106 #total_height += item_margin 107 self.content_padding = 0 108 109 width = self.items[self.maximize].size().width() 110 old_height = self.items[self.maximize].size().height() 111 112 new_height = max((self.visibleHeight()-(total_height-old_height)), 113 self.orig_height) 114 115 delta = new_height - old_height 116 117 if delta: 118 self.items[self.maximize].resize(width, new_height) 119 self.resizeContents(width, self.contentsHeight()+delta+self.content_padding) 120 m_y = self.childY(self.items[self.maximize]) 121 122 for w in self.items: 123 w_y = self.childY(self.items[w]) 124 if w_y > m_y: 125 self.moveChild(self.items[w], 0, w_y+delta) 126 127 128 def onDeviceChange(self, cur_device=None, updating=False): 129 if cur_device is not None: 130 log.debug("ScrollView.onDeviceChange(%s)" % cur_device.device_uri) 131 else: 132 log.debug("ScrollView.onDeviceChange(None)") 133 134 self.cur_device = cur_device 135 136 if self.cur_device is not None and self.cur_device.supported: 137 #if not updating or not self.cur_printer: 138 if not self.cur_printer: 139 try: 140 cur_printer = self.cur_device.cups_printers[0] 141 except IndexError: 142 log.error("Printer list empty") # Shouldn't happen! 143 self.cur_printer = None 144 return 145 146 #self.isFax() 147 self.printers = cups.getPrinters() 148 self.onPrinterChange(cur_printer) 149 self.cur_printer = cur_printer 150 151 #else: 152 if 1: 153 QApplication.setOverrideCursor(QApplication.waitCursor) 154 try: 155 if 1: 156 #try: 157 self.fillControls() 158 #except Exception, e: 159 # log.exception() 160 finally: 161 QApplication.restoreOverrideCursor() 162 163 else: 164 log.debug("Unsupported device") 165 self.y = 0 166 self.clear() 167 168 self.addGroupHeading("error", self.__tr("ERROR: No device found or unsupported device.")) 169 170 def onUpdate(self, cur_device=None): 171 log.debug("ScrollView.onUpdate()") 172 return self.onDeviceChange(cur_device, True) 173 174 def fillControls(self): 175 log.debug("fillControls(%s)" % str(self.name())) 176 self.y = 0 177 self.clear() 178 179 def onPrinterChange(self, printer_name): 180 if printer_name == self.cur_printer or printer_name is None: 181 return 182 183 self.cur_printer = to_unicode(printer_name) 184 185 if self.cur_device is not None and self.cur_device.supported: 186 #self.isFax() 187 QApplication.setOverrideCursor(QApplication.waitCursor) 188 try: 189 if 1: 190 #try: 191 self.fillControls() 192 #except Exception, e: 193 # log.exception() 194 finally: 195 QApplication.restoreOverrideCursor() 196 197 if self.cur_printer is not None: 198 try: 199 self.printerComboBox.setCurrentText(self.cur_printer) 200 except AttributeError: 201 pass 202 203 else: 204 self.y = 0 205 self.clear() 206 207 def addWidget(self, widget, key, control=None, maximize=False): 208 try: 209 self.items[key] 210 except KeyError: 211 if maximize: 212 self.maximize = key 213 widget.resize(widget.size().width(), 150) 214 self.orig_height = widget.size().height() 215 216 try: 217 widget.setControl(control) 218 except AttributeError: 219 pass 220 self.items[key] = widget 221 widget.setMinimumWidth(self.visibleWidth()) 222 widget.adjustSize() 223 self.addChild(widget, 0, self.y) 224 self.y += (widget.size().height() + self.item_margin) 225 self.resizeContents(self.visibleWidth(), self.y + self.content_padding) 226 widget.show() 227 #else: 228 # log.debug("ERROR: Duplicate control name: %s" % key) 229 230 def clear(self): 231 if len(self.items): 232 for x in self.items: 233 self.removeChild(self.items[x]) 234 self.items[x].hide() 235 236 self.items.clear() 237 238 def addGroupHeading(self, group, heading, read_only=False): 239 widget = self.getWidget() 240 widget.setMinimumHeight(30) 241 242 layout = QGridLayout(widget, 0, 0, 5, 0, "layout") 243 textLabel2 = QLabel(widget, "textLabel2") 244 245 textLabel2.setSizePolicy(QSizePolicy(QSizePolicy.Preferred, 246 QSizePolicy.Maximum, 0, 0, 247 textLabel2.sizePolicy().hasHeightForWidth())) 248 249 if log.is_debug(): 250 textLabel2.setFrameShape(self.frame_shape) 251 252 elif heading: 253 textLabel2.setFrameShape(QFrame.TabWidgetPanel) 254 textLabel2.setPaletteBackgroundColor(self.heading_color) 255 256 if read_only: 257 s = self.__tr("<b>%1 (read only)</b>").arg(heading) # <nobr> 258 else: 259 s = QString("<b>%1</b>").arg(heading) 260 261 # If label is kinda long, provide a tooltip to allow reading the whole thing 262 if s.length() > 32: 263 QToolTip.add(textLabel2, s) 264 265 textLabel2.setText(s) 266 textLabel2.setAlignment(QLabel.AlignLeft | QLabel.AlignVCenter | Qt.SingleLine) 267 268 layout.addWidget(textLabel2, 0, 0) 269 270 self.addWidget(widget, "g:"+to_unicode(group)) 271 272 273 def addActionButton(self, name, action_text, action_func, 274 action_pixmap=None, disabled_action_pixmap=None, 275 nav_text ='', nav_func=None): 276 277 widget = self.getWidget() 278 279 self.actionPushButton = None 280 self.navPushButton = None 281 282 layout36 = QHBoxLayout(widget,5,10,"layout36") 283 284 if nav_func is not None: 285 self.navPushButton = QPushButton(widget,"navPushButton") 286 navPushButton_font = QFont(self.navPushButton.font()) 287 navPushButton_font.setBold(1) 288 self.navPushButton.setFont(navPushButton_font) 289 self.navPushButton.setText(nav_text) 290 layout36.addWidget(self.navPushButton) 291 292 self.connect(self.navPushButton, SIGNAL("clicked()"), nav_func) 293 294 spacer35 = QSpacerItem(20,20,QSizePolicy.Expanding,QSizePolicy.Minimum) 295 layout36.addItem(spacer35) 296 297 if action_func is not None: 298 if action_pixmap is None: 299 self.actionPushButton = QPushButton(widget, "actionPushButton") 300 else: 301 self.actionPushButton = PixmapLabelButton(widget, action_pixmap, 302 disabled_action_pixmap, 'actionPushButton') 303 304 actionPushButton_font = QFont(self.actionPushButton.font()) 305 actionPushButton_font.setBold(1) 306 self.actionPushButton.setFont(actionPushButton_font) 307 layout36.addWidget(self.actionPushButton) 308 309 self.actionPushButton.setText(action_text) 310 311 self.connect(self.actionPushButton, SIGNAL("clicked()"), action_func) 312 313 self.addWidget(widget, name) 314 315 if self.actionPushButton is not None: 316 return self.actionPushButton 317 318 elif self.navPushButton is not None: 319 return self.navPushButton 320 321 else: 322 return None 323 324 def printerComboBox_activated(self, p): 325 self.cur_printer = str(p) 326 327 def addPrinterFaxList(self): # printers=True, faxes=False): 328 widget = self.getWidget() 329 330 layout = QGridLayout(widget,1,1,5,10,"layout") 331 332 self.printernameTextLabel = QLabel(widget,"printernameTextLabel") 333 layout.addWidget(self.printernameTextLabel,0,0) 334 335 self.printerComboBox = QComboBox(0,widget,"printerComboBox") 336 layout.addWidget(self.printerComboBox,0,1) 337 338 #print self.cur_device.device_type 339 if self.cur_device.device_type == DEVICE_TYPE_PRINTER: 340 self.addGroupHeading("printer_list_heading", self.__tr("Printer")) 341 self.printernameTextLabel.setText(self.__tr("Printer Name:")) 342 else: 343 self.addGroupHeading("fax_list_heading", self.__tr("Fax")) 344 self.printernameTextLabel.setText(self.__tr("Fax Name:")) 345 346 self.printers = cups.getPrinters() 347 self.cur_printer = None 348 for p in self.printers: 349 if p.device_uri == self.cur_device.device_uri: 350 351 self.printerComboBox.insertItem(p.name) 352 353 if self.cur_printer is None: 354 self.cur_printer = p.name 355 356 if self.cur_printer is None: 357 #log.error("No fax queue found") 358 self.y = 0 359 self.clear() 360 361 #if printers and faxes: 362 if self.cur_device.device_type == DEVICE_TYPE_PRINTER: 363 self.addGroupHeading("error", self.__tr("ERROR: No CUPS queue found for device.")) 364 else: 365 self.addGroupHeading("error", self.__tr("ERROR: No CUPS fax queue found for device.")) 366 367 return False 368 369 else: 370 self.connect(self.printerComboBox, SIGNAL("activated(const QString&)"), self.printerComboBox_activated) 371 372 self.addWidget(widget, "printer_list") 373 return True 374 375 376 def addLoadPaper(self, paper_type=PAPER_TYPE_PLAIN): 377 self.addGroupHeading("load_paper", self.__tr("Load Paper")) 378 379 widget = self.getWidget() 380 layout1 = QGridLayout(widget, 1, 2, 5, 10,"layout1") 381 382 layout1.setColStretch(0, 1) 383 layout1.setColStretch(1, 10) 384 385 icon = QLabel(widget, "icon") 386 icon.setSizePolicy(QSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed, 0, 0, 387 icon.sizePolicy().hasHeightForWidth())) 388 389 icon.setScaledContents(1) 390 layout1.addWidget(icon, 0, 0) 391 392 textLabel = QLabel(widget, "textLabel") 393 textLabel.setAlignment(QLabel.WordBreak) 394 textLabel.setSizePolicy(QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Preferred, 0, 0, 395 textLabel.sizePolicy().hasHeightForWidth())) 396 textLabel.setFrameShape(self.frame_shape) 397 layout1.addWidget(textLabel, 0, 1) 398 399 spacer1 = QSpacerItem(20, 20, QSizePolicy.Expanding, QSizePolicy.Minimum) 400 layout1.addItem(spacer1, 0, 2) 401 402 if paper_type == PAPER_TYPE_PLAIN: 403 textLabel.setText(self.__tr("A page will be printed. Please load Letter/A4 <b>Plain Paper</b> into the printer.")) 404 elif paper_type == PAPER_TYPE_HP_ADV_PHOTO: 405 textLabel.setText(self.__tr("A page will be printed. Please load Letter/A4 <b>HP Advanced Photo Paper - Glossy</b> into the printer.")) 406 407 icon.setPixmap(load_pixmap("load_paper", 'other')) 408 409 self.addWidget(widget, "load_paper") 410 411 412 def cleanup(self): 413 pass 414 415 def __tr(self,s,c = None): 416 return qApp.translate("ScrollView",s,c) 417 418 419 420class PixmapLabelButton(QPushButton): 421 def __init__(self, parent=None, pixmap=None, disabled_pixmap=None, name='', subdir=None): 422 QPushButton.__init__(self, parent, name) 423 424 if subdir is None: 425 subdir = '16x16' 426 427 if type(pixmap) == type(''): 428 self.pixmap = load_pixmap(pixmap, subdir) 429 else: 430 self.pixmap = pixmap 431 432 if type(disabled_pixmap) == type(''): 433 self.disabled_pixmap = load_pixmap(disabled_pixmap, subdir) 434 else: 435 self.disabled_pixmap = disabled_pixmap 436 437 self.pixmap_width, self.pixmap_height = self.pixmap.width(), self.pixmap.height() 438 self.width_set = None 439 440 441 def drawButtonLabel(self, painter): 442 button_width, button_height = self.width(), self.height() 443 444 adj = 0 445 if self.isDown(): 446 adj = 1 447 448 if self.isEnabled(): 449 painter.setPen(Qt.black) 450 else: 451 painter.setPen(Qt.gray) 452 453 text_rect = painter.boundingRect(0, 0, 1000, 1000, Qt.AlignLeft, self.text()) 454 text_width, text_height = text_rect.right() - text_rect.left(), text_rect.bottom() - text_rect.top() 455 456 button_width_center = button_width/2 457 button_height_center = button_height/2 458 combined_width_center = (self.pixmap_width + text_width + 10)/2 459 460 461 if self.isEnabled() or self.disabled_pixmap is None: 462 painter.drawPixmap(button_width_center - combined_width_center + adj, 463 button_height_center - self.pixmap_height/2 + adj, self.pixmap) 464 else: 465 painter.drawPixmap(button_width_center - combined_width_center + adj, 466 button_height_center - self.pixmap_height/2 + adj, self.disabled_pixmap) 467 468 if self.width_set is None: 469 self.setMinimumWidth(self.pixmap_width + text_width + 20) 470 self.width_set = 0 471 472 painter.drawText(button_width_center - combined_width_center + 473 self.pixmap_width + 5 + adj, 474 button_height_center - text_height/2 + adj, 1000, 1000, 475 Qt.AlignLeft, self.text()) 476 477