class ScrollPrintView(ScrollView):
    utils.mixin(JobStorageMixin)

    def __init__(self, service, parent=None, form=None, name=None, fl=0):
        ScrollView.__init__(self, service, parent, name, fl)

        self.initJobStorage()

        self.form = form
        self.file_list = []
        self.pages_button_group = 0
        self.prev_selected_file_index = 0

        self.allowable_mime_types = cups.getAllowableMIMETypes()
        log.debug(self.allowable_mime_types)

        self.MIME_TYPES_DESC = \
        {
            "application/pdf" : (self.__tr("PDF Document"), '.pdf'),
            "application/postscript" : (self.__tr("Postscript Document"), '.ps'),
            "application/vnd.hp-HPGL" : (self.__tr("HP Graphics Language File"), '.hgl, .hpg, .plt, .prn'),
            "application/x-cshell" : (self.__tr("C Shell Script"), '.csh, .sh'),
            "application/x-csource" : (self.__tr("C Source Code"), '.c'),
            "text/cpp": (self.__tr("C++ Source Code"), '.cpp, .cxx'),
            "application/x-perl" : (self.__tr("Perl Script"), '.pl'),
            "application/x-python" : (self.__tr("Python Program"), '.py'),
            "application/x-shell" : (self.__tr("Shell Script"), '.sh'),
            "application/x-sh" : (self.__tr("Shell Script"), '.sh'),
            "text/plain" : (self.__tr("Plain Text"), '.txt, .log, etc'),
            "text/html" : (self.__tr("HTML Dcoument"), '.htm, .html'),
            "image/gif" : (self.__tr("GIF Image"), '.gif'),
            "image/png" : (self.__tr("PNG Image"), '.png'),
            "image/jpeg" : (self.__tr("JPEG Image"), '.jpg, .jpeg'),
            "image/tiff" : (self.__tr("TIFF Image"), '.tif, .tiff'),
            "image/x-bitmap" : (self.__tr("Bitmap (BMP) Image"), '.bmp'),
            "image/x-bmp" : (self.__tr("Bitmap (BMP) Image"), '.bmp'),
            "image/x-photocd" : (self.__tr("Photo CD Image"), '.pcd'),
            "image/x-portable-anymap" : (self.__tr("Portable Image (PNM)"), '.pnm'),
            "image/x-portable-bitmap" : (self.__tr("Portable B&W Image (PBM)"), '.pbm'),
            "image/x-portable-graymap" : (self.__tr("Portable Grayscale Image (PGM)"), '.pgm'),
            "image/x-portable-pixmap" : (self.__tr("Portable Color Image (PPM)"), '.ppm'),
            "image/x-sgi-rgb" : (self.__tr("SGI RGB"), '.rgb'),
            "image/x-xbitmap" : (self.__tr("X11 Bitmap (XBM)"), '.xbm'),
            "image/x-xpixmap" : (self.__tr("X11 Pixmap (XPM)"), '.xpm'),
            "image/x-sun-raster" : (self.__tr("Sun Raster Format"), '.ras'),
        }


    def fillControls(self):
        ScrollView.fillControls(self)

        if self.addPrinterFaxList():
            self.addGroupHeading("files_to_print", self.__tr("File(s) to Print"))
            self.addFileList()
            self.addGroupHeading("options", self.__tr("Print Options"))
            self.addCopies()
            self.addPageRange()
            self.addPageSet()

            self.job_storage_avail = self.cur_device.mq['job-storage'] == JOB_STORAGE_ENABLE

            if self.job_storage_avail:
                self.addGroupHeading("jobstorage", self.__tr("Job Storage and Secure Printing"))
                self.addJobStorage()

            self.addGroupHeading("space1", "")

            self.printButton = self.addActionButton("bottom_nav", self.__tr("Print File(s)"),
                                    self.printButton_clicked, 'print.png', 'print.png',
                                    self.__tr("Close"), self.funcButton_clicked)

            self.printButton.setEnabled(False)
            self.maximizeControl()

        else:
            QApplication.restoreOverrideCursor()
            self.form.FailureUI("<b>Print is disabled.</b><p>No CUPS print queue found for this device.")
            self.funcButton_clicked()


    def onUpdate(self, cur_device=None):
        log.debug("ScrollPrintView.onUpdate()")
        self.updateFileList()

    def onDeviceChange(self, cur_device=None):
        self.file_list = []
        ScrollView.onDeviceChange(self, cur_device)

    def addFileList(self):
        widget = self.getWidget()
        layout37 = QGridLayout(widget,1,1,5,10,"layout37")

        self.addFilePushButton = PixmapLabelButton(widget,
            "list_add.png", "list_add.png")

        layout37.addWidget(self.addFilePushButton,2,0)

        self.removeFilePushButton = PixmapLabelButton(widget,
            "list_remove.png", "list_remove.png")

        layout37.addWidget(self.removeFilePushButton,2,1)

        self.moveFileUpPushButton = PixmapLabelButton(widget, "up.png",
            "up.png", name='moveFileUpPushButton')

        layout37.addWidget(self.moveFileUpPushButton,2,2)

        self.moveFileDownPushButton = PixmapLabelButton(widget, "down.png",
            "down.png", name='moveFileDownPushButton')

        layout37.addWidget(self.moveFileDownPushButton,2,3)

        self.showTypesPushButton = PixmapLabelButton(widget, "mimetypes.png",
            None, name='addFilePushButton')

        layout37.addWidget(self.showTypesPushButton,2,5)
        self.fileListView = QListView(widget,"fileListView")
        self.fileListView.addColumn(self.__tr("Order"))
        self.fileListView.addColumn(self.__tr("Name"))
        self.fileListView.addColumn(self.__tr("Type"))
        self.fileListView.addColumn(self.__tr("Path"))
        self.fileListView.setAllColumnsShowFocus(1)
        self.fileListView.setShowSortIndicator(1)
        self.fileListView.setColumnWidth(0, 100)
        self.fileListView.setColumnWidth(1, 150)
        self.fileListView.setColumnWidth(2, 75)
        self.fileListView.setColumnWidth(3, 300)
        self.fileListView.setItemMargin(2)
        self.fileListView.setSorting(-1)

        layout37.addMultiCellWidget(self.fileListView,1,1,0,5)

        spacer26 = QSpacerItem(20,20,QSizePolicy.Expanding,QSizePolicy.Minimum)
        layout37.addItem(spacer26,2,4)

        self.addFilePushButton.setText(self.__tr("Add File..."))
        self.showTypesPushButton.setText(self.__tr("Show Types..."))
        self.removeFilePushButton.setText(self.__tr("Remove File"))
        self.moveFileDownPushButton.setText(self.__tr("Move Down"))
        self.moveFileUpPushButton.setText(self.__tr("Move Up"))

        self.removeFilePushButton.setEnabled(False)
        self.moveFileDownPushButton.setEnabled(False)
        self.moveFileUpPushButton.setEnabled(False)

        self.connect(self.addFilePushButton, SIGNAL("clicked()"), self.addFile_clicked)
        self.connect(self.removeFilePushButton, SIGNAL("clicked()"), self.removeFile_clicked)
        self.connect(self.showTypesPushButton, SIGNAL("clicked()"), self.showFileTypes_clicked)
        self.connect(self.fileListView,SIGNAL("rightButtonClicked(QListViewItem*,const QPoint&, int)"),self.fileListView_rightButtonClicked)

        self.connect(self.moveFileUpPushButton, SIGNAL("clicked()"), self.moveFileUp_clicked)
        self.connect(self.moveFileDownPushButton, SIGNAL("clicked()"), self.moveFileDown_clicked)
        self.connect(self.fileListView, SIGNAL("selectionChanged(QListViewItem*)"),
            self.fileListView_selectionChanged)

        self.addWidget(widget, "file_list", maximize=True)

    def fileListView_selectionChanged(self, i):
        try:
            self.prev_selected_file_index = i.index
        except AttributeError:
            pass
        else:
            flv = self.fileListView
            selected_item = flv.selectedItem()
            file_count = flv.childCount()
            last_item = flv.firstChild()
            while last_item.nextSibling():
                last_item = last_item.nextSibling()

            self.moveFileDownPushButton.setEnabled(file_count > 1 and selected_item is not last_item)
            self.moveFileUpPushButton.setEnabled(file_count > 1 and selected_item is not flv.firstChild())

    def fileListView_rightButtonClicked(self, item, pos, col):
        popup = QPopupMenu(self)
        popup.insertItem(QIconSet(load_pixmap('list_add', '16x16')),
            self.__tr("Add File..."), self.addFile_clicked)

        if item is not None:
            popup.insertItem(QIconSet(load_pixmap('list_remove', '16x16')),
                self.__tr("Remove File"), self.removeFile_clicked)

            if self.fileListView.childCount() > 1:
                last_item = self.fileListView.firstChild()
                while last_item is not None and last_item.nextSibling():
                    last_item = last_item.nextSibling()

                if item is not self.fileListView.firstChild():
                    popup.insertItem(QIconSet(load_pixmap('up', '16x16')),
                        self.__tr("Move Up"), self.moveFileUp_clicked)

                if item is not last_item:
                    popup.insertItem(QIconSet(load_pixmap('down', '16x16')),
                        self.__tr("Move Down"), self.moveFileDown_clicked)

        popup.insertSeparator(-1)
        popup.insertItem(QIconSet(load_pixmap('mimetypes', '16x16')),
            self.__tr("Show File Types..."), self.showFileTypes_clicked)

        popup.popup(pos)

    def moveFileUp_clicked(self):
        log.debug("Move file up")
        try:
            item = self.fileListView.selectedItem()
            path, index = item.path, item.index
        except AttributeError:
            return
        else:
            new_pos = index-1
            self.file_list[new_pos], self.file_list[index] = self.file_list[index], self.file_list[new_pos]
            item.index = new_pos
            self.prev_selected_file_index = new_pos
            self.updateFileList()

    def moveFileDown_clicked(self):
        log.debug("Move file down")
        try:
            item = self.fileListView.selectedItem()
            path, index = item.path, item.index
        except AttributeError:
            return
        else:
            new_pos = index+1
            self.file_list[index], self.file_list[new_pos] = self.file_list[new_pos], self.file_list[index]
            item.index = new_pos
            self.prev_selected_file_index = new_pos
            self.updateFileList()

    def addFile(self, path):
        path = os.path.realpath(path)
        if os.path.exists(path) and os.access(path, os.R_OK):
            mime_type = magic.mime_type(path)
            mime_type_desc = mime_type
            log.debug(mime_type)

            try:
                mime_type_desc = self.MIME_TYPES_DESC[mime_type][0]
            except KeyError:
                self.form.FailureUI(self.__tr("<b>You are trying to add a file that cannot be directly printed with this utility.</b><p>To print this file, use the print command in the application that created it."))
            else:
                log.debug("Adding file %s (%s,%s)" % (path, mime_type, mime_type_desc))
                self.file_list.append((path, mime_type, mime_type_desc))
        else:
            self.form.FailureUI(self.__tr("<b>Unable to add file '%1' to file list (file not found or insufficient permissions).</b><p>Check the file name and try again.").arg(path))

        self.updateFileList()

    def updateFileList(self):
        self.fileListView.clear()
        temp = self.file_list[:]
        temp.reverse()
        last_item = None
        selected_item = None
        index = len(temp)-1

        for path, mime_type, desc in temp:
            log.debug("path=%s, mime_type=%s, desc=%s, index=%d" % (path, mime_type, desc, index))
            i = FileListViewItem(self.fileListView, index, os.path.basename(path), desc, path)

            if self.prev_selected_file_index == index:
                self.fileListView.setSelected(i, True)
                self.prev_selected_file_index = index
                selected_item = i

            index -= 1

        last_item = self.fileListView.firstChild()
        while last_item is not None and last_item.nextSibling():
            last_item = last_item.nextSibling()

        file_count = self.fileListView.childCount()
        self.moveFileDownPushButton.setEnabled(file_count > 1 and selected_item is not last_item)
        self.moveFileUpPushButton.setEnabled(file_count > 1 and selected_item is not self.fileListView.firstChild())
        self.removeFilePushButton.setEnabled(file_count > 0)
        self.printButton.setEnabled(file_count > 0)

    def addFile_clicked(self):
        dlg = QFileDialog(user_conf.workingDirectory(), QString.null, None, None, True)

        dlg.setCaption("openfile")
        dlg.setMode(QFileDialog.ExistingFile)
        dlg.show()

        if dlg.exec_loop() == QDialog.Accepted:
                results = dlg.selectedFile()
                working_directory = unicode(dlg.dir().absPath())
                log.debug("results: %s" % results)
                user_conf.setWorkingDirectory(working_directory)

                if results:
                    self.addFile(unicode(results))

    def removeFile_clicked(self):
        try:
            path = self.fileListView.selectedItem().path
        except AttributeError:
            return
        else:
            temp = self.file_list[:]
            index = 0
            for p, t, d in temp:
                if p == path:
                    del self.file_list[index]
                    if index == self.prev_selected_file_index:
                        self.prev_selected_file_index = 0
                    break
                index += 1

            self.updateFileList()

    def showFileTypes_clicked(self):
        x = {}
        for a in self.allowable_mime_types:
            x[a] = self.MIME_TYPES_DESC.get(a, ('Unknown', 'n/a'))

        log.debug(x)
        dlg = AllowableTypesDlg(x, self)
        dlg.exec_loop()


    def addCopies(self):
        widget = self.getWidget()

        layout12 = QHBoxLayout(widget,5,10,"layout12")

        self.textLabel5 = QLabel(widget,"textLabel5")
        layout12.addWidget(self.textLabel5)
        spacer20 = QSpacerItem(20,20,QSizePolicy.Expanding,QSizePolicy.Minimum)
        layout12.addItem(spacer20)

        self.copiesSpinBox = QSpinBox(widget,"copiesSpinBox")
        layout12.addWidget(self.copiesSpinBox)

        self.copiesDefaultPushButton = QPushButton(widget,"copiesDefaultPushButton")
        layout12.addWidget(self.copiesDefaultPushButton)

        self.textLabel5.setText(self.__tr("Number of copies:"))
        self.copiesDefaultPushButton.setText(self.__tr("Default"))

        self.copiesSpinBox.setMaxValue(99)
        self.copiesSpinBox.setMinValue(1)
        self.copiesSpinBox.setValue(1)

        self.copiesDefaultPushButton.setEnabled(False)

        self.connect(self.copiesDefaultPushButton, SIGNAL("clicked()"), self.copiesDefaultPushButton_clicked)
        self.connect(self.copiesSpinBox, SIGNAL("valueChanged(int)"), self.copiesSpinBox_valueChanged)

        self.addWidget(widget, "copies")

    def copiesDefaultPushButton_clicked(self):
        self.copiesSpinBox.setValue(1)
        self.copiesDefaultPushButton.setEnabled(False)

    def copiesSpinBox_valueChanged(self, i):
        self.copiesDefaultPushButton.setEnabled(i != 1)

    def addPageRange(self):
        widget = self.getWidget()

        layout39 = QGridLayout(widget,1,1,5,10,"layout39")

        self.pageRangeEdit = QLineEdit(widget,"self.pageRangeEdit")
        self.pageRangeEdit.setEnabled(0)
        layout39.addWidget(self.pageRangeEdit,0,3)

        spacer20_2 = QSpacerItem(20,20,QSizePolicy.Expanding,QSizePolicy.Minimum)
        layout39.addItem(spacer20_2,0,1)

        textLabel5_2 = QLabel(widget,"textLabel5_2")
        layout39.addWidget(textLabel5_2,0,0)

        self.pagerangeDefaultPushButton = QPushButton(widget,"pagerangeDefaultPushButton")
        layout39.addWidget(self.pagerangeDefaultPushButton,0,4)

        self.rangeButtonGroup = QButtonGroup(widget,"self.rangeButtonGroup")
        self.rangeButtonGroup.setLineWidth(0)
        self.rangeButtonGroup.setColumnLayout(0,Qt.Vertical)
        self.rangeButtonGroup.layout().setSpacing(0)
        self.rangeButtonGroup.layout().setMargin(0)
        self.rangeButtonGroupLayout = QGridLayout(self.rangeButtonGroup.layout())
        self.rangeButtonGroupLayout.setAlignment(Qt.AlignTop)

        radioButton3_2 = QRadioButton(self.rangeButtonGroup,"radioButton3_2")
        radioButton3_2.setChecked(1)
        self.rangeButtonGroup.insert( radioButton3_2,0)
        self.rangeButtonGroupLayout.addWidget(radioButton3_2,0,0)

        radioButton4_2 = QRadioButton(self.rangeButtonGroup,"radioButton4_2")
        self.rangeButtonGroup.insert( radioButton4_2,1)
        self.rangeButtonGroupLayout.addWidget(radioButton4_2,0,1)

        layout39.addWidget(self.rangeButtonGroup,0,2)

        self.bg = self.pageRangeEdit.paletteBackgroundColor()
        self.invalid_page_range = False

        self.pageRangeEdit.setValidator(RangeValidator(self.pageRangeEdit))

        textLabel5_2.setText(self.__tr("Page Range:"))
        radioButton3_2.setText(self.__tr("All pages"))
        radioButton4_2.setText(self.__tr("Page range:"))

        self.pagerangeDefaultPushButton.setText(self.__tr("Default"))

        self.pagerangeDefaultPushButton.setEnabled(False)

        self.connect(self.rangeButtonGroup, SIGNAL("clicked(int)"), self.rangeButtonGroup_clicked)
        self.connect(self.pageRangeEdit,SIGNAL("lostFocus()"),self.pageRangeEdit_lostFocus)
        self.connect(self.pageRangeEdit,SIGNAL("textChanged(const QString&)"),self.pageRangeEdit_textChanged)
        self.connect(self.pagerangeDefaultPushButton, SIGNAL("clicked()"), self.pagerangeDefaultPushButton_clicked)

        self.addWidget(widget, "range")

    def pagerangeDefaultPushButton_clicked(self):
        self.rangeButtonGroup.setButton(0)
        self.pagerangeDefaultPushButton.setEnabled(False)
        self.pageRangeEdit.setEnabled(False)

    def rangeButtonGroup_clicked(self, a0):
        self.pages_button_group = a0
        self.pageRangeEdit.setEnabled(a0 == 1)
        self.pagerangeDefaultPushButton.setEnabled(a0 == 1)

    def pageRangeEdit_lostFocus(self):
        x = []
        try:
            x = utils.expand_range(unicode(self.pageRangeEdit.text()))
        except ValueError:
            log.error("Invalid page range entered.")
            self.invalid_page_range = True
            self.pageRangeEdit.setPaletteBackgroundColor(QColor(0xff, 0x99, 0x99))

        else:
            self.pageRangeEdit.setText(QString(utils.collapse_range(x)))
            self.pageRangeEdit.setPaletteBackgroundColor(self.bg)
            self.invalid_page_range = False

    def pageRangeEdit_textChanged(self,a0):
        x = []
        try:
            x = utils.expand_range(str(self.pageRangeEdit.text()))
        except ValueError:
            self.invalid_page_range = True
            self.pageRangeEdit.setPaletteBackgroundColor(QColor(0xff, 0x99, 0x99))

        else:
            self.pageRangeEdit.setPaletteBackgroundColor(self.bg)
            self.invalid_page_range = False

    def addPageSet(self):
        widget = self.getWidget()

        layout34 = QHBoxLayout(widget,5,10,"layout34")

        self.textLabel5_4 = QLabel(widget,"textLabel5_4")
        layout34.addWidget(self.textLabel5_4)
        spacer20_4 = QSpacerItem(20,20,QSizePolicy.Expanding,QSizePolicy.Minimum)
        layout34.addItem(spacer20_4)

        self.pageSetComboBox = QComboBox(0,widget,"pageSetComboBox")
        layout34.addWidget(self.pageSetComboBox)

        self.pagesetDefaultPushButton = QPushButton(widget,"pagesetDefaultPushButton")
        layout34.addWidget(self.pagesetDefaultPushButton)

        self.textLabel5_4.setText(self.__tr("Page set:"))
        self.pageSetComboBox.clear()
        self.pageSetComboBox.insertItem(self.__tr("All pages"))
        self.pageSetComboBox.insertItem(self.__tr("Even pages"))
        self.pageSetComboBox.insertItem(self.__tr("Odd pages"))
        self.pagesetDefaultPushButton.setText(self.__tr("Default"))

        self.pagesetDefaultPushButton.setEnabled(False)

        self.connect(self.pageSetComboBox, SIGNAL("activated(int)"), self.pageSetComboBox_activated)
        self.connect(self.pagesetDefaultPushButton, SIGNAL("clicked()"), self.pagesetDefaultPushButton_clicked)

        self.addWidget(widget, "set")

    def pagesetDefaultPushButton_clicked(self):
        self.pagesetDefaultPushButton.setEnabled(False)
        self.pageSetComboBox.setCurrentItem(0)

    def pageSetComboBox_activated(self, i):
        self.pagesetDefaultPushButton.setEnabled(i != 0)

