Esempio n. 1
0
    def __init__(self, main_window, page):
        self.page = page

        widget_tree = load_uifile(
            os.path.join("pageeditor", "pageeditor.glade"))

        self.__dialog = widget_tree.get_object("dialogPageEditing")
        self.__dialog.set_transient_for(main_window.window)

        img_scrollbars = widget_tree.get_object("scrolledwindowOriginal")
        img_canvas = Canvas(img_scrollbars)
        img_canvas.set_visible(True)
        img_scrollbars.add(img_canvas)

        self.__original_img_widgets = {
            'img': img_canvas,
            'scrolledwindow': img_scrollbars,
            'eventbox': widget_tree.get_object("eventboxOriginal"),
            'zoom': widget_tree.get_object("adjustmentZoom"),
        }
        self.__result_img_widget = widget_tree.get_object("imageResult")
        self.__buttons = {
            'cutting': widget_tree.get_object("togglebuttonCutting"),
            'rotate': {
                'clockwise':
                (widget_tree.get_object("buttonRotateClockwise"), 90),
                'counter_clockwise':
                (widget_tree.get_object("buttonRotateCounterClockwise"), -90),
            }
        }

        self.__cut_grips = None

        self.__original_img_widgets['scrolledwindow'].connect(
            "size-allocate",
            lambda widget, size: GLib.idle_add(self.__on_size_allocate))
        self.__buttons['cutting'].connect(
            "toggled",
            lambda widget: GLib.idle_add(self.__on_cutting_button_toggled_cb))
        self.__buttons['rotate']['clockwise'][0].connect(
            "clicked", lambda widget: GLib.idle_add(
                self.__on_rotate_activated_cb, widget))
        self.__buttons['rotate']['counter_clockwise'][0].connect(
            "clicked", lambda widget: GLib.idle_add(
                self.__on_rotate_activated_cb, widget))

        self.page = page
        self.img = self.page.img

        self.__changes = []
Esempio n. 2
0
    def __init__(self, main_scheduler, mainwindow_gui, config):
        super(SettingsWindow, self).__init__()

        self.schedulers = {
            'main': main_scheduler,
            'progress': JobScheduler('progress'),
        }
        self.local_schedulers = [
            self.schedulers['progress'],
        ]

        widget_tree = load_uifile(
            os.path.join("settingswindow", "settingswindow.glade"))
        # self.widget_tree is for tests/screenshots ONLY
        self.widget_tree = widget_tree

        distrib = platform.dist()
        if distrib:
            distrib = distrib[0].lower()
            logger.info("Distribution: [%s]" % distrib)
            for widget in widget_tree.get_objects():
                if type(widget) == Gtk.LinkButton:
                    uri = widget.get_uri()
                    uri += "#" + distrib
                    widget.set_uri(uri)

        self.window = widget_tree.get_object("windowSettings")
        self.window.set_transient_for(mainwindow_gui)

        self.__config = config

        self.workdir_chooser = widget_tree.get_object("filechooserbutton")

        self.ocr_settings = {
            "enabled": {
                'gui': widget_tree.get_object("checkbuttonOcrEnabled")
            },
            "lang": {
                'gui': widget_tree.get_object("comboboxLang"),
                'store': widget_tree.get_object("liststoreOcrLang"),
            },
        }

        actions = {
            "delete-event": (
                [self.window],
                ActionApplySettings(self, config),
            ),
            "toggle_ocr": (
                [self.ocr_settings['enabled']['gui']],
                ActionToggleOCRState(self),
            ),
            "select_scanner": (
                [widget_tree.get_object("comboboxDevices")],
                ActionSelectScanner(self)
            ),
            "select_source": (
                [widget_tree.get_object("comboboxScanSources")],
                ActionSelectSource(self)
            ),
            "scan_calibration": (
                [widget_tree.get_object("buttonScanCalibration")],
                ActionScanCalibration(self)
            )
        }

        self.device_settings = {
            "devid": {
                'gui': widget_tree.get_object("comboboxDevices"),
                'stores': {
                    'loaded': widget_tree.get_object("liststoreDevice"),
                },
                'nb_elements': 0,
                'active_idx': -1,
            },
            "has_feeder": False,
            "source": {
                'gui': widget_tree.get_object("comboboxScanSources"),
                'stores': {
                    'loaded': widget_tree.get_object("liststoreScanSources"),
                },
                'nb_elements': 0,
                'active_idx': -1,
            },
            "resolution": {
                'gui': widget_tree.get_object("comboboxResolution"),
                'stores': {
                    'loaded': widget_tree.get_object("liststoreResolution"),
                },
                'nb_elements': 0,
                'active_idx': -1,
            },
        }

        img_scrollbars = widget_tree.get_object("scrolledwindowCalibration")
        img_canvas = Canvas(img_scrollbars)
        img_canvas.set_visible(True)
        img_scrollbars.add(img_canvas)

        self.calibration = {
            "scan_button": widget_tree.get_object("buttonScanCalibration"),
            "image_gui": img_canvas,
            "image": None,
            "image_eventbox": widget_tree.get_object("eventboxCalibration"),
            "image_scrollbars": img_scrollbars,
            "resolution": DEFAULT_CALIBRATION_RESOLUTION,
            "zoom": widget_tree.get_object("adjustmentZoom"),
        }

        self.grips = None

        self.progressbar = widget_tree.get_object("progressbarScan")
        self.__scan_start = 0.0

        self.job_factories = {
            "device_finder": JobFactoryDeviceFinder(
                self, config['scanner_devid'].value
            ),
            "source_finder": JobFactorySourceFinder(
                self, config['scanner_source'].value
            ),
            "resolution_finder": JobFactoryResolutionFinder(
                self,
                config['scanner_resolution'].value,
                RECOMMENDED_SCAN_RESOLUTION
            ),
            "scan": JobFactoryCalibrationScan(
                self,
                self.device_settings['resolution']['stores']['loaded']
            ),
            "progress_updater": JobFactoryProgressUpdater(self.progressbar),
        }

        try:
            translations = gettext.translation(
                'iso639-3', pycountry.LOCALES_DIR
            )
            logger.info("Language name translations loaded")
        except Exception:
            logger.exception("Unable to load languages translations")
            translations = None

        ocr_tools = pyocr.get_available_tools()

        if len(ocr_tools) == 0:
            short_ocr_langs = []
        else:
            short_ocr_langs = ocr_tools[0].get_available_languages()
        ocr_langs = []
        for short in short_ocr_langs:
            if short in ['equ', 'osd']:
                # ignore some (equ = equation ; osd = orientation detection)
                continue
            llang = self.__get_short_to_long_langs(short)
            if llang:
                if not translations:
                    tlang = llang
                else:
                    tlang = translations.gettext(llang)
                logger.info("Translation: {} | {}".format(llang, tlang))
            if not tlang:
                logger.error("Warning: Long name not found for language "
                             "'%s'." % short)
                logger.warning("  Will use short name as long name.")
                tlang = short
            ocr_langs.append((short, tlang))
        ocr_langs.sort(key=lambda lang: lang[1])

        self.ocr_settings['lang']['store'].clear()
        for (short_lang, long_lang) in ocr_langs:
            self.ocr_settings['lang']['store'].append([long_lang, short_lang])

        for (k, v) in actions.items():
            v[1].connect(v[0])

        self.window.connect("destroy", self.__on_destroy)

        self.display_config(config)

        self.window.set_visible(True)

        for scheduler in self.local_schedulers:
            scheduler.start()

        job = self.job_factories['device_finder'].make()
        self.schedulers['main'].schedule(job)
