1#!/usr/local/bin/python3.8
2# -*- coding: utf-8 -*-
3#
4# (c) Copyright 2003-2015 HP Development Company, L.P.
5#
6# This program is free software; you can redistribute it and/or modify
7# it under the terms of the GNU General Public License as published by
8# the Free Software Foundation; either version 2 of the License, or
9# (at your option) any later version.
10#
11# This program is distributed in the hope that it will be useful,
12# but WITHOUT ANY WARRANTY; without even the implied warranty of
13# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14# GNU General Public License for more details.
15#
16# You should have received a copy of the GNU General Public License
17# along with this program; if not, write to the Free Software
18# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
19#
20# Author: Don Welch, Naga Samrat Chowdary Narla,
21#
22
23__version__ = '5.0'
24__title__ = 'Printer Cartridge Alignment Utility'
25__mod__ = 'hp-align'
26__doc__ = "Cartridge alignment utility for HPLIP supported inkjet printers. (Note: Not all printers require the use of this utility)."
27
28# Std Lib
29import sys
30import re
31import getopt
32import operator
33import os
34
35
36# Local
37from base.g import *
38from base import device, status, utils, maint, tui, module
39from prnt import cups
40
41try:
42    from importlib import import_module
43except ImportError as e:
44    log.debug(e)
45    from base.utils import dyn_import_mod as import_module
46
47def enterAlignmentNumber(letter, hortvert, colors, line_count, maximum):
48    ok, value = tui.enter_range("From the printed Alignment page, Enter the best aligned value for line %s (1-%d): " %
49                        (letter, maximum),
50                        1,
51                        maximum)
52    if not ok:
53        sys.exit(0)
54
55    return ok, value
56
57
58def enterPaperEdge(maximum):
59    ok, value = tui.enter_range("Enter numbered arrow that is best aligned with the paper edge (1-%d): "
60                        % maximum,
61                        1,
62                        maximum)
63    if not ok:
64        sys.exit(0)
65
66    return ok, value
67
68
69def colorAdj(line, maximum):
70    ok, value = tui.enter_range("Enter the numbered box on line %s that is best color matched to the background color (1-%d): " %
71                        (line, maximum),
72                        1,
73                        maximum)
74    if not ok:
75        sys.exit(0)
76
77    return ok, value
78
79
80def bothPensRequired():
81    log.error("Cannot perform alignment with 0 or 1 cartridges installed.\nPlease install both cartridges and try again.")
82
83
84def invalidPen():
85    log.error("Invalid cartridge(s) installed.\nPlease install valid cartridges and try again.")
86
87
88def invalidPen2():
89    log.error("Invalid cartridge(s) installed. Cannot align with only the photo cartridge installed.\nPlease install other cartridges and try again.")
90
91
92def aioUI1():
93    log.info("To perform alignment, you will need the alignment page that is automatically\nprinted after you install a print cartridge.")
94    log.info("\np\t\tPrint the alignment page and continue.")
95    log.info("n\t\tDo Not print the alignment page (you already have one) and continue.")
96    log.info("q\t\tQuit.\n")
97
98    ok, choice = tui.enter_choice("Choice (p=print page*, n=do not print page, q=quit) ? ", ['p', 'n', 'q'], 'p')
99
100    if choice == 'q':
101        sys.exit(0)
102
103    return choice == 'y'
104
105
106def type10and11and14Align(pattern, align_type):
107    controls = maint.align10and11and14Controls(pattern, align_type)
108    values = []
109    s_controls = list(controls.keys())
110    s_controls.sort()
111
112    for line in s_controls:
113        if not controls[line][0]:
114            values.append(0)
115        else:
116            ok, value = tui.enter_range("Enter the numbered box on line %s where the inner lines best line up with the outer lines (1-%d): "
117                % (line, controls[line][1]),  1, controls[line][1])
118            values.append(value)
119
120            if not ok:
121                sys.exit(0)
122
123    return values
124
125
126def aioUI2():
127    log.info("")
128    log.info(log.bold("Follow these steps to complete the alignment:"))
129    log.info("1. Place the alignment page, with the printed side facing down, ")
130    log.info("   in the scanner.")
131    log.info("2. Press the Enter or Scan button on the printer.")
132    log.info('3. "Alignment Complete" will be displayed when the process is finished (on some models).')
133
134
135
136
137try:
138    mod = module.Module(__mod__, __title__, __version__, __doc__, None,
139                        (INTERACTIVE_MODE, GUI_MODE), (UI_TOOLKIT_QT4, UI_TOOLKIT_QT5))
140
141    mod.setUsage(module.USAGE_FLAG_DEVICE_ARGS,
142                 see_also_list=['hp-clean', 'hp-colorcal', 'hp-linefeedcal',
143                                'hp-pqdiag'])
144
145    opts, device_uri, printer_name, mode, ui_toolkit, lang = \
146        mod.parseStdOpts()
147
148    device_uri = mod.getDeviceUri(device_uri, printer_name,
149         filter={'align-type': (operator.ne, ALIGN_TYPE_NONE)})
150
151    if not device_uri:
152        sys.exit(1)
153    log.info("Using device : %s\n" % device_uri)
154    if mode == GUI_MODE:
155        if not utils.canEnterGUIMode4():
156            log.error("%s -u/--gui requires Qt4 GUI support. Entering interactive mode." % __mod__)
157            mode = INTERACTIVE_MODE
158
159    if mode == INTERACTIVE_MODE:
160        try:
161            d = device.Device(device_uri, printer_name)
162        except Error as e:
163            log.error("Unable to open device: %s" % e.msg)
164            sys.exit(0)
165
166        try:
167            try:
168                d.open()
169            except Error:
170                log.error("Device is busy or in an error state. Please check device and try again.")
171                sys.exit(1)
172
173            if d.isIdleAndNoError():
174                align_type = d.mq.get('align-type', ALIGN_TYPE_NONE)
175                log.debug("Alignment type=%d" % align_type)
176                d.close()
177
178                if align_type == ALIGN_TYPE_UNSUPPORTED:
179                    log.error("Alignment through HPLIP not supported for this printer. Please use the printer's front panel to perform cartridge alignment.")
180
181                elif align_type == ALIGN_TYPE_AUTO:
182                    maint.AlignType1PML(d, tui.load_paper_prompt)
183
184                elif align_type == ALIGN_TYPE_AIO:
185                    maint.AlignType13(d, tui.load_paper_prompt, tui.load_scanner_for_align_prompt)
186
187                elif align_type == ALIGN_TYPE_8XX:
188                    maint.AlignType2(d, tui.load_paper_prompt, enterAlignmentNumber,
189                                      bothPensRequired)
190
191                elif align_type in (ALIGN_TYPE_9XX,ALIGN_TYPE_9XX_NO_EDGE_ALIGN):
192                    maint.AlignType3(d, tui.load_paper_prompt, enterAlignmentNumber,
193                                      enterPaperEdge, update_spinner)
194
195                elif align_type == ALIGN_TYPE_LIDIL_AIO:
196                    maint.AlignType6(d, aioUI1, aioUI2, tui.load_paper_prompt)
197
198                elif align_type == ALIGN_TYPE_DESKJET_450:
199                    maint.AlignType8(d, tui.load_paper_prompt, enterAlignmentNumber)
200
201                elif align_type in (ALIGN_TYPE_LIDIL_0_3_8, ALIGN_TYPE_LIDIL_0_4_3, ALIGN_TYPE_LIDIL_VIP):
202
203                    maint.AlignxBow(d, align_type, tui.load_paper_prompt, enterAlignmentNumber, enterPaperEdge,
204                                     invalidPen, colorAdj)
205
206                elif align_type  == ALIGN_TYPE_LBOW:
207                    maint.AlignType10(d, tui.load_paper_prompt, type10and11and14Align)
208
209                elif align_type == ALIGN_TYPE_LIDIL_0_5_4:
210                    maint.AlignType11(d, tui.load_paper_prompt, type10and11and14Align, invalidPen2)
211
212                elif align_type == ALIGN_TYPE_OJ_PRO:
213                    maint.AlignType12(d, tui.load_paper_prompt)
214
215                elif align_type == ALIGN_TYPE_LIDIL_DJ_D1600:
216                    maint.AlignType14(d, tui.load_paper_prompt, type10and11and14Align, invalidPen2)
217
218                elif align_type == ALIGN_TYPE_LEDM:
219                    maint.AlignType15(d, tui.load_paper_prompt, aioUI2)
220
221                elif align_type == ALIGN_TYPE_LEDM_MANUAL:
222                    maint.AlignType16(d, tui.load_paper_prompt, enterAlignmentNumber)
223
224                elif align_type == ALIGN_TYPE_LEDM_FF_CC_0:
225                    maint.AlignType17(d, tui.load_paper_prompt, aioUI2)
226
227                else:
228                    log.error("Invalid alignment type.")
229
230            else:
231                log.error("Device is busy or in an error state. Please check device and try again.")
232
233        finally:
234            d.close()
235
236    else: # GUI_MODE (qt4)
237        # try:
238        #     from PyQt4.QtGui import QApplication
239        #     from ui4.aligndialog import AlignDialog
240        # except ImportError:
241        #     log.error("Unable to load Qt4 support. Is it installed?")
242        #     sys.exit(1)
243        QApplication, ui_package = utils.import_dialog(ui_toolkit)
244        ui = import_module(ui_package + ".aligndialog")
245
246
247        #try:
248        if 1:
249            app = QApplication(sys.argv)
250            dlg = ui.AlignDialog(None, device_uri)
251            dlg.show()
252            try:
253                log.debug("Starting GUI loop...")
254                app.exec_()
255            except KeyboardInterrupt:
256                sys.exit(0)
257
258        #finally:
259        if 1:
260            sys.exit(0)
261
262except KeyboardInterrupt:
263    log.error("User exit")
264
265
266log.info("")
267log.info('Done.')
268