##    #
##    # JOB STORAGE
##    #
##
##    def addJobStorage(self):
##        self.addJobStorageMode()
##        self.addJobStoragePIN()
##        self.addJobStorageUsername()
##        self.addJobStorageID()
##        self.addJobStorageIDExists()
##        self.jobStorageDisable()
##
##
##    def addJobStorageMode(self):
##        widget = self.getWidget()
##
##        layout34 = QHBoxLayout(widget,5,10,"layout34")
##
##        self.jobStorageModeLabel = QLabel(widget,"jobStorageModeLabel")
##        layout34.addWidget(self.jobStorageModeLabel)
##        spacer20_4 = QSpacerItem(20,20,QSizePolicy.Expanding,QSizePolicy.Minimum)
##        layout34.addItem(spacer20_4)
##
##        self.jobStorageModeComboBox = QComboBox(0,widget,"jobStorageModeComboBox")
##        layout34.addWidget(self.jobStorageModeComboBox)
##
##        self.jobStorageModeDefaultPushButton = QPushButton(widget,"pagesetDefaultPushButton")
##        layout34.addWidget(self.jobStorageModeDefaultPushButton)
##
##        self.jobStorageModeLabel.setText(self.__tr("Job Storage Mode:"))
##        self.jobStorageModeComboBox.clear()
##        self.jobStorageModeComboBox.insertItem(self.__tr("Off"))
##        self.jobStorageModeComboBox.insertItem(self.__tr("Proof and Hold"))
##        self.jobStorageModeComboBox.insertItem(self.__tr("Personal/Private Job"))
##        self.jobStorageModeComboBox.insertItem(self.__tr("Quick Copy"))
##        self.jobStorageModeComboBox.insertItem(self.__tr("Stored Job"))
##
##        self.jobStorageModeDefaultPushButton.setText(self.__tr("Default"))
##        self.jobStorageModeDefaultPushButton.setEnabled(False)
##
##        self.connect(self.jobStorageModeComboBox, SIGNAL("activated(int)"), self.jobStorageModeComboBox_activated)
##        self.connect(self.jobStorageModeDefaultPushButton, SIGNAL("clicked()"), self.jobStorageModeDefaultPushButton_clicked)
##
##        self.addWidget(widget, "job_storage_mode")
##
##    def jobStorageModeComboBox_activated(self, a):
##        self.job_storage_mode = a
##
##        if a == 0: # Off
##            self.jobStorageDisable()
##
##        elif a == 1: # Proof and Hold
##            self.jobStorageModeDefaultPushButton.setEnabled(True)
##            self.jobStorageUserJobEnable(True)
##            self.jobStoragePINEnable(False)
##
##        elif a == 2: # Private Job
##            self.jobStorageModeDefaultPushButton.setEnabled(True)
##            self.jobStoragePINEnable(True)
##            self.jobStorageUserJobEnable(True)
##
##        elif a == 3: # Quick Copy
##            self.jobStorageModeDefaultPushButton.setEnabled(True)
##            self.jobStoragePINEnable(False)
##            self.jobStorageUserJobEnable(True)
##
##        elif a == 4: # Stored Job
##            self.jobStorageModeDefaultPushButton.setEnabled(True)
##            self.jobStoragePINEnable(True) # ???
##            self.jobStorageUserJobEnable(True)
##
##    def jobStorageModeDefaultPushButton_clicked(self):
##        self.jobStorageModeComboBox.setCurrentItem(0)
##        self.job_storage_mode = 0
##
##    def jobStorageDisable(self): # Turn all Off
##        self.jobStorageModeDefaultPushButton.setEnabled(False)
##        self.jobStoragePINEnable(False)
##        self.jobStorageUserJobEnable(False)
##
##    def jobStoragePINEnable(self, e=True): # PIN On/Off
##        t = e and self.jobStoragePINButtonGroup.selectedId() == 1
##        self.jobStoragePINButtonGroup.setEnabled(e)
##        self.jobStoragePINEdit.setEnabled(t)
##        self.jobStoragePINDefaultPushButton.setEnabled(t)
##
##    def jobStorageUserJobEnable(self, e=True): # Username/Job ID/Job ID Exists On/Off
##        t = e and self.jobStorageUsernameButtonGroup.selectedId() == 1
##        self.jobStorageUsernameButtonGroup.setEnabled(e)
##        self.jobStorageUsernameDefaultPushButton.setEnabled(t)
##        self.jobStorageUsernameEdit.setEnabled(t)
##
##        t = e and self.jobStorageIDButtonGroup.selectedId() == 1
##        self.jobStorageIDButtonGroup.setEnabled(e)
##        self.jobStorageIDDefaultPushButton.setEnabled(t)
##        self.jobStorageIDEdit.setEnabled(t)
##
##        t = e and self.jobStorageIDExistsComboBox.currentItem() == 1
##        self.jobStorageIDExistsComboBox.setEnabled(e)
##        self.jobStorageIDExistsDefaultPushButton.setEnabled(t)
##
##
##
##    # PIN
##
##
##    def addJobStoragePIN(self):
##        widget = self.getWidget()
##
##        layout39 = QGridLayout(widget,1,1,5,10,"layout39")
##
##        self.jobStoragePINEdit = QLineEdit(widget,"self.jobStoragePINEdit")
##        self.jobStoragePINEdit.setMaxLength(4)
##        self.jobStoragePINEdit.setText(self.job_storage_pin)
##        layout39.addWidget(self.jobStoragePINEdit,0,3)
##
##        spacer20_2 = QSpacerItem(20,20,QSizePolicy.Expanding,QSizePolicy.Minimum)
##        layout39.addItem(spacer20_2,0,1)
##
##        textLabel5_2 = QLabel(widget,"textLabel5_2")
##        layout39.addWidget(textLabel5_2,0,0)
##
##        self.jobStoragePINDefaultPushButton = QPushButton(widget,"jobStoragePINDefaultPushButton")
##        layout39.addWidget(self.jobStoragePINDefaultPushButton,0,4)
##
##        self.jobStoragePINButtonGroup = QButtonGroup(widget,"self.jobStoragePINButtonGroup")
##        self.jobStoragePINButtonGroup.setLineWidth(0)
##        self.jobStoragePINButtonGroup.setColumnLayout(0,Qt.Vertical)
##        self.jobStoragePINButtonGroup.layout().setSpacing(0)
##        self.jobStoragePINButtonGroup.layout().setMargin(0)
##        self.jobStoragePINButtonGroupLayout = QGridLayout(self.jobStoragePINButtonGroup.layout())
##        self.jobStoragePINButtonGroupLayout.setAlignment(Qt.AlignTop)
##
##        radioButton3_2 = QRadioButton(self.jobStoragePINButtonGroup,"radioButton3_2")
##        radioButton3_2.setChecked(1)
##        self.jobStoragePINButtonGroup.insert( radioButton3_2,0)
##        self.jobStoragePINButtonGroupLayout.addWidget(radioButton3_2,0,0)
##
##        radioButton4_2 = QRadioButton(self.jobStoragePINButtonGroup,"radioButton4_2")
##        self.jobStoragePINButtonGroup.insert( radioButton4_2,1)
##        self.jobStoragePINButtonGroupLayout.addWidget(radioButton4_2,0,1)
##
##        layout39.addWidget(self.jobStoragePINButtonGroup,0,2)
##
##        self.bg = self.jobStoragePINEdit.paletteBackgroundColor()
##        self.invalid_page_range = False
##
##        self.jobStoragePINEdit.setValidator(PINValidator(self.jobStoragePINEdit))
##
##        textLabel5_2.setText(self.__tr("Make Job Private (use PIN to print):"))
##        radioButton3_2.setText(self.__tr("Public/Off"))
##        radioButton4_2.setText(self.__tr("Private/Use PIN to Print:"))
##
##        self.jobStoragePINDefaultPushButton.setText(self.__tr("Default"))
##
##        self.connect(self.jobStoragePINButtonGroup, SIGNAL("clicked(int)"), self.jobStoragePINButtonGroup_clicked)
##        self.connect(self.jobStoragePINEdit,SIGNAL("lostFocus()"),self.jobStoragePINEdit_lostFocus)
##        self.connect(self.jobStoragePINEdit,SIGNAL("textChanged(const QString&)"),self.jobStoragePINEdit_textChanged)
##        self.connect(self.jobStoragePINDefaultPushButton, SIGNAL("clicked()"), self.jobStoragePINDefaultPushButton_clicked)
##
##        self.addWidget(widget, "job_storage_pin")
##
##    def jobStoragePINButtonGroup_clicked(self, a):
##        if a == 0: # Public/Off
##            self.jobStoragePINDefaultPushButton.setEnabled(False)
##            self.jobStoragePINEdit.setEnabled(False)
##            self.job_storage_use_pin = False
##            self.job_storage_pin = u"0000"
##
##        else: # On/Private/Use PIN
##            self.jobStoragePINDefaultPushButton.setEnabled(True)
##            self.jobStoragePINEdit.setEnabled(True)
##            self.job_storage_use_pin = True
##            self.job_storage_pin = unicode(self.jobStoragePINEdit.text())
##
##    def jobStoragePINEdit_lostFocus(self):
##        pafss
##
##    def jobStoragePINEdit_textChanged(self, a):
##        self.job_storage_pin = unicode(a)
##
##    def jobStoragePINDefaultPushButton_clicked(self):
##        self.jobStoragePINButtonGroup.setButton(0)
##        self.jobStoragePINDefaultPushButton.setEnabled(False)
##        self.jobStoragePINEdit.setEnabled(False)
##        self.job_storage_use_pin = False
##
##    # Username
##
##    def addJobStorageUsername(self):
##        widget = self.getWidget()
##
##        layout39 = QGridLayout(widget,1,1,5,10,"layout39")
##
##        self.jobStorageUsernameEdit = QLineEdit(widget,"self.jobStorageUsernameEdit")
##        self.jobStorageUsernameEdit.setMaxLength(16)
##        self.jobStorageUsernameEdit.setText(self.job_storage_username)
##        layout39.addWidget(self.jobStorageUsernameEdit,0,3)
##
##        spacer20_2 = QSpacerItem(20,20,QSizePolicy.Expanding,QSizePolicy.Minimum)
##        layout39.addItem(spacer20_2,0,1)
##
##        textLabel5_2 = QLabel(widget,"textLabel5_2")
##        layout39.addWidget(textLabel5_2,0,0)
##
##        self.jobStorageUsernameDefaultPushButton = QPushButton(widget,"jobStorageUsernameDefaultPushButton")
##        layout39.addWidget(self.jobStorageUsernameDefaultPushButton,0,4)
##
##        self.jobStorageUsernameButtonGroup = QButtonGroup(widget,"self.jobStorageUsernameButtonGroup")
##        self.jobStorageUsernameButtonGroup.setLineWidth(0)
##        self.jobStorageUsernameButtonGroup.setColumnLayout(0,Qt.Vertical)
##        self.jobStorageUsernameButtonGroup.layout().setSpacing(0)
##        self.jobStorageUsernameButtonGroup.layout().setMargin(0)
##        self.jobStorageUsernameButtonGroupLayout = QGridLayout(self.jobStorageUsernameButtonGroup.layout())
##        self.jobStorageUsernameButtonGroupLayout.setAlignment(Qt.AlignTop)
##
##        radioButton3_2 = QRadioButton(self.jobStorageUsernameButtonGroup,"radioButton3_2")
##        radioButton3_2.setChecked(1)
##        self.jobStorageUsernameButtonGroup.insert( radioButton3_2,0)
##        self.jobStorageUsernameButtonGroupLayout.addWidget(radioButton3_2,0,0)
##
##        radioButton4_2 = QRadioButton(self.jobStorageUsernameButtonGroup,"radioButton4_2")
##        self.jobStorageUsernameButtonGroup.insert( radioButton4_2,1)
##        self.jobStorageUsernameButtonGroupLayout.addWidget(radioButton4_2,0,1)
##
##        layout39.addWidget(self.jobStorageUsernameButtonGroup,0,2)
##
##        self.bg = self.jobStorageUsernameEdit.paletteBackgroundColor()
##        self.invalid_page_range = False
##
##        self.jobStorageUsernameEdit.setValidator(TextValidator(self.jobStorageUsernameEdit))
##
##        textLabel5_2.setText(self.__tr("User name (for job identification):"))
##        radioButton3_2.setText(self.__tr("Automatic"))
##        radioButton4_2.setText(self.__tr("Custom:"))
##
##        self.jobStorageUsernameDefaultPushButton.setText(self.__tr("Default"))
##
##        self.connect(self.jobStorageUsernameButtonGroup, SIGNAL("clicked(int)"), self.jobStorageUsernameButtonGroup_clicked)
##        self.connect(self.jobStorageUsernameEdit,SIGNAL("lostFocus()"),self.jobStorageUsernameEdit_lostFocus)
##        self.connect(self.jobStorageUsernameEdit,SIGNAL("textChanged(const QString&)"),self.jobStorageUsernameEdit_textChanged)
##        self.connect(self.jobStorageUsernameDefaultPushButton, SIGNAL("clicked()"), self.jobStorageUsernameDefaultPushButton_clicked)
##
##        self.addWidget(widget, "job_storage_username")
##
##    def jobStorageUsernameButtonGroup_clicked(self, a):
##        if a == 0: # Automatic
##            self.jobStorageUsernameDefaultPushButton.setEnabled(False)
##            self.jobStorageUsernameEdit.setEnabled(False)
##            self.job_storage_auto_username = True
##            self.job_storage_username = unicode(prop.username[:16])
##
##        else: # Custom
##            self.jobStorageUsernameDefaultPushButton.setEnabled(True)
##            self.jobStorageUsernameEdit.setEnabled(True)
##            self.job_storage_auto_username = False
##            self.job_storage_username = unicode(self.jobStorageUsernameEdit.text())
##
##    def jobStorageUsernameEdit_lostFocus(saddJobStorageIDelf):
##        pass
##
##    def jobStorageUsernameEdit_textChanged(self, a):
##        self.job_storage_username = unicode(a)
##
##    def jobStorageUsernameDefaultPushButton_clicked(self):
##        self.jobStorageUsernameButtonGroup.setButton(0)
##        self.jobStorageUsernameDefaultPushButton.setEnabled(False)
##        self.jobStorageUsernameEdit.setEnabled(False)
##        self.job_storage_auto_username = True
##        self.job_storage_username = unicode(prop.username[:16])
##
##    # Job ID
##
##    def addJobStorageID(self):
##        widget = self.getWidget()
##
##        layout39 = QGridLayout(widget,1,1,5,10,"layout39")
##
##        self.jobStorageIDEdit = QLineEdit(widget,"self.jobStorageIDEdit")
##        self.jobStorageIDEdit.setMaxLength(16)
##        self.jobStorageIDEdit.setText(self.job_storage_jobname)
##        layout39.addWidget(self.jobStorageIDEdit,0,3)
##
##        spacer20_2 = QSpacerItem(20,20,QSizePolicy.Expanding,QSizePolicy.Minimum)
##        layout39.addItem(spacer20_2,0,1)
##
##        textLabel5_2 = QLabel(widget,"textLabel5_2")
##        layout39.addWidget(textLabel5_2,0,0)
##
##        self.jobStorageIDDefaultPushButton = QPushButton(widget,"jobStorageIDDefaultPushButton")
##        layout39.addWidget(self.jobStorageIDDefaultPushButton,0,4)
##
##        self.jobStorageIDButtonGroup = QButtonGroup(widget,"self.jobStorageIDButtonGroup")
##        self.jobStorageIDButtonGroup.setLineWidth(0)
##        self.jobStorageIDButtonGroup.setColumnLayout(0,Qt.Vertical)
##        self.jobStorageIDButtonGroup.layout().setSpacing(0)
##        self.jobStorageIDButtonGroup.layout().setMargin(0)
##        self.jobStorageIDButtonGroupLayout = QGridLayout(self.jobStorageIDButtonGroup.layout())
##        self.jobStorageIDButtonGroupLayout.setAlignment(Qt.AlignTop)
##
##        radioButton3_2 = QRadioButton(self.jobStorageIDButtonGroup,"radioButton3_2")
##        radioButton3_2.setChecked(1)
##        self.jobStorageIDButtonGroup.insert( radioButton3_2,0)
##        self.jobStorageIDButtonGroupLayout.addWidget(radioButton3_2,0,0)
##
##        radioButton4_2 = QRadioButton(self.jobStorageIDButtonGroup,"radioButton4_2")
##        self.jobStorageIDButtonGroup.insert( radioButton4_2,1)
##        self.jobStorageIDButtonGroupLayout.addWidget(radioButton4_2,0,1)
##
##        layout39.addWidget(self.jobStorageIDButtonGroup,0,2)
##
##        self.bg = self.jobStorageIDEdit.paletteBackgroundColor()
##        self.invalid_page_range = False
##
##        self.jobStorageIDEdit.setValidator(TextValidator(self.jobStorageIDEdit))
##
##        textLabel5_2.setText(self.__tr("Job name (for job identification):"))
##        radioButton3_2.setText(self.__tr("Automatic"))
##        radioButton4_2.setText(self.__tr("Custom:"))
##
##        self.jobStorageIDDefaultPushButton.setText(self.__tr("Default"))
##
##        self.connect(self.jobStorageIDButtonGroup, SIGNAL("clicked(int)"), self.jobStorageIDButtonGroup_clicked)
##        self.connect(self.jobStorageIDEdit,SIGNAL("lostFocus()"),self.jobStorageIDEdit_lostFocus)
##        self.connect(self.jobStorageIDEdit,SIGNAL("textChanged(const QString&)"),self.jobStorageIDEdit_textChanged)
##        self.connect(self.jobStorageIDDefaultPushButton, SIGNAL("clicked()"), self.jobStorageIDDefaultPushButton_clicked)
##
##        self.addWidget(widget, "job_storage_ID")
##
##    def jobStorageIDButtonGroup_clicked(self, a):
##        if a == 0: # Automatic
##            self.jobStorageIDDefaultPushButton.setEnabled(False)
##            self.jobStorageIDEdit.setEnabled(False)
##            self.job_storage_auto_jobname = True
##            self.job_storage_jobname = unicode(time.strftime("%a, %d %b %Y %H:%M:%S"))
##
##        else: # Custom
##            self.jobStorageIDDefaultPushButton.setEnabled(True)
##            self.jobStorageIDEdit.setEnabled(True)
##            self.job_storage_auto_jobname = False
##            self.job_storage_jobname = unicode(self.jobStorageIDEdit.text())
##
##    def jobStorageIDEdit_lostFocus(self):
##        pass
##
##    def jobStorageIDEdit_textChanged(self, a):
##        self.job_storage_jobname = unicode(a)
##
##    def jobStorageIDDefaultPushButton_clicked(self):
##        self.jobStorageIDButtonGroup.setButton(0)
##        self.jobStorageIDDefaultPushButton.setEnabled(False)
##        self.jobStorageIDEdit.setEnabled(False)
##        self.job_storage_auto_jobname = True
##        self.job_storage_jobname = unicode(time.strftime("%a, %d %b %Y %H:%M:%S"))
##
##    # Job ID Exists
##
##    def addJobStorageIDExists(self):
##        widget = self.getWidget()
##
##        layout34 = QHBoxLayout(widget,5,10,"layout34")
##
##        self.jobStorageIDExistsLabel = QLabel(widget,"jobStorageIDExistsLabel")
##        layout34.addWidget(self.jobStorageIDExistsLabel)
##        spacer20_4 = QSpacerItem(20,20,QSizePolicy.Expanding,QSizePolicy.Minimum)
##        layout34.addItem(spacer20_4)
##
##        self.jobStorageIDExistsComboBox = QComboBox(0,widget,"jobStorageIDExistsComboBox")
##        layout34.addWidget(self.jobStorageIDExistsComboBox)
##
##        self.jobStorageIDExistsDefaultPushButton = QPushButton(widget,"pagesetDefaultPushButton")
##        layout34.addWidget(self.jobStorageIDExistsDefaultPushButton)
##
##        self.jobStorageIDExistsLabel.setText(self.__tr("If Job Name already exists:"))
##        self.jobStorageIDExistsComboBox.clear()
##        self.jobStorageIDExistsComboBox.insertItem(self.__tr("Replace existing job"))
##        self.jobStorageIDExistsComboBox.insertItem(self.__tr("Use Job Name + (1-99)"))
##
##        self.jobStorageIDExistsDefaultPushButton.setText(self.__tr("Default"))
##
##        self.connect(self.jobStorageIDExistsComboBox, SIGNAL("activated(int)"), self.jobStorageIDExistsComboBox_activated)
##        self.connect(self.jobStorageIDExistsDefaultPushButton, SIGNAL("clicked()"), self.jobStorageIDExistsDefaultPushButton_clicked)
##
##        self.addWidget(widget, "job_storage_id_exists")
##
##    def jobStorageIDExistsComboBox_activated(self, a):
##        self.jobStorageIDExistsDefaultPushButton.setEnabled(a==1)
##        self.job_storage_job_exist = a
##
##    def jobStorageIDExistsDefaultPushButton_clicked(self):
##        self.jobStorageIDExistsComboBox.setCurrentItem(0)
##        self.jobStorageIDExistsDefaultPushButton.setEnabled(False)
##        self.job_storage_job_exist = 0
##
##
##    #
##    #
##    #

    def printButton_clicked(self):
        if self.invalid_page_range:
            self.form.FailureUI(self.__tr("<b>Cannot print: Invalid page range: %1</b><p>A valid page range is a list of pages or ranges of pages separated by commas (e.g., 1-2,4,6-7)").arg(self.pageRangeEdit.text()))
            return

        try:
            try:
                self.cur_device.open()
            except Error:
                self.form.FailureUI(self.__tr("<b>Cannot print: Device is busy or not available.</b><p>Please check device and try again."))
                return

            if 1: # Go ahead and allow - print will be queued in CUPS if not rejecting
                printers = cups.getPrinters()
                for p in printers:
                    if p.name == self.cur_printer:
                        break

                if p.state == cups.IPP_PRINTER_STATE_STOPPED:
                    self.form.FailureUI(self.__tr("<b>Cannot print: Printer is stopped.</b><p>Please START the printer to continue this print. Job will begin printing once printer is started."))

                if not p.accepting:
                    self.form.FailureUI(self.__tr("<b>Cannot print: Printer is not accepting jobs.</b><p>Please set the printer to ACCEPTING JOBS to continue printing."))
                    return

                copies = int(self.copiesSpinBox.value())
                all_pages = self.pages_button_group == 0
                page_range = unicode(self.pageRangeEdit.text())
                page_set = int(self.pageSetComboBox.currentItem())

                cups.resetOptions()
                cups.openPPD(self.cur_printer)
                current_options = dict(cups.getOptions())
                cups.closePPD()

                nup = int(current_options.get("number-up", 1))
                log.debug("number-up = %d" % nup)

                for p, t, d in self.file_list:

                    alt_nup = (nup > 1 and t == 'application/postscript' and utils.which('psnup'))

                    if utils.which('lpr'):
                        if alt_nup:
                            cmd = ' '.join(['psnup', '-%d' % nup, ''.join(['"', p, '"']), '| lpr -P', self.cur_printer])
                        else:
                            cmd = ' '.join(['lpr -P', self.cur_printer])

                        if copies > 1:
                            cmd = ' '.join([cmd, '-#%d' % copies])

                    else:
                        if alt_nup:
                            cmd = ' '.join(['psnup', '-%d' % nup, ''.join(['"', p, '"']), '| lp -c -d', self.cur_printer])
                        else:
                            cmd = ' '.join(['lp -c -d', self.cur_printer])

                        if copies > 1:
                            cmd = ' '.join([cmd, '-n%d' % copies])


                    if not all_pages and len(page_range) > 0:
                        cmd = ' '.join([cmd, '-o page-ranges=%s' % page_range])

                    if page_set > 0:
                        if page_set == 1:
                            cmd = ' '.join([cmd, '-o page-set=even'])
                        else:
                            cmd = ' '.join([cmd, '-o page-set=odd'])


                    # Job Storage
                    # self.job_storage_mode = (0=Off, 1=P&H, 2=PJ, 3=QC, 4=SJ)
                    # self.job_storage_pin = u"" (dddd)
                    # self.job_storage_use_pin = True|False
                    # self.job_storage_username = u""
                    # self.job_storage_auto_username = True|False
                    # self.job_storage_jobname = u""
                    # self.job_storage_auto_jobname = True|False
                    # self.job_storage_job_exist = (0=replace, 1=job name+(1-99))

                    if self.job_storage_avail:
                        if self.job_storage_mode: # On

                            if self.job_storage_mode == 1: # Proof and Hold
                                cmd = ' '.join([cmd, '-o HOLD=PROOF'])

                            elif self.job_storage_mode == 2: # Private Job
                                if self.job_storage_use_pin:
                                    cmd = ' '.join([cmd, '-o HOLD=ON'])
                                    cmd = ' '.join([cmd, '-o HOLDTYPE=PRIVATE'])
                                    cmd = ' '.join([cmd, '-o HOLDKEY=%s' % self.job_storage_pin.encode('ascii')])
                                else:
                                    cmd = ' '.join([cmd, '-o HOLD=PROOF'])
                                    cmd = ' '.join([cmd, '-o HOLDTYPE=PRIVATE'])

                            elif self.job_storage_mode == 3: # Quick Copy
                                cmd = ' '.join([cmd, '-o HOLD=ON'])
                                cmd = ' '.join([cmd, '-o HOLDTYPE=PUBLIC'])

                            elif self.job_storage_mode == 4: # Store Job
                                if self.job_storage_use_pin:
                                    cmd = ' '.join([cmd, '-o HOLD=STORE'])
                                    cmd = ' '.join([cmd, '-o HOLDTYPE=PRIVATE'])
                                    cmd = ' '.join([cmd, '-o HOLDKEY=%s' % self.job_storage_pin.encode('ascii')])
                                else:
                                    cmd = ' '.join([cmd, '-o HOLD=STORE'])

                            cmd = ' '.join([cmd, '-o USERNAME=%s' % self.job_storage_username.encode('ascii')\
                                .replace(" ", "_")])

                            cmd = ' '.join([cmd, '-o JOBNAME=%s' % self.job_storage_jobname.encode('ascii')\
                                .replace(" ", "_")])

                            if self.job_storage_job_exist == 1:
                                cmd = ' '.join([cmd, '-o DUPLICATEJOB=APPEND'])
                            else:
                                cmd = ' '.join([cmd, '-o DUPLICATEJOB=REPLACE'])

                        else: # Off
                            cmd = ' '.join([cmd, '-o HOLD=OFF'])


                    if not alt_nup:
                        cmd = ''.join([cmd, ' "', p, '"'])

                    log.debug("Printing: %s" % cmd)

                    code = os.system(cmd)
                    if code != 0:
                        log.error("Print command failed.")
                        self.form.FailureUI(self.__tr("Print command failed with error code %1").arg(code))

                self.form.close()

        finally:
            self.cur_device.close()

    def funcButton_clicked(self):
        self.form.close()

    def __tr(self,s,c = None):
        return qApp.translate("ScrollPrintView",s,c)