Esempio n. 3
0
    def __init__(self, main_scheduler, mainwindow_gui, config):
        super(SettingsWindow, self).__init__()

        self.schedulers = {
            'main': main_scheduler,
            'progress': JobScheduler('progress'),
        }
        self.local_schedulers = [
            self.schedulers['progress'],
        ]

        widget_tree = load_uifile(
            os.path.join("settingswindow", "settingswindow.glade"))

        distrib = platform.dist()
        if distrib:
            distrib = distrib[0].lower()
            logger.info("Distribution: [%s]" % distrib)
            for widget in widget_tree.get_objects():
                if type(widget) == Gtk.LinkButton:
                    uri = widget.get_uri()
                    uri += "#" + distrib
                    widget.set_uri(uri)

        self.window = widget_tree.get_object("windowSettings")
        self.window.set_transient_for(mainwindow_gui)

        self.__config = config

        self.workdir_chooser = widget_tree.get_object("filechooserbutton")

        self.ocr_settings = {
            "enabled": {
                'gui': widget_tree.get_object("checkbuttonOcrEnabled")
            },
            "lang": {
                'gui': widget_tree.get_object("comboboxLang"),
                'store': widget_tree.get_object("liststoreOcrLang"),
            },
        }

        actions = {
            "delete-event": (
                [self.window],
                ActionApplySettings(self, config),
            ),
            "toggle_ocr": (
                [self.ocr_settings['enabled']['gui']],
                ActionToggleOCRState(self),
            ),
            "select_scanner": (
                [widget_tree.get_object("comboboxDevices")],
                ActionSelectScanner(self)
            ),
            "select_source": (
                [widget_tree.get_object("comboboxScanSources")],
                ActionSelectSource(self)
            ),
            "scan_calibration": (
                [widget_tree.get_object("buttonScanCalibration")],
                ActionScanCalibration(self)
            )
        }

        self.device_settings = {
            "devid": {
                'gui': widget_tree.get_object("comboboxDevices"),
                'stores': {
                    'loaded': widget_tree.get_object("liststoreDevice"),
                },
                'nb_elements': 0,
                'active_idx': -1,
            },
            "has_feeder": False,
            "source": {
                'gui': widget_tree.get_object("comboboxScanSources"),
                'stores': {
                    'loaded': widget_tree.get_object("liststoreScanSources"),
                },
                'nb_elements': 0,
                'active_idx': -1,
            },
            "resolution": {
                'gui': widget_tree.get_object("comboboxResolution"),
                'stores': {
                    'loaded': widget_tree.get_object("liststoreResolution"),
                },
                'nb_elements': 0,
                'active_idx': -1,
            },
        }

        img_scrollbars = widget_tree.get_object("scrolledwindowCalibration")
        img_canvas = Canvas(img_scrollbars)
        img_canvas.set_visible(True)
        img_scrollbars.add(img_canvas)

        self.calibration = {
            "scan_button": widget_tree.get_object("buttonScanCalibration"),
            "image_gui": img_canvas,
            "image": None,
            "image_eventbox": widget_tree.get_object("eventboxCalibration"),
            "image_scrollbars": img_scrollbars,
            "resolution": DEFAULT_CALIBRATION_RESOLUTION,
            "zoom": widget_tree.get_object("adjustmentZoom"),
        }

        self.grips = None

        self.progressbar = widget_tree.get_object("progressbarScan")
        self.__scan_start = 0.0

        self.job_factories = {
            "device_finder": JobFactoryDeviceFinder(
                self, config['scanner_devid'].value
            ),
            "source_finder": JobFactorySourceFinder(
                self, config['scanner_source'].value
            ),
            "resolution_finder": JobFactoryResolutionFinder(
                self,
                config['scanner_resolution'].value,
                RECOMMENDED_SCAN_RESOLUTION
            ),
            "scan": JobFactoryCalibrationScan(
                self,
                self.device_settings['resolution']['stores']['loaded']
            ),
            "progress_updater": JobFactoryProgressUpdater(self.progressbar),
        }

        ocr_tools = pyocr.get_available_tools()
        if len(ocr_tools) == 0:
            ocr_langs = []
        else:
            ocr_langs = ocr_tools[0].get_available_languages()
        ocr_langs = self.__get_short_to_long_langs(ocr_langs)
        ocr_langs.sort(key=lambda lang: lang[1])
        ocr_langs.insert(0, (None, _("Disable OCR")))

        self.ocr_settings['lang']['store'].clear()
        for (short_lang, long_lang) in ocr_langs:
            self.ocr_settings['lang']['store'].append([long_lang, short_lang])

        for (k, v) in actions.items():
            v[1].connect(v[0])

        self.window.connect("destroy", self.__on_destroy)

        self.display_config(config)

        self.window.set_visible(True)

        for scheduler in self.local_schedulers:
            scheduler.start()

        job = self.job_factories['device_finder'].make()
        self.schedulers['main'].schedule(job)
