#!/usr/bin/env python
# -*- coding: utf-8 -*-
#
# main.py
#
# Copyright 2009-2010 Sandro Mani <manisandro@gmail.com>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
# MA 02110-1301, USA.
import gtk
import os
import sys
import config
import dialogs
import drawingarea
import notifier
import threadtools
import urllib2
import outbuffer
class gimagereader:
def __init__(self,filename=None):
# Read builder
self.builder=gtk.Builder()
self.builder.add_from_file("gimagereader.xml")
self.window=self.builder.get_object("main")
self.status=self.builder.get_object("status_msg")
self.aboutdialog=self.builder.get_object("aboutdialog")
# Some variables
self.curdir=os.path.expanduser("~")
self.filename=None
self.lang_count=0
# Complete the GUI
self.langcombo = gtk.combo_box_new_text()
self.builder.get_object("tb_language").add(self.langcombo)
self.langcombo.show()
self.langcombo.set_sensitive(False)
self.langcombo.connect('changed', self.set_language)
# Load modules
self.drawingarea=drawingarea.Drawingarea(self.builder)
self.notifier=notifier.Notifier(self.builder)
self.outbuffer=outbuffer.Outbuffer(self.builder)
self.conf=config.Config(self.builder)
# Connect signals and show window
self.window.connect("delete-event", self.quit)
#self.window.connect("destroy", self.quit)
dic = { "on_tb_openimg_clicked" : self.open_image,
"on_tb_zoomin_clicked" : (self.drawingarea.set_zoom,"i"),
"on_tb_zoomout_clicked" : (self.drawingarea.set_zoom,"o"),
"on_tb_bestzoom_clicked" : (self.drawingarea.set_zoom,"f"),
"on_tb_resetzoom_clicked" : (self.drawingarea.set_zoom,"r"),
"on_tb_lrotate_clicked" : (self.drawingarea.rotate,+90),
"on_tb_rrotate_clicked" : (self.drawingarea.rotate,-90),
"on_tb_doocr_clicked" : self.recognize,
"on_menu_open_activate" : self.open_image,
"on_menu_config_activate" : self.show_config,
"on_menu_zoomin_activate" : (self.drawingarea.set_zoom,"i"),
"on_menu_zoomout_activate" : (self.drawingarea.set_zoom,"o"),
"on_menu_bestzoom_activate" : (self.drawingarea.set_zoom,"f"),
"on_menu_resetzoom_activate" : (self.drawingarea.set_zoom,"r"),
"on_menu_lrotate_activate" : (self.drawingarea.rotate,+90),
"on_menu_rrotate_activate" : (self.drawingarea.rotate,-90),
"on_menu_about_activate" : self.about,
"gtk_main_quit" : self.quit }
self.builder.connect_signals(dic)
self.window.show()
if not self.conf.valid:
self.show_config();
if not self.conf.valid:
self.window.connect('event-after', self.quit)
return
else:
self.load_dictionaries()
threadtools.SubprocessThread(self.getnewversion,self.checkversion).start()
if filename==None:
self.status.set_text("Open an image to begin...")
else:
self.load_image(filename)
def quit(self,Widget=None,event=None):
if not self.outbuffer.clear_buffer():
return True
gtk.main_quit()
sys.exit(0)
### Open and load images ###
def open_image(self,widget):
filename=dialogs.open_image(self.curdir,self.window)
if filename!="":
self.load_image(filename)
def load_image(self,filename):
self.status.set_text("Loading '"+filename+"'...")
if not self.drawingarea.set_image(filename):
dialogs.error_dialog('Failed to load image','The file might not be an image or be corrupted.',self.window)
if self.filename==None:
self.status.set_text("Open an image to begin...")
else:
self.status.set_text("Drag a rectangle around the area to recognize, then press 'Recognize'...")
return
self.filename=filename
self.curdir=os.path.dirname(self.filename)
self.window.set_title(os.path.basename(self.filename)+" - gImageReader")
for obj in ("tb_zoomin", "tb_zoomout", "tb_resetzoom", "tb_rrotate", "tb_lrotate",
"menu_zoomin", "menu_zoomout", "menu_resetzoom", "menu_rrotate", "menu_lrotate"):
self.builder.get_object(obj).set_sensitive(True)
self.langcombo.set_sensitive(True)
self.status.set_text("Drag a rectangle around the area to recognize, then press 'Recognize'...")
### Recognition ###
def recognize(self, widget):
self.window.set_sensitive(False)
self.status.set_text('Recognizing area, please wait...')
threadtools.SubprocessThread(self.outbuffer.set_buffer_from_image,self.recognize_end,self.filename,self.drawingarea.osel,self.drawingarea.angle,self.conf).start()
def recognize_end(self, result):
if result[0]!=True:
dialogs.error_dialog(result[1], result[2], self.window)
else:
self.outbuffer.set_buffer(result[1])
self.window.set_sensitive(True)
self.status.set_text("Drag a rectangle around the area to recognize, then press 'Recognize'...")
### Set and detect languages ###
def show_config(self ,widget):
self.conf.show_dialog()
self.load_dictionaries()
def load_dictionaries(self):
for i in range(0, self.lang_count):
self.langcombo.remove_text(0)
self.lang_count=0
for lang in (("eng","English"),("fra","French"),("deu","German"),("ita","Italian"),("spa","Spanish"),("nld","Dutch")):
if os.path.isfile(self.conf.dict_path+lang[0]+".unicharset"):
self.lang_count+=1
self.langcombo.append_text(lang[1])
if self.lang_count==0:
if dialogs.question_dialog("No dictionaries found","Do you want to correct the configuration? (Pressing 'No' will quit the program.)",self.window):
self.conf.show()
else:
self.window.connect('event-after', gtk.main_quit)
else:
self.langcombo.set_active(0)
def set_language(self, widget):
list=widget.get_model()
i=widget.get_active()
if i==-1:
return
for lang in (("eng","English","en_US"),("fra","French","fr_FR"),("deu","German","de_DE"),("ita","Italian","it_IT"),("spa","Spanish","es_ES"),("nld","Dutch","nl_NL")):
if list[i][0]==lang[1]:
self.outbuffer.set_language(lang)
break
### About ###
def about(self, widget):
self.aboutdialog.run()
self.aboutdialog.hide()
### Check for updates ###
def getnewversion(self):
try:
urlh = urllib2.urlopen("http://sourceforge.net/projects/gimagereader/files/LATEST/download?use_mirror=autoselect",None,10)
except:
return "unknown"
return urlh.read()
def checkversion(self, txt):
if txt=="unknown":
return
v=txt.replace('\n','')
if v!=self.aboutdialog.get_version():
self.notifier.notify("<b>New version:</b> gImageReader "+v+" is available on <a href=\"http://sourceforge.net/projects/gimagereader/\">SourceForge</a>, <a href=\"http://sourceforge.net/projects/gimagereader/files/changelog.txt/download?use_mirror=autoselect\">changelog</a>.")