Exemple #2
0
class ScrollPrintSettingsView(ScrollView):
    utils.mixin(JobStorageMixin)

    def __init__(self, service, parent=None, name=None, fl=0):
        ScrollView.__init__(self, service, parent, name, fl)

        self.initJobStorage(True)



    def fillControls(self):
        QApplication.setOverrideCursor(QApplication.waitCursor)

        ScrollView.fillControls(self)

        self.loading = True
        cups.resetOptions()
        cups.openPPD(self.cur_printer)
        cur_outputmode = ""
                
        #if 1:
        try:
            if 1:
            #try:
                current_options = dict(cups.getOptions())

                if not self.cur_device.device_type == DEVICE_TYPE_FAX:
                    self.addGroupHeading("basic", self.__tr("Basic"))
                    log.debug("Group: Basic")

                    # Basic
                        # PageSize (in PPD section)
                        # orientation-requested
                        # sides
                        # outputorder
                        # Collate


                    current = current_options.get('orientation-requested', '3')

                    self.addItem("basic", "orientation-requested", self.__tr("Page Orientation"),
                        cups.PPD_UI_PICKONE, current,
                        [('3', self.__tr('Portrait')),
                         ('4', self.__tr('Landscape')),
                         ('5', self.__tr('Reverse landscape')),
                         ('6', self.__tr('Reverse portrait'))], '3')

                    log.debug("Option: orientation-requested")
                    log.debug("Current value: %s" % current)

                    duplexer = self.cur_device.dq.get('duplexer', 0)
                    log.debug("Duplexer = %d" % duplexer)

                    if duplexer:
                        current = current_options.get('sides', 'one-sided')
                        self.addItem("basic", "sides",
                            self.__tr("Duplex (Print on both sides of the page)"),
                            cups.PPD_UI_PICKONE, current,
                            [('one-sided',self.__tr('Single sided')),
                             ('two-sided-long-edge', self.__tr('Two sided (long edge)')),
                             ('two-sided-short-edge', self.__tr('Two sided (short edge)'))], 'one-sided')

                        log.debug("Option: sides")
                        log.debug("Current value: %s" % current)

                    current = current_options.get('outputorder', 'normal')

                    self.addItem("basic", "outputorder",
                        self.__tr("Output Order (Print last page first)"),
                        cups.PPD_UI_PICKONE, current,
                        [('normal', self.__tr('Normal (Print first page first)')),
                         ('reverse', self.__tr('Reversed (Print last page first)'))], 'normal')

                    log.debug("Option: outputorder")
                    log.debug("Current value: %s" % current)

                    current = utils.to_bool(current_options.get('Collate', '0'))

                    self.addItem("basic", "Collate",
                        self.__tr("Collate (Group together multiple copies)"),
                        cups.PPD_UI_BOOLEAN, current,
                        [], 0)

                    log.debug("Option: Collate")
                    log.debug("Current value: %s" % current)

                groups = cups.getGroupList()

                for g in groups:
                    log.debug("Group: %s" % repr(g))

                    if 'jobretention' in g.lower():
                        log.debug("HPJobRetention skipped.")
                        continue

                    text, num_subgroups = cups.getGroup(g)
                    read_only = 'install' in g.lower()

                    try:
                        text = text.decode('utf-8')
                    except UnicodeDecodeError:
                        pass

                    if g.lower() == 'printoutmode':
                        text = self.__tr("Quality")

                    self.addGroupHeading(g, text, read_only)

                    log.debug("  Text: %s" % repr(text))
                    log.debug("Num subgroups: %d" % num_subgroups)

                    options = cups.getOptionList(g)

                    for o in options:
                        log.debug("  Option: %s" % repr(o))

                        if 'pageregion' in o.lower():
                            log.debug("Page Region skipped.")
                            continue



                        option_text, defchoice, conflicted, ui  = cups.getOption(g, o)

                        try:
                            option_text = option_text.decode('utf-8')
                        except UnicodeDecodeError:
                            pass

                        if o.lower() == 'quality':
                            option_text = self.__tr("Quality")

                        log.debug("    Text: %s" % repr(option_text))
                        log.debug("    Defchoice: %s" % repr(defchoice))

                        choices = cups.getChoiceList(g, o)

                        value = None
                        choice_data = []
                        for c in choices:
                            log.debug("    Choice: %s" % repr(c))

                            # TODO: Add custom paper size controls
                            if 'pagesize' in o.lower() and 'custom' in c.lower():
                                log.debug("Skipped.")
                                continue

                            choice_text, marked = cups.getChoice(g, o, c)

                            try:
                                choice_text = choice_text.decode('utf-8')
                            except UnicodeDecodeError:
                                pass

                            log.debug("      Text: %s" % repr(choice_text))

                            if marked:
                                value = c

                            choice_data.append((c, choice_text))

                        if o.lower() == 'outputmode':
                            if value is not None:
                                cur_outputmode = value
                            else:
                                cur_outputmode = defchoice                                

                        self.addItem(g, o, option_text, ui, value, choice_data, defchoice, read_only)