Esempio n. 4
0
    def __init__(self, main_window, config):
        GObject.GObject.__init__(self)

        self.main_window = main_window

        self.schedulers = {
            'main': main_window.schedulers['main'],
        }

        self.scanned_pages = 0

        self.__config = config

        widget_tree = load_uifile(os.path.join("multiscan", "multiscan.glade"))

        self.window = widget_tree.get_object("dialogMultiscan")

        scan_scrollbars = widget_tree.get_object("scrolledwindowScan")
        self.scan_canvas = Canvas(scan_scrollbars)
        self.scan_canvas.set_visible(True)
        scan_scrollbars.add(self.scan_canvas)

        self.lists = {
            'docs': {
                'gui': widget_tree.get_object("treeviewScanList"),
                'model': widget_tree.get_object("liststoreScanList"),
                'columns': {
                    'nb_pages':
                    widget_tree.get_object("treeviewcolumnNbPages"),
                },
                'include_current_doc': False,
            },
        }

        self.removeDocButton = widget_tree.get_object("buttonRemoveDoc")
        self.removeDocButton.set_sensitive(False)

        actions = {
            'add_doc': (
                [widget_tree.get_object("buttonAddDoc")],
                ActionAddDoc(self, config),
            ),
            'select_doc': (
                [widget_tree.get_object("treeviewScanList")],
                ActionSelectDoc(self),
            ),
            'start_edit_doc': (
                [widget_tree.get_object("buttonEditDoc")],
                ActionStartEditDoc(self),
            ),
            'end_edit_doc': (
                [widget_tree.get_object("cellrenderertextNbPages")],
                ActionEndEditDoc(self),
            ),
            'del_doc': (
                [self.removeDocButton],
                ActionRemoveDoc(self),
            ),
            'cancel':
            ([widget_tree.get_object("buttonCancel")], ActionCancel(self)),
            'scan': (
                [widget_tree.get_object("buttonOk")],
                ActionScan(self, config, main_window.docsearch, main_window),
            ),
        }

        for action in [
                'add_doc', 'select_doc', 'start_edit_doc', 'end_edit_doc',
                'del_doc', 'scan', 'cancel'
        ]:
            actions[action][1].connect(actions[action][0])

        self.to_disable_on_scan = [
            actions['add_doc'][0][0],
            actions['start_edit_doc'][0][0],
            actions['del_doc'][0][0],
            actions['scan'][0][0],
        ]

        self.lists['docs']['model'].clear()
        if len(main_window.doc.pages) > 0 and main_window.doc.can_edit:
            self.lists['docs']['model'].append([
                _("Current document (%s)") % (str(main_window.doc)),
                "0",  # nb_pages
                True,  # can_edit (nb_pages)
                0,  # scan_progress_int
                "",  # scan_progress_txt
                False,  # can_delete
            ])
            self.lists['docs']['include_current_doc'] = True
        else:
            # add a first document to the list (the user will need one anyway)
            actions['add_doc'][1].do()

        self.dialog = widget_tree.get_object("dialogMultiscan")
        self.dialog.connect("destroy", self.__on_destroy)

        self.dialog.set_transient_for(main_window.window)
        self.dialog.set_visible(True)
Esempio n. 5
0
class MultiscanDialog(GObject.GObject):
    __gsignals__ = {
        'need-doclist-refresh': (GObject.SignalFlags.RUN_LAST, None, ()),
        'need-show-page':
        (GObject.SignalFlags.RUN_LAST, None, (GObject.TYPE_PYOBJECT, )),
    }

    def __init__(self, main_window, config):
        GObject.GObject.__init__(self)

        self.main_window = main_window

        self.schedulers = {
            'main': main_window.schedulers['main'],
        }

        self.scanned_pages = 0

        self.__config = config

        widget_tree = load_uifile(os.path.join("multiscan", "multiscan.glade"))

        self.window = widget_tree.get_object("dialogMultiscan")

        scan_scrollbars = widget_tree.get_object("scrolledwindowScan")
        self.scan_canvas = Canvas(scan_scrollbars)
        self.scan_canvas.set_visible(True)
        scan_scrollbars.add(self.scan_canvas)

        self.lists = {
            'docs': {
                'gui': widget_tree.get_object("treeviewScanList"),
                'model': widget_tree.get_object("liststoreScanList"),
                'columns': {
                    'nb_pages':
                    widget_tree.get_object("treeviewcolumnNbPages"),
                },
                'include_current_doc': False,
            },
        }

        self.removeDocButton = widget_tree.get_object("buttonRemoveDoc")
        self.removeDocButton.set_sensitive(False)

        actions = {
            'add_doc': (
                [widget_tree.get_object("buttonAddDoc")],
                ActionAddDoc(self, config),
            ),
            'select_doc': (
                [widget_tree.get_object("treeviewScanList")],
                ActionSelectDoc(self),
            ),
            'start_edit_doc': (
                [widget_tree.get_object("buttonEditDoc")],
                ActionStartEditDoc(self),
            ),
            'end_edit_doc': (
                [widget_tree.get_object("cellrenderertextNbPages")],
                ActionEndEditDoc(self),
            ),
            'del_doc': (
                [self.removeDocButton],
                ActionRemoveDoc(self),
            ),
            'cancel':
            ([widget_tree.get_object("buttonCancel")], ActionCancel(self)),
            'scan': (
                [widget_tree.get_object("buttonOk")],
                ActionScan(self, config, main_window.docsearch, main_window),
            ),
        }

        for action in [
                'add_doc', 'select_doc', 'start_edit_doc', 'end_edit_doc',
                'del_doc', 'scan', 'cancel'
        ]:
            actions[action][1].connect(actions[action][0])

        self.to_disable_on_scan = [
            actions['add_doc'][0][0],
            actions['start_edit_doc'][0][0],
            actions['del_doc'][0][0],
            actions['scan'][0][0],
        ]

        self.lists['docs']['model'].clear()
        if len(main_window.doc.pages) > 0 and main_window.doc.can_edit:
            self.lists['docs']['model'].append([
                _("Current document (%s)") % (str(main_window.doc)),
                "0",  # nb_pages
                True,  # can_edit (nb_pages)
                0,  # scan_progress_int
                "",  # scan_progress_txt
                False,  # can_delete
            ])
            self.lists['docs']['include_current_doc'] = True
        else:
            # add a first document to the list (the user will need one anyway)
            actions['add_doc'][1].do()

        self.dialog = widget_tree.get_object("dialogMultiscan")
        self.dialog.connect("destroy", self.__on_destroy)

        self.dialog.set_transient_for(main_window.window)
        self.dialog.set_visible(True)

    def set_mouse_cursor(self, cursor):
        self.dialog.get_window().set_cursor({
            "Normal":
            None,
            "Busy":
            Gdk.Cursor.new(Gdk.CursorType.WATCH),
        }[cursor])
        pass

    def on_global_scan_start_cb(self):
        for el in self.to_disable_on_scan:
            el.set_sensitive(False)
        for line in self.lists['docs']['model']:
            line[2] = False  # disable nb page edit
            line[5] = False  # disable deletion
        self.set_mouse_cursor("Busy")

    def on_scan_start_cb(self, page_scan):
        progression = ("%d / %d" % (page_scan.page_nb, page_scan.total_pages))
        self.lists['docs']['model'][page_scan.line_idx][1] = progression
        progression = (page_scan.page_nb * 100 / page_scan.total_pages)
        self.lists['docs']['model'][page_scan.line_idx][3] = progression
        self.lists['docs']['model'][page_scan.line_idx][4] = _("Scanning")

    def on_ocr_start_cb(self, page_scan):
        progression = ((page_scan.page_nb * 100 + 50) / page_scan.total_pages)
        self.lists['docs']['model'][page_scan.line_idx][3] = progression
        self.lists['docs']['model'][page_scan.line_idx][4] = _("Reading")

    def on_scan_done_cb(self, page_scan):
        progression = ("%d / %d" %
                       (page_scan.page_nb + 1, page_scan.total_pages))
        self.lists['docs']['model'][page_scan.line_idx][1] = progression
        progression = ((page_scan.page_nb * 100 + 100) / page_scan.total_pages)
        self.lists['docs']['model'][page_scan.line_idx][3] = progression
        self.lists['docs']['model'][page_scan.line_idx][4] = _("Done")
        self.scanned_pages += 1

    def on_global_scan_end_cb(self):
        self.emit('need-doclist-refresh')
        self.set_mouse_cursor("Normal")
        msg = _("All the pages have been scanned")
        dialog = Gtk.MessageDialog(self.dialog,
                                   flags=Gtk.DialogFlags.MODAL,
                                   message_type=Gtk.MessageType.INFO,
                                   buttons=Gtk.ButtonsType.OK,
                                   message_format=msg)
        dialog.run()
        dialog.destroy()
        self.dialog.destroy()

    def on_scan_error_cb(self, page_scan, exception):
        logger.warning("Scan failed: %s" % str(exception))
        logger.info("Scan job cancelled")

        self.emit('need-doclist-refresh')
        self.set_mouse_cursor("Normal")

        if isinstance(exception, StopIteration):
            msg = _("Less pages than expected have been Img"
                    " (got %d pages)") % (self.scanned_pages)
            dialog = Gtk.MessageDialog(self.dialog,
                                       flags=Gtk.DialogFlags.MODAL,
                                       message_type=Gtk.MessageType.WARNING,
                                       buttons=Gtk.ButtonsType.OK,
                                       message_format=msg)
            dialog.run()
            dialog.destroy()
        else:
            raise exception
        self.dialog.destroy()

    def __on_destroy(self, window=None):
        logger.info("Multi-scan dialog destroyed")