##                        if 'pagesize' in o.lower(): # and 'custom' in c.lower():
##                            current = 0.0
##                            width_widget = self.addItem("custom", "custom-width", self.__tr("Custom Paper Width"), cups.UI_UNITS_SPINNER,
##                                current, (0.0, 0.0), 0.0)
##
##                            current = 0.0
##                            height_widget = self.addItem("custom", "custom-height", self.__tr("Custom Paper Height"), cups.UI_UNITS_SPINNER,
##                                current, (0.0, 0.0), 0.0)
##
##                            if value.lower() == 'custom':
##                                pass

                # N-Up
                    # number-up
                    # number-up-layout
                    # page-border

                self.addGroupHeading("nup",
                    self.__tr("N-Up (Multiple document pages per printed page)"))

                log.debug("Group: N-Up")

                current = current_options.get('number-up', '1')

                self.addItem("nup", "number-up", self.__tr("Pages per Sheet"),
                    cups.PPD_UI_PICKONE, current,
                    [('1', self.__tr('1 page per sheet')),
                     ('2', self.__tr('2 pages per sheet')),
                     ('4', self.__tr('4 pages per sheet'))], '1')

                log.debug("  Option: number-up")
                log.debug("  Current value: %s" % current)

                current = current_options.get('number-up-layout', 'lrtb')

                self.addItem("nup", "number-up-layout", self.__tr("Layout"),
                    cups.PPD_UI_PICKONE, current,
                    [('btlr', self.__tr('Bottom to top, left to right')),
                     ('btrl', self.__tr('Bottom to top, right to left')),
                     ('lrbt', self.__tr('Left to right, bottom to top')),
                     ('lrtb', self.__tr('Left to right, top to bottom')),
                     ('rlbt', self.__tr('Right to left, bottom to top')),
                     ('rltb', self.__tr('Right to left, top to bottom')),
                     ('tblr', self.__tr('Top to bottom, left to right')),
                     ('tbrl', self.__tr('Top to bottom, right to left')) ], 'lrtb')

                log.debug("  Option: number-up-layout")
                log.debug("  Current value: %s" % current)

                current = current_options.get('page-border', 'none')

                self.addItem("nup", "page-border",
                    self.__tr("Printed Border Around Each Page"),
                    cups.PPD_UI_PICKONE, current,
                    [('double', self.__tr("Two thin borders")),
                     ("double-thick", self.__tr("Two thick borders")),
                     ("none", self.__tr("No border")),
                     ("single", self.__tr("One thin border")),
                     ("single-thick", self.__tr("One thick border"))], 'none')

                log.debug("  Option: page-border")
                log.debug("  Current value: %s" % current)

                # Adjustment
                    # brightness
                    # gamma

                if not self.cur_device.device_type == DEVICE_TYPE_FAX:
                    self.addGroupHeading("adjustment", self.__tr("Printout Appearance"))

                    current = int(current_options.get('brightness', 100))

                    log.debug("  Option: brightness")
                    log.debug("  Current value: %s" % current)

                    self.addItem("adjustment", "brightness", self.__tr("Brightness"),
                        cups.UI_SPINNER, current, (0, 200), 100, suffix=" %")

                    current = int(current_options.get('gamma', 1000))

                    log.debug("  Option: gamma")
                    log.debug("  Current value: %s" % current)

                    self.addItem("adjustment", "gamma", self.__tr("Gamma"), cups.UI_SPINNER, current,
                        (1, 10000), 1000)

                # Margins (pts)
                    # page-left
                    # page-right
                    # page-top
                    # page-bottom