Esempio n. 6
0
    def __init__(self, main_window, config):
        GObject.GObject.__init__(self)

        self.main_window = main_window

        self.schedulers = {
            'main': main_window.schedulers['main'],
        }

        self.scanned_pages = 0

        self.__config = config

        widget_tree = load_uifile(
            os.path.join("multiscan", "multiscan.glade"))
        # self.widget_tree is for tests/screenshots ONLY
        self.widget_tree = widget_tree

        self.window = widget_tree.get_object("dialogMultiscan")

        scan_scrollbars = widget_tree.get_object("scrolledwindowScan")
        self.scan_canvas = Canvas(scan_scrollbars)
        self.scan_canvas.set_visible(True)
        scan_scrollbars.add(self.scan_canvas)

        self.lists = {
            'docs': {
                'gui': widget_tree.get_object("treeviewScanList"),
                'model': widget_tree.get_object("liststoreScanList"),
                'columns': {
                    'nb_pages':
                    widget_tree.get_object("treeviewcolumnNbPages"),
                },
                'include_current_doc': False,
            },
        }

        self.removeDocButton = widget_tree.get_object("buttonRemoveDoc")
        self.removeDocButton.set_sensitive(False)

        self.actions = {
            'add_doc': (
                [widget_tree.get_object("buttonAddDoc")],
                ActionAddDoc(self, config),
            ),
            'select_doc': (
                [widget_tree.get_object("treeviewScanList")],
                ActionSelectDoc(self),
            ),
            'start_edit_doc': (
                [widget_tree.get_object("buttonEditDoc")],
                ActionStartEditDoc(self),
            ),
            'end_edit_doc': (
                [widget_tree.get_object("cellrenderertextNbPages")],
                ActionEndEditDoc(self),
            ),
            'del_doc': (
                [self.removeDocButton],
                ActionRemoveDoc(self),
            ),
            'cancel': (
                [widget_tree.get_object("buttonCancel")],
                ActionCancel(self)
            ),
            'scan': (
                [widget_tree.get_object("buttonOk")],
                ActionScan(self, config, main_window.docsearch,
                           main_window),
            ),
        }

        for action in ['add_doc', 'select_doc', 'start_edit_doc',
                       'end_edit_doc', 'del_doc',
                       'scan', 'cancel']:
            self.actions[action][1].connect(self.actions[action][0])

        self.to_disable_on_scan = [
            self.actions['add_doc'][0][0],
            self.actions['start_edit_doc'][0][0],
            self.actions['del_doc'][0][0],
            self.actions['scan'][0][0],
        ]

        self.lists['docs']['model'].clear()
        if len(main_window.doc.pages) > 0 and main_window.doc.can_edit:
            self.lists['docs']['model'].append([
                _("Current document (%s)") % (str(main_window.doc)),
                "0",  # nb_pages
                True,  # can_edit (nb_pages)
                0,  # scan_progress_int
                "",  # scan_progress_txt
                False,  # can_delete
            ])
            self.lists['docs']['include_current_doc'] = True
        else:
            # add a first document to the list (the user will need one anyway)
            self.actions['add_doc'][1].do()

        self.dialog = widget_tree.get_object("dialogMultiscan")
        self.dialog.connect("destroy", self.__on_destroy)

        self.dialog.set_transient_for(main_window.window)
        self.dialog.set_visible(True)
Esempio n. 7
0
class MultiscanDialog(GObject.GObject):
    __gsignals__ = {
        'need-doclist-refresh': (GObject.SignalFlags.RUN_LAST, None, ()),
        'need-show-page': (GObject.SignalFlags.RUN_LAST, None,
                           (GObject.TYPE_PYOBJECT,)),
    }

    def __init__(self, main_window, config):
        GObject.GObject.__init__(self)

        self.main_window = main_window

        self.schedulers = {
            'main': main_window.schedulers['main'],
        }

        self.scanned_pages = 0

        self.__config = config

        widget_tree = load_uifile(
            os.path.join("multiscan", "multiscan.glade"))
        # self.widget_tree is for tests/screenshots ONLY
        self.widget_tree = widget_tree

        self.window = widget_tree.get_object("dialogMultiscan")

        scan_scrollbars = widget_tree.get_object("scrolledwindowScan")
        self.scan_canvas = Canvas(scan_scrollbars)
        self.scan_canvas.set_visible(True)
        scan_scrollbars.add(self.scan_canvas)

        self.lists = {
            'docs': {
                'gui': widget_tree.get_object("treeviewScanList"),
                'model': widget_tree.get_object("liststoreScanList"),
                'columns': {
                    'nb_pages':
                    widget_tree.get_object("treeviewcolumnNbPages"),
                },
                'include_current_doc': False,
            },
        }

        self.removeDocButton = widget_tree.get_object("buttonRemoveDoc")
        self.removeDocButton.set_sensitive(False)

        self.actions = {
            'add_doc': (
                [widget_tree.get_object("buttonAddDoc")],
                ActionAddDoc(self, config),
            ),
            'select_doc': (
                [widget_tree.get_object("treeviewScanList")],
                ActionSelectDoc(self),
            ),
            'start_edit_doc': (
                [widget_tree.get_object("buttonEditDoc")],
                ActionStartEditDoc(self),
            ),
            'end_edit_doc': (
                [widget_tree.get_object("cellrenderertextNbPages")],
                ActionEndEditDoc(self),
            ),
            'del_doc': (
                [self.removeDocButton],
                ActionRemoveDoc(self),
            ),
            'cancel': (
                [widget_tree.get_object("buttonCancel")],
                ActionCancel(self)
            ),
            'scan': (
                [widget_tree.get_object("buttonOk")],
                ActionScan(self, config, main_window.docsearch,
                           main_window),
            ),
        }

        for action in ['add_doc', 'select_doc', 'start_edit_doc',
                       'end_edit_doc', 'del_doc',
                       'scan', 'cancel']:
            self.actions[action][1].connect(self.actions[action][0])

        self.to_disable_on_scan = [
            self.actions['add_doc'][0][0],
            self.actions['start_edit_doc'][0][0],
            self.actions['del_doc'][0][0],
            self.actions['scan'][0][0],
        ]

        self.lists['docs']['model'].clear()
        if len(main_window.doc.pages) > 0 and main_window.doc.can_edit:
            self.lists['docs']['model'].append([
                _("Current document (%s)") % (str(main_window.doc)),
                "0",  # nb_pages
                True,  # can_edit (nb_pages)
                0,  # scan_progress_int
                "",  # scan_progress_txt
                False,  # can_delete
            ])
            self.lists['docs']['include_current_doc'] = True
        else:
            # add a first document to the list (the user will need one anyway)
            self.actions['add_doc'][1].do()

        self.dialog = widget_tree.get_object("dialogMultiscan")
        self.dialog.connect("destroy", self.__on_destroy)

        self.dialog.set_transient_for(main_window.window)
        self.dialog.set_visible(True)

    def set_mouse_cursor(self, cursor):
        self.dialog.get_window().set_cursor({
            "Normal": None,
            "Busy": Gdk.Cursor.new(Gdk.CursorType.WATCH),
        }[cursor])
        pass

    def on_global_scan_start_cb(self):
        for el in self.to_disable_on_scan:
            el.set_sensitive(False)
        for line in self.lists['docs']['model']:
            line[2] = False  # disable nb page edit
            line[5] = False  # disable deletion
        self.set_mouse_cursor("Busy")

    def on_scan_start_cb(self, page_scan):
        progression = ("%d / %d" % (page_scan.page_nb, page_scan.total_pages))
        self.lists['docs']['model'][page_scan.line_idx][1] = progression
        progression = (page_scan.page_nb * 100 / page_scan.total_pages)
        self.lists['docs']['model'][page_scan.line_idx][3] = progression
        self.lists['docs']['model'][page_scan.line_idx][4] = _("Scanning")

    def on_ocr_start_cb(self, page_scan):
        progression = ((page_scan.page_nb * 100 + 50) / page_scan.total_pages)
        self.lists['docs']['model'][page_scan.line_idx][3] = progression
        self.lists['docs']['model'][page_scan.line_idx][4] = _("Reading")

    def on_scan_done_cb(self, page_scan):
        progression = ("%d / %d" % (page_scan.page_nb + 1,
                                    page_scan.total_pages))
        self.lists['docs']['model'][page_scan.line_idx][1] = progression
        progression = ((page_scan.page_nb * 100 + 100) / page_scan.total_pages)
        self.lists['docs']['model'][page_scan.line_idx][3] = progression
        self.lists['docs']['model'][page_scan.line_idx][4] = _("Done")
        self.scanned_pages += 1

    def on_global_scan_end_cb(self, scan_session):
        try:
            logger.info("Ending scan session")
            scan_session.scan.cancel()
        except Exception as exc:
            logger.warning("Failed to cancel scan: %s", str(exc), exc_info=exc)
        self.emit('need-doclist-refresh')
        self.set_mouse_cursor("Normal")
        msg = _("All the pages have been scanned")
        dialog = Gtk.MessageDialog(self.dialog,
                                   flags=Gtk.DialogFlags.MODAL,
                                   message_type=Gtk.MessageType.INFO,
                                   buttons=Gtk.ButtonsType.OK,
                                   message_format=msg)
        dialog.connect("response", lambda dialog, response:
                       GLib.idle_add(dialog.destroy))
        dialog.connect("response", lambda dialog, response:
                       GLib.idle_add(self.dialog.destroy))
        dialog.show_all()

    def on_scan_error_cb(self, page_scan, exception):
        logger.warning("Scan failed: %s" % str(exception))
        logger.info("Scan job cancelled")

        self.emit('need-doclist-refresh')
        self.set_mouse_cursor("Normal")

        if isinstance(exception, StopIteration):
            msg = _("Less pages than expected have been Img"
                    " (got %d pages)") % (self.scanned_pages)
            dialog = Gtk.MessageDialog(self.dialog,
                                       flags=Gtk.DialogFlags.MODAL,
                                       message_type=Gtk.MessageType.WARNING,
                                       buttons=Gtk.ButtonsType.OK,
                                       message_format=msg)
            dialog.connect("response", lambda dialog, response:
                           GLib.idle_add(dialog.destroy))
            dialog.connect("response", lambda dialog, response:
                           GLib.idle_add(self.dialog.destroy))
            dialog.show_all()
        else:
            # TODO(Jflesch): Dialog
            raise exception

    def __on_destroy(self, window=None):
        logger.info("Multi-scan dialog destroyed")