##                if 0:
##                    # TODO: cupsPPDPageSize() fails on LaserJets. How do we get margins in this case? Defaults?
##                    # PPD file for LJs has a HWMargin entry...
##                    page, page_width, page_len, left, bottom, right, top = cups.getPPDPageSize()
##
##                    right = page_width - right
##                    top = page_len - top
##
##                    self.addGroupHeading("margins", self.__tr("Margins"))
##                    current_top = current_options.get('page-top', 0) # pts
##                    current_bottom = current_options.get('page-bottom', 0) # pts
##                    current_left = current_options.get('page-left', 0) # pts
##                    current_right = current_options.get('page-right', 0) # pts
##
##                    log.debug("  Option: page-top")
##                    log.debug("  Current value: %s" % current_top)
##
##                    self.addItem("margins", "page-top", self.__tr("Top margin"),
##                        cups.UI_UNITS_SPINNER, current_top,
##                        (0, page_len), top)
##
##                    self.addItem("margins", "page-bottom", self.__tr("Bottom margin"),
##                        cups.UI_UNITS_SPINNER, current_bottom,
##                        (0, page_len), bottom)
##
##                    self.addItem("margins", "page-left", self.__tr("Right margin"),
##                        cups.UI_UNITS_SPINNER, current_left,
##                        (0, page_width), left)
##
##                    self.addItem("margins", "page-right", self.__tr("Left margin"),
##                        cups.UI_UNITS_SPINNER, current_right,
##                        (0, page_width), right)

                # Image Printing
                    # position
                    # natural-scaling
                    # saturation
                    # hue

                self.addGroupHeading("image", self.__tr("Image Printing"))

                current = utils.to_bool(current_options.get('fitplot', 'false'))

                self.addItem("image", "fitplot",
                    self.__tr("Fit to Page"),
                    cups.PPD_UI_BOOLEAN, current,
                    [], 0)


                current = current_options.get('position', 'center')

                self.addItem("image", "position", self.__tr("Position on Page"),
                    cups.PPD_UI_PICKONE, current,
                    [('center', self.__tr('Centered')),
                     ('top', self.__tr('Top')),
                     ('left', self.__tr('Left')),
                     ('right', self.__tr('Right')),
                     ('top-left', self.__tr('Top left')),
                     ('top-right', self.__tr('Top right')),
                     ('bottom', self.__tr('Bottom')),
                     ('bottom-left', self.__tr('Bottom left')),
                     ('bottom-right', self.__tr('Bottom right'))], 'center')

                log.debug("  Option: position")
                log.debug("  Current value: %s" % current)

                if not self.cur_device.device_type == DEVICE_TYPE_FAX:
                    current = int(current_options.get('saturation', 100))

                    log.debug("  Option: saturation")
                    log.debug("  Current value: %s" % current)

                    self.addItem("image", "saturation", self.__tr("Saturation"),
                        cups.UI_SPINNER, current, (0, 200), 100, suffix=" %")

                    current = int(current_options.get('hue', 0))

                    log.debug("  Option: hue")
                    log.debug("  Current value: %s" % current)

                    self.addItem("image", "hue", self.__tr("Hue (color shift/rotation)"),
                        cups.UI_SPINNER, current,
                        (-100, 100), 0)

                current = int(current_options.get('natural-scaling', 100))

                log.debug("  Option: natural-scaling")
                log.debug("  Current value: %s" % current)

                self.addItem("image", "natural-scaling",
                    self.__tr('"Natural" Scaling (relative to image)'),
                    cups.UI_SPINNER, current, (1, 800), 100, suffix=" %")

                current = int(current_options.get('scaling', 100))

                log.debug("  Option: scaling")
                log.debug("  Current value: %s" % current)

                self.addItem("image", "scaling", self.__tr("Scaling (relative to page)"),
                    cups.UI_SPINNER, current,
                    (1, 800), 100, suffix=" %")

                # Misc
                    # PrettyPrint
                    # job-sheets
                    # mirror

                self.addGroupHeading("misc", self.__tr("Miscellaneous"))

                log.debug("Group: Misc")

                current = utils.to_bool(current_options.get('prettyprint', '0'))

                self.addItem("misc", "prettyprint",
                    self.__tr('"Pretty Print" Text Documents (Add headers and formatting)'),
                    cups.PPD_UI_BOOLEAN, current, [], 0)

                log.debug("  Option: prettyprint")
                log.debug("  Current value: %s" % current)

                if not self.cur_device.device_type == DEVICE_TYPE_FAX:
                    current = current_options.get('job-sheets', 'none').split(',')

                    try:
                        start = current[0]
                    except IndexError:
                        start = 'none'

                    try:
                        end = current[1]
                    except IndexError:
                        end = 'none'

                    # TODO: Look for locally installed banner pages beyond the default CUPS ones?
                    self.addItem("misc", "job-sheets", self.__tr("Banner Pages"), cups.UI_BANNER_JOB_SHEETS,
                        (start, end),
                        [("none", self.__tr("No banner page")),
                         ('classified', self.__tr("Classified")),
                         ('confidential', self.__tr("Confidential")),
                         ('secret', self.__tr("Secret")),
                         ('standard', self.__tr("Standard")),
                         ('topsecret', self.__tr("Top secret")),
                         ('unclassified', self.__tr("Unclassified"))], ('none', 'none'))

                    log.debug("  Option: job-sheets")
                    log.debug("  Current value: %s,%s" % (start, end))

                current = utils.to_bool(current_options.get('mirror', '0'))

                self.addItem("misc", "mirror", self.__tr('Mirror Printing'),
                    cups.PPD_UI_BOOLEAN, current, [], 0)

                log.debug("  Option: mirror")
                log.debug("  Current value: %s" % current)
                
                #Summary
                    #color input
                    #quality
                quality_attr_name = "OutputModeDPI"
                cur_outputmode_dpi = cups.findPPDAttribute(quality_attr_name, cur_outputmode)
                if cur_outputmode_dpi is not None:
                    log.debug("Adding Group: Summary outputmode is : %s" % cur_outputmode)
                    log.debug("Adding Group: Summary outputmode dpi is : %s" % str (cur_outputmode_dpi))                
                    self.addGroupHeading("summry", self.__tr("Summary"))
                    self.addItem("summry", "colorinput", self.__tr('Color Input / Black Render'),
                        cups.UI_INFO, cur_outputmode_dpi, [], 0)
                    self.addItem("summry", "quality", self.__tr('Print Quality'),
                        cups.UI_INFO, cur_outputmode, [], 0)
                
                self.job_storage_avail = 0 #self.cur_device.mq['job-storage'] == JOB_STORAGE_ENABLE

                #print current_options

                if self.job_storage_avail:
                    self.addGroupHeading("jobstorage", self.__tr("Job Storage and Secure Printing"))
                    self.addJobStorage(current_options)


            #except Exception, e:
                #log.exception()
            #    pass

        finally:
            cups.closePPD()
            self.loading = False
            QApplication.restoreOverrideCursor()

    def ComboBox_indexChanged(self, currentItem):
        sender = self.sender()
        currentItem = to_unicode(currentItem)
        # Checking for summary control
        labelPQValaue = getattr(self, 'PQValueLabel', None)
        labelPQColorInput = getattr(self, 'PQColorInputLabel', None)
        # When output mode combo item is changed, we need to update the summary information      
        if currentItem is not None and sender.option == 'OutputMode' and labelPQValaue is not None and labelPQColorInput is not None:
            # Setting output mode
            self.PQValueLabel.setText(currentItem)
            
            # Getting DPI custom attributefrom the PPD
            # Setting color input
            quality_attr_name = "OutputModeDPI"
            cups.openPPD(self.cur_printer)
            outputmode_dpi = cups.findPPDAttribute(quality_attr_name, currentItem)
            log.debug("Outputmode changed, setting outputmode_dpi: %s" % outputmode_dpi)
            cups.closePPD()            
            self.PQColorInputLabel.setText(outputmode_dpi)
            
            log.debug("Outputmode changed, setting value outputmode: %s" % currentItem)            

    def optionComboBox_activated(self, a):
        a = to_unicode(a)
        sender = self.sender()
        choice = None

        if sender.typ == cups.UI_BANNER_JOB_SHEETS:
            start, end = None, None
            for c, t in sender.choices:
                if t == a:
                    start = c
                    break

            for c, t in sender.other.choices:
                if t == sender.other.currentText():
                    end = c
                    break

            if sender.option == 'end':
                start, end = end, start

            if start is not None and \
                end is not None and \
                start.lower() == sender.default[0].lower() and \
                end.lower() == sender.default[1].lower():
                    self.removePrinterOption('job-sheets')
                    sender.pushbutton.setEnabled(False)
            else:
                sender.pushbutton.setEnabled(True)

                if start is not None and \
                    end is not None:

                    self.setPrinterOption('job-sheets', ','.join([start, end]))

        else:
            choice = None
            for c, t in sender.choices:
                if t == a:
                    choice = c
                    break

            if choice is not None and choice.lower() == sender.default.lower():
                self.removePrinterOption(sender.option)
                sender.pushbutton.setEnabled(False)
            else:
                sender.pushbutton.setEnabled(True)

                if choice is not None:
                    self.setPrinterOption(sender.option, choice)

            self.linkPrintoutModeAndQuality(sender.option, choice)


    def linkPrintoutModeAndQuality(self, option, choice):
        if option.lower() == 'quality' and \
            choice is not None:

            try:
                c = self.items['o:PrintoutMode'].control
            except KeyError:
                return
            else:
                if c is not None:
                    if choice.lower() == 'fromprintoutmode':
                        # from printoutmode selected
                        # determine printoutmode option combo enable state
                        c.setEnabled(True)
                        QToolTip.remove(c)
                        a = to_unicode(c.currentText())

                        # determine printoutmode default button state
                        link_choice = None
                        for x, t in c.choices:
                            if t == a:
                                link_choice = x
                                break

                        if link_choice is not None and \
                            link_choice.lower() == c.default.lower():

                            c.pushbutton.setEnabled(False)
                        else:
                            c.pushbutton.setEnabled(True)

                    else: # fromprintoutmode not selected, disable printoutmode
                        c.setEnabled(False)
                        QToolTip.add(c, self.__tr("""Set Quality to "Controlled by 'Printout Mode'" to enable."""))
                        c.pushbutton.setEnabled(False)



    def optionSpinBox_valueChanged(self, i):
        sender = self.sender()

        if i == sender.default:
            self.removePrinterOption(sender.option)
            sender.pushbutton.setEnabled(False)
        else:
            sender.pushbutton.setEnabled(True)
            self.setPrinterOption(sender.option, str(i))


    def optionButtonGroup_clicked(self, b):
        sender = self.sender()
        b = int(b)

        if b == sender.default:
            self.removePrinterOption(sender.option)
            sender.pushbutton.setEnabled(False)
        else:
            sender.pushbutton.setEnabled(True)

            if b:
                self.setPrinterOption(sender.option, "true")
            else:
                self.setPrinterOption(sender.option, "false")



    def defaultPushButton_clicked(self):
        sender = self.sender()
        sender.setEnabled(False)

        if sender.typ == cups.PPD_UI_BOOLEAN:
            if sender.default:
                sender.control.setButton(1)
            else:
                sender.control.setButton(0)

            self.removePrinterOption(sender.option)

        elif sender.typ == cups.PPD_UI_PICKONE:
            choice, text = None, None

            for c, t in sender.choices:
                if c == sender.default:
                    choice = c
                    text = t
                    break

            if choice is not None:
                self.removePrinterOption(sender.option)
                sender.control.setCurrentText(text)

                self.linkPrintoutModeAndQuality(sender.option, choice)

        elif sender.typ == cups.UI_SPINNER:
            sender.control.setValue(sender.default)
            self.removePrinterOption(sender.option)

        elif sender.typ == cups.UI_BANNER_JOB_SHEETS:
            start, end, start_text, end_text = None, None, None, None
            for c, t in sender.choices:
                if c == sender.default[0]:
                    start = c
                    start_text = t

                if c == sender.default[1]:
                    end = c
                    end_text = t

            if start is not None:
                sender.control[0].setCurrentText(start_text)

            if end is not None:
                sender.control[1].setCurrentText(end_text)

            self.removePrinterOption('job-sheets')


    def setPrinterOption(self, option, value):
        cups.openPPD(self.cur_printer)

        try:
            cups.addOption("%s=%s" % (option, value))
            cups.setOptions()
        finally:
            cups.closePPD()

    def removePrinterOption(self, option):
        cups.openPPD(self.cur_printer)

        try:
            cups.removeOption(option)
            cups.setOptions()
        finally:
            cups.closePPD()


    def addItem(self, group, option, text, typ, value, choices, default, read_only=False, suffix=""):
        widget, control = None, None

        if typ == cups.PPD_UI_BOOLEAN: # () On (*) Off widget
            widget = self.getWidget()
            layout = QGridLayout(widget, 1, 1, 5, 10, "layout")
            default = int(utils.to_bool(str(default)))
            value = int(utils.to_bool(str(value)))

            textLabel1 = QLabel(widget, "textLabel1")
            layout.addWidget(textLabel1, 0, 0)

            buttonGroup = OptionButtonGroup(widget, "buttonGroup", group, option, default)
            buttonGroup.setLineWidth(0)
            buttonGroup.setColumnLayout(0,Qt.Vertical)
            buttonGroup.layout().setSpacing(1)
            buttonGroup.layout().setMargin(5)
            buttonGroupLayout = QHBoxLayout(buttonGroup.layout())
            buttonGroupLayout.setAlignment(Qt.AlignTop)

            defaultPushButton = DefaultPushButton(widget,"defaultPushButton", group, option,
                choices, default, buttonGroup, typ)

            buttonGroup.setDefaultPushbutton(defaultPushButton)

            layout.addWidget(defaultPushButton, 0, 3)

            spacer1 = QSpacerItem(20, 20, QSizePolicy.Expanding, QSizePolicy.Minimum)
            layout.addItem(spacer1, 0, 1)

            onRadioButton = QRadioButton(buttonGroup,"onRadioButton")
            buttonGroup.insert(onRadioButton, 1)
            buttonGroupLayout.addWidget(onRadioButton)

            offRadioButton = QRadioButton(buttonGroup,"offRadioButton")
            buttonGroup.insert(offRadioButton, 0)
            buttonGroupLayout.addWidget(offRadioButton)

            layout.addWidget(buttonGroup, 0, 2)

            textLabel1.setText(text)
            onRadioButton.setText(self.__tr("On"))
            offRadioButton.setText(self.__tr("Off"))

            if value == default:
                defaultPushButton.setEnabled(False)

            self.connect(defaultPushButton, SIGNAL("clicked()"), self.defaultPushButton_clicked)
            self.connect(buttonGroup, SIGNAL("clicked(int)"), self.optionButtonGroup_clicked)

            x = self.__tr('Off')
            if default:
                x = self.__tr('On')

            if value:
                buttonGroup.setButton(1)
            else:
                buttonGroup.setButton(0)

            if read_only:
                onRadioButton.setEnabled(False)
                offRadioButton.setEnabled(False)
                defaultPushButton.setEnabled(False)
            else:
                QToolTip.add(defaultPushButton, self.__tr('Set to default value of "%1".').arg(x))

            defaultPushButton.setText("Default")

        elif typ == cups.PPD_UI_PICKONE: # Combo box widget
            widget = self.getWidget()

            layout1 = QHBoxLayout(widget,5,10,"layout1")

            textLabel1 = QLabel(widget,"textLabel1")
            layout1.addWidget(textLabel1)

            spacer1 = QSpacerItem(20, 20, QSizePolicy.Expanding, QSizePolicy.Minimum)
            layout1.addItem(spacer1)

            optionComboBox = OptionComboBox(0, widget, "optionComboBox", group, option, choices, default)
            layout1.addWidget(optionComboBox)

            defaultPushButton = DefaultPushButton(widget,"defaultPushButton", group, option,
                choices, default, optionComboBox, typ)

            optionComboBox.setDefaultPushbutton(defaultPushButton)

            layout1.addWidget(defaultPushButton)

            textLabel1.setText(text)
            defaultPushButton.setText("Default")

            x, y = None, None
            for c, t in choices:
                d = c.lower()
                if value is not None and d == value.lower():
                    x = t

                if d == default.lower():
                    y = t

                optionComboBox.insertItem(t)

            if x is not None:
                optionComboBox.setCurrentText(x)

            if value is not None and value.lower() == default.lower():
                defaultPushButton.setEnabled(False)

            self.linkPrintoutModeAndQuality(option, value)

            if read_only:
                optionComboBox.setEnabled(False)
                defaultPushButton.setEnabled(False)
            elif y is not None:
                QToolTip.add(defaultPushButton, self.__tr('Set to default value of "%1".').arg(y))

            self.connect(defaultPushButton, SIGNAL("clicked()"), self.defaultPushButton_clicked)
            self.connect(optionComboBox, SIGNAL("activated(const QString&)"), self.optionComboBox_activated)
            self.connect(optionComboBox, SIGNAL("activated(const QString &)"), self.ComboBox_indexChanged)

            control = optionComboBox

        elif typ == cups.UI_SPINNER: # Spinner widget
            widget = self.getWidget()

            layout1 = QHBoxLayout(widget,5,10, "layout1")

            textLabel1 = QLabel(widget, "textLabel1")
            layout1.addWidget(textLabel1)

            spacer1 = QSpacerItem(20, 20, QSizePolicy.Expanding, QSizePolicy.Minimum)
            layout1.addItem(spacer1)

            optionSpinBox = OptionSpinBox(widget,"optionSpinBox", group, option, default)
            layout1.addWidget(optionSpinBox)

            defaultPushButton = DefaultPushButton(widget, "defaultPushButton", group, option, choices,
                default, optionSpinBox, typ)

            optionSpinBox.setDefaultPushbutton(defaultPushButton)

            layout1.addWidget(defaultPushButton)

            min, max = choices
            optionSpinBox.setMinValue(min)
            optionSpinBox.setMaxValue(max)
            optionSpinBox.setValue(value)

            if suffix:
                optionSpinBox.setSuffix(suffix)

            textLabel1.setText(text)
            defaultPushButton.setText("Default")

            self.connect(optionSpinBox, SIGNAL("valueChanged(int)"), self.optionSpinBox_valueChanged)
            self.connect(defaultPushButton, SIGNAL("clicked()"), self.defaultPushButton_clicked)

            if value == default:
                defaultPushButton.setEnabled(False)

            if read_only:
                self.optionSpinBox.setEnabled(False)
                self.defaultPushButton.setEnabled()
            else:
                QToolTip.add(defaultPushButton,
                    self.__tr('Set to default value of "%1".').arg(default))

        elif typ == cups.UI_BANNER_JOB_SHEETS:  # Job sheets widget
            widget = self.getWidget()

            layout1 = QGridLayout(widget,1,1,5,10,"layout1")

            startComboBox = OptionComboBox(0, widget, "startComboBox", group,
                "start", choices, default, typ)

            layout1.addWidget(startComboBox,0,3)

            startTextLabel = QLabel(widget,"startTextLabel")
            layout1.addWidget(startTextLabel,0,2)

            endTextLabel = QLabel(widget,"endTextLabel")
            layout1.addWidget(endTextLabel,0,4)

            endComboBox = OptionComboBox(0, widget, "endComboBox", group, "end", choices,
                default, typ, startComboBox)

            layout1.addWidget(endComboBox,0,5)

            startComboBox.setOther(endComboBox)

            defaultPushButton = DefaultPushButton(widget, "defaultPushButton", group, option, choices,
                default, (startComboBox, endComboBox), typ)

            layout1.addWidget(defaultPushButton,0,6)

            startComboBox.setDefaultPushbutton(defaultPushButton)
            endComboBox.setDefaultPushbutton(defaultPushButton)

            textLabel1 = QLabel(widget,"textLabel1")
            layout1.addWidget(textLabel1,0,0)

            spacer1 = QSpacerItem(20,20,QSizePolicy.Expanding,QSizePolicy.Minimum)
            layout1.addItem(spacer1,0,1)

            textLabel1.setText(text)
            defaultPushButton.setText("Default")

            startTextLabel.setText(self.__tr("Start:"))
            endTextLabel.setText(self.__tr("End:"))

            s, e, y, z = None, None, None, None
            for c, t in choices:
                d = c.lower()
                if value is not None:
                    if d == value[0].lower():
                        s = t

                    if d == value[1].lower():
                        e = t

                if d == default[0].lower():
                    y = t

                if d == default[1].lower():
                    z = t

                startComboBox.insertItem(t)
                endComboBox.insertItem(t)

            if s is not None:
                startComboBox.setCurrentText(s)

            if e is not None:
                endComboBox.setCurrentText(e)

            if value is not None and \
                value[0].lower() == default[0].lower() and \
                value[1].lower() == default[1].lower():

                defaultPushButton.setEnabled(False)

            if y is not None and z is not None:
                QToolTip.add(defaultPushButton, self.__tr('Set to default value of "Start: %1, End: %2".').arg(y).arg(z))

            self.connect(startComboBox, SIGNAL("activated(const QString&)"), self.optionComboBox_activated)
            self.connect(endComboBox, SIGNAL("activated(const QString&)"), self.optionComboBox_activated)
            self.connect(defaultPushButton, SIGNAL("clicked()"), self.defaultPushButton_clicked)

        elif typ == cups.PPD_UI_PICKMANY:
            log.error("Unrecognized type: pickmany")

        elif typ == cups.UI_UNITS_SPINNER:
            widget = self.getWidget()

            layout1 = QHBoxLayout(widget,5,10,"layout1")

            textLabel1 = QLabel(widget,"textLabel1")
            layout1.addWidget(textLabel1)

            spacer1 = QSpacerItem(20,20,QSizePolicy.Expanding,QSizePolicy.Minimum)
            layout1.addItem(spacer1)

            lineEdit1 = QLineEdit(widget,"lineEdit1")
            layout1.addWidget(lineEdit1)

            comboBox1 = QComboBox(0,widget,"comboBox1")
            layout1.addWidget(comboBox1)

            defaultPushButton = QPushButton(widget,"defaultPushButton")
            layout1.addWidget(defaultPushButton)

            textLabel1.setText(text)
            defaultPushButton.setText("Default")

        elif typ == cups.UI_INFO:
            widget = self.getWidget()

            layout1 = QHBoxLayout(widget,5,10,"layout1")

            textPropName = QLabel(widget,"textPropName")
            layout1.addWidget(textPropName)
            textPropName.setText(text)            

            spacer1 = QSpacerItem(20,20,QSizePolicy.Expanding,QSizePolicy.Minimum)
            layout1.addItem(spacer1)
            
            if text == 'Print Quality':
                self.PQValueLabel = QLabel(widget,"textPropValue")
                layout1.addWidget(self.PQValueLabel)
                self.PQValueLabel.setText(value)
            elif text == 'Color Input / Black Render':
                self.PQColorInputLabel = QLabel(widget,"textPropValue")
                layout1.addWidget(self.PQColorInputLabel)
                self.PQColorInputLabel.setText(value)
            else:
                textPropValue = QLabel(widget,"textPropValue")
                layout1.addWidget(textPropValue)
                textPropValue.setText(value)
            
        else:
            log.error("Invalid UI value: %s/%s" % (group, option))

        if widget is not None:
            self.addWidget(widget, "o:"+option, control)
            return widget



    def __tr(self,s,c = None):
        return qApp.translate("ScrollPrintSettingsView",s,c)