Esempio n. 8
0
    def __init__(self, main_scheduler, mainwindow_gui, config):
        super(SettingsWindow, self).__init__()

        self.schedulers = {
            'main': main_scheduler,
            'progress': JobScheduler('progress'),
        }
        self.local_schedulers = [
            self.schedulers['progress'],
        ]

        widget_tree = load_uifile(
            os.path.join("settingswindow", "settingswindow.glade"))
        # self.widget_tree is for tests/screenshots ONLY
        self.widget_tree = widget_tree

        distrib = platform.dist()
        if distrib:
            distrib = distrib[0].lower()
            logger.info("Distribution: [%s]" % distrib)
            for widget in widget_tree.get_objects():
                if type(widget) == Gtk.LinkButton:
                    uri = widget.get_uri()
                    uri += "#" + distrib
                    widget.set_uri(uri)

        self.window = widget_tree.get_object("windowSettings")
        self.window.set_transient_for(mainwindow_gui)

        self.__config = config

        self.workdir_chooser = widget_tree.get_object("filechooserbutton")

        self.network_settings = {
            "update": widget_tree.get_object("checkUpdate"),
            "statistics": widget_tree.get_object("checkStatistics")
        }

        self.ocr_settings = {
            "enabled": {
                'gui': widget_tree.get_object("checkbuttonOcrEnabled")
            },
            "lang": {
                'gui': widget_tree.get_object("comboboxLang"),
                'store': widget_tree.get_object("liststoreOcrLang"),
            },
        }

        actions = {
            "delete-event": (
                [self.window],
                ActionApplySettings(self, config),
            ),
            "toggle_ocr": (
                [self.ocr_settings['enabled']['gui']],
                ActionToggleOCRState(self),
            ),
            "select_scanner": (
                [widget_tree.get_object("comboboxDevices")],
                ActionSelectScanner(self)
            ),
            "select_source": (
                [widget_tree.get_object("comboboxScanSources")],
                ActionSelectSource(self)
            ),
            "scan_calibration": (
                [widget_tree.get_object("buttonScanCalibration")],
                ActionScanCalibration(self)
            )
        }

        self.device_settings = {
            "devid": {
                'gui': widget_tree.get_object("comboboxDevices"),
                'stores': {
                    'loaded': widget_tree.get_object("liststoreDevice"),
                },
                'nb_elements': 0,
                'active_idx': -1,
            },
            "has_feeder": False,
            "source": {
                'gui': widget_tree.get_object("comboboxScanSources"),
                'stores': {
                    'loaded': widget_tree.get_object("liststoreScanSources"),
                },
                'nb_elements': 0,
                'active_idx': -1,
            },
            "resolution": {
                'gui': widget_tree.get_object("comboboxResolution"),
                'stores': {
                    'loaded': widget_tree.get_object("liststoreResolution"),
                },
                'nb_elements': 0,
                'active_idx': -1,
            },
        }

        img_scrollbars = widget_tree.get_object("scrolledwindowCalibration")
        img_canvas = Canvas(img_scrollbars)
        img_canvas.set_visible(True)
        img_scrollbars.add(img_canvas)

        self.calibration = {
            "scan_button": widget_tree.get_object("buttonScanCalibration"),
            "image_gui": img_canvas,
            "image": None,
            "image_eventbox": widget_tree.get_object("eventboxCalibration"),
            "image_scrollbars": img_scrollbars,
            "resolution": DEFAULT_CALIBRATION_RESOLUTION,
            "zoom": widget_tree.get_object("adjustmentZoom"),
        }

        self.grips = None

        self.progressbar = widget_tree.get_object("progressbarScan")
        self.__scan_start = 0.0

        self.job_factories = {
            "device_finder": JobFactoryDeviceFinder(
                self, config['scanner_devid'].value
            ),
            "source_finder": JobFactorySourceFinder(
                self, config['scanner_source'].value
            ),
            "resolution_finder": JobFactoryResolutionFinder(
                self,
                config['scanner_resolution'].value,
                RECOMMENDED_SCAN_RESOLUTION
            ),
            "scan": JobFactoryCalibrationScan(
                self,
                self.device_settings['resolution']['stores']['loaded']
            ),
            "progress_updater": JobFactoryProgressUpdater(self.progressbar),
        }

        try:
            translations = gettext.translation(
                'iso639-3', pycountry.LOCALES_DIR
            )
            logger.info("Language name translations loaded")
        except Exception:
            logger.exception("Unable to load languages translations")
            translations = None

        ocr_tools = pyocr.get_available_tools()

        if len(ocr_tools) == 0:
            short_ocr_langs = []
        else:
            short_ocr_langs = ocr_tools[0].get_available_languages()
        ocr_langs = []
        for short in short_ocr_langs:
            if short in ['equ', 'osd']:
                # ignore some (equ = equation ; osd = orientation detection)
                continue
            llang = self.__get_short_to_long_langs(short)
            if llang:
                if not translations:
                    tlang = llang
                else:
                    tlang = translations.gettext(llang)
                logger.info("Translation: {} | {}".format(llang, tlang))
            if not tlang:
                logger.error("Warning: Long name not found for language "
                             "'%s'." % short)
                logger.warning("  Will use short name as long name.")
                tlang = short
            ocr_langs.append((short, tlang))
        ocr_langs.sort(key=lambda lang: lang[1])

        self.ocr_settings['lang']['store'].clear()
        for (short_lang, long_lang) in ocr_langs:
            self.ocr_settings['lang']['store'].append([long_lang, short_lang])

        for (k, v) in actions.items():
            v[1].connect(v[0])

        self.window.connect("destroy", self.__on_destroy)

        self.display_config(config)

        self.window.set_visible(True)

        for scheduler in self.local_schedulers:
            scheduler.start()

        job = self.job_factories['device_finder'].make()
        self.schedulers['main'].schedule(job)
Esempio n. 9
0
    def __init__(self, main_win, config, widget_tree):
        self.__main_win = main_win
        self.__config = config

        self.default_thumbnail = self.__init_default_thumbnail(
            JobDocThumbnailer.SMALL_THUMBNAIL_WIDTH,
            JobDocThumbnailer.SMALL_THUMBNAIL_HEIGHT)

        self.gui = {
            'list': widget_tree.get_object("listboxDocList"),
            'box': widget_tree.get_object("doclist_box"),
            'scrollbars': widget_tree.get_object("scrolledwindowDocList"),
            'spinner': SpinnerAnimation((0, 0)),
        }
        self.gui['loading'] = Canvas(self.gui['scrollbars'])
        self.gui['loading'].set_visible(False)
        self.gui['box'].add(self.gui['loading'])
        self.gui['scrollbars'].connect(
            "size-allocate",
            lambda x, s: GLib.idle_add(self._on_size_allocate))

        self.actions = {
            'open_doc': ([
                self.gui['list'],
            ], ActionOpenSelectedDocument(main_win, config, self)),
        }
        connect_actions(self.actions)

        self.model = {
            'has_new': False,
            'by_row': {},  # Gtk.ListBoxRow: docid
            'by_id': {},  # docid: Gtk.ListBoxRow
            # keep the thumbnails in cache
            'thumbnails': {}  # docid: pixbuf
        }
        self.new_doc = ImgDoc(config['workdir'].value)

        self.job_factories = {
            'doc_thumbnailer': JobFactoryDocThumbnailer(self),
        }
        self.selected_doc = None

        self.gui['scrollbars'].get_vadjustment().connect(
            "value-changed",
            lambda v: GLib.idle_add(self._on_scrollbar_value_changed))

        self.gui['list'].connect(
            "size-allocate",
            lambda w, s: GLib.idle_add(self._on_scrollbar_value_changed))

        self.gui['list'].connect("drag-motion", self._on_drag_motion)
        self.gui['list'].connect("drag-leave", self._on_drag_leave)
        self.gui['list'].connect("drag-data-received",
                                 self._on_drag_data_received)
        self.gui['list'].drag_dest_set(Gtk.DestDefaults.ALL, [],
                                       Gdk.DragAction.MOVE)
        self.gui['list'].drag_dest_add_text_targets()

        self.accel_group = Gtk.AccelGroup()
        self.__main_win.window.add_accel_group(self.accel_group)

        self.show_loading()