mirror of https://github.com/NaN-tic/nanscan.git
Added Planta application. A template designer.
This is the old 'playground' nano-client and thus not only depends on NaNScaN but in KTiny too.
This commit is contained in:
parent
e1be884d22
commit
8ac6afa164
|
@ -0,0 +1,60 @@
|
||||||
|
##############################################################################
|
||||||
|
#
|
||||||
|
# Copyright (c) 2007-2008 Albert Cervera i Areny <albert@nan-tic.com>
|
||||||
|
#
|
||||||
|
# WARNING: This program as such is intended to be used by professional
|
||||||
|
# programmers who take the whole responsability of assessing all potential
|
||||||
|
# consequences resulting from its eventual inadequacies and bugs
|
||||||
|
# End users who are looking for a ready-to-use solution with commercial
|
||||||
|
# garantees and support are strongly adviced to contract a Free Software
|
||||||
|
# Service Company
|
||||||
|
#
|
||||||
|
# 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 2
|
||||||
|
# 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
#
|
||||||
|
##############################################################################
|
||||||
|
|
||||||
|
from PyQt4.QtCore import *
|
||||||
|
from PyQt4.QtGui import *
|
||||||
|
|
||||||
|
class DeleteUndoCommand(QUndoCommand):
|
||||||
|
def __init__( self, template, box ):
|
||||||
|
self.template = template
|
||||||
|
self.box = box
|
||||||
|
if box.name:
|
||||||
|
text = _("Delete box '%s'") % box.name
|
||||||
|
else:
|
||||||
|
text = _("Delete unnamed box")
|
||||||
|
QUndoCommand.__init__( self, text )
|
||||||
|
|
||||||
|
def redo(self):
|
||||||
|
self.template.removeBox( self.box )
|
||||||
|
|
||||||
|
def undo(self):
|
||||||
|
self.template.addBox( self.box )
|
||||||
|
|
||||||
|
|
||||||
|
class AddTemplateBoxUndoCommand(QUndoCommand):
|
||||||
|
def __init__( self, template, box ):
|
||||||
|
self.template = template
|
||||||
|
self.box = box
|
||||||
|
QUndoCommand.__init__( self, _("Add box") )
|
||||||
|
|
||||||
|
def redo(self):
|
||||||
|
self.template.addBox( self.box )
|
||||||
|
|
||||||
|
def undo(self):
|
||||||
|
self.template.removeBox( self.box )
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,50 @@
|
||||||
|
#!/usr/bin/python
|
||||||
|
|
||||||
|
##############################################################################
|
||||||
|
#
|
||||||
|
# Copyright (c) 2007-2008 Albert Cervera i Areny <albert@nan-tic.com>
|
||||||
|
#
|
||||||
|
# WARNING: This program as such is intended to be used by professional
|
||||||
|
# programmers who take the whole responsability of assessing all potential
|
||||||
|
# consequences resulting from its eventual inadequacies and bugs
|
||||||
|
# End users who are looking for a ready-to-use solution with commercial
|
||||||
|
# garantees and support are strongly adviced to contract a Free Software
|
||||||
|
# Service Company
|
||||||
|
#
|
||||||
|
# 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 2
|
||||||
|
# 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
#
|
||||||
|
##############################################################################
|
||||||
|
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
import glob
|
||||||
|
import base64
|
||||||
|
import rpc
|
||||||
|
|
||||||
|
if len(sys.argv) != 3:
|
||||||
|
print 'loader.py database directory'
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
rpc.session.login( 'http://admin:admin@127.0.0.1:8069', sys.argv[1] )
|
||||||
|
|
||||||
|
files = glob.glob(sys.argv[2] + "/*.png")
|
||||||
|
print "F: ", files
|
||||||
|
for x in files:
|
||||||
|
print "Loading file: ", x
|
||||||
|
fields = {}
|
||||||
|
fields['name'] = os.path.split(x)[1]
|
||||||
|
fields['datas'] = base64.encodestring(open(x, 'rb').read())
|
||||||
|
rpc.session.execute('/object', 'execute', 'nan.document', 'create', fields )
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
export PYTHONPATH=../../ktiny/bin
|
||||||
|
./loader.py $1 $2
|
||||||
|
|
|
@ -0,0 +1,579 @@
|
||||||
|
##############################################################################
|
||||||
|
#
|
||||||
|
# Copyright (c) 2007-2008 Albert Cervera i Areny <albert@nan-tic.com>
|
||||||
|
#
|
||||||
|
# WARNING: This program as such is intended to be used by professional
|
||||||
|
# programmers who take the whole responsability of assessing all potential
|
||||||
|
# consequences resulting from its eventual inadequacies and bugs
|
||||||
|
# End users who are looking for a ready-to-use solution with commercial
|
||||||
|
# garantees and support are strongly adviced to contract a Free Software
|
||||||
|
# Service Company
|
||||||
|
#
|
||||||
|
# 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 2
|
||||||
|
# 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
#
|
||||||
|
##############################################################################
|
||||||
|
|
||||||
|
from PyQt4.QtGui import *
|
||||||
|
from PyQt4.QtCore import *
|
||||||
|
from PyQt4.uic import *
|
||||||
|
from NaNScaN.template import *
|
||||||
|
from NaNScaN.ocr import *
|
||||||
|
from NaNScaN.recognizer import *
|
||||||
|
|
||||||
|
|
||||||
|
from opentemplatedialog import *
|
||||||
|
from commands import *
|
||||||
|
|
||||||
|
from modules.gui.login import LoginDialog
|
||||||
|
import rpc
|
||||||
|
|
||||||
|
class ToolWidget(QWidget):
|
||||||
|
|
||||||
|
def __init__(self, parent=None):
|
||||||
|
QWidget.__init__(self, parent)
|
||||||
|
loadUi( 'toolwidget.ui', self )
|
||||||
|
|
||||||
|
for x in TemplateBox.recognizers:
|
||||||
|
self.uiRecognizer.addItem( x )
|
||||||
|
|
||||||
|
for x in TemplateBox.types:
|
||||||
|
self.uiType.addItem( x )
|
||||||
|
|
||||||
|
for x in TemplateBox.filters:
|
||||||
|
self.uiFilter.addItem( x )
|
||||||
|
|
||||||
|
self._box = None
|
||||||
|
self.load()
|
||||||
|
self.connect( self.uiRecognizer, SIGNAL('activated(QString)'), self.recognizerChanged )
|
||||||
|
|
||||||
|
def recognizerChanged(self, recognizer):
|
||||||
|
self.emit(SIGNAL('recognizerChanged(QString)'), recognizer)
|
||||||
|
|
||||||
|
def setText(self, text):
|
||||||
|
self.uiText.setText( text )
|
||||||
|
|
||||||
|
def setBox(self, box):
|
||||||
|
self._box = box
|
||||||
|
self.load()
|
||||||
|
|
||||||
|
def getBox(self):
|
||||||
|
return self._box
|
||||||
|
box=property(getBox,setBox)
|
||||||
|
|
||||||
|
def store(self):
|
||||||
|
if not self._box:
|
||||||
|
return
|
||||||
|
self._box.rect = QRectF( self.uiX.value(), self.uiY.value(), self.uiWidth.value(), self.uiHeight.value() )
|
||||||
|
self._box.recognizer = unicode( self.uiRecognizer.currentText() )
|
||||||
|
self._box.type = unicode( self.uiType.currentText() )
|
||||||
|
self._box.filter = unicode( self.uiFilter.currentText() )
|
||||||
|
self._box.name = unicode( self.uiName.text() )
|
||||||
|
self._box.text = unicode( self.uiText.text() )
|
||||||
|
|
||||||
|
def enable(self, value):
|
||||||
|
if not value:
|
||||||
|
self.uiX.setValue( -1 )
|
||||||
|
self.uiY.setValue( -1 )
|
||||||
|
self.uiWidth.setValue( -1 )
|
||||||
|
self.uiHeight.setValue( -1 )
|
||||||
|
self.uiName.clear()
|
||||||
|
self.uiText.clear()
|
||||||
|
self.uiRecognizer.setEnabled( value )
|
||||||
|
self.uiName.setEnabled( value )
|
||||||
|
self.uiText.setEnabled( value )
|
||||||
|
self.uiType.setEnabled( value )
|
||||||
|
self.uiFilter.setEnabled( value )
|
||||||
|
|
||||||
|
def load(self):
|
||||||
|
if self._box:
|
||||||
|
self.enable( True )
|
||||||
|
self.uiX.setValue( self._box.rect.x() )
|
||||||
|
self.uiY.setValue( self._box.rect.y() )
|
||||||
|
self.uiWidth.setValue( self._box.rect.width() )
|
||||||
|
self.uiHeight.setValue( self._box.rect.height() )
|
||||||
|
self.uiRecognizer.setCurrentIndex( self.uiRecognizer.findText( self._box.recognizer ) )
|
||||||
|
self.uiType.setCurrentIndex( self.uiType.findText( self._box.type ) )
|
||||||
|
self.uiFilter.setCurrentIndex( self.uiFilter.findText( self._box.filter ) )
|
||||||
|
self.uiText.setText( self._box.text )
|
||||||
|
self.uiName.setText( self._box.name )
|
||||||
|
else:
|
||||||
|
self.enable( False )
|
||||||
|
|
||||||
|
|
||||||
|
class TemplateBoxItem(QGraphicsRectItem):
|
||||||
|
def __init__(self, rect):
|
||||||
|
QGraphicsRectItem.__init__(self, rect)
|
||||||
|
self.templateBox = None
|
||||||
|
|
||||||
|
class DocumentScene(QGraphicsScene):
|
||||||
|
|
||||||
|
CreationMode = 1
|
||||||
|
SelectionMode = 2
|
||||||
|
|
||||||
|
MovingState = 1
|
||||||
|
CreationState = 2
|
||||||
|
|
||||||
|
def __init__(self, parent=None):
|
||||||
|
QGraphicsScene.__init__(self,parent)
|
||||||
|
self._imageBoxesVisible = True
|
||||||
|
self._templateBoxesVisible = True
|
||||||
|
self._binarizedVisible = False
|
||||||
|
self._mode = self.CreationMode
|
||||||
|
self._selection = None
|
||||||
|
self._activeItem = None
|
||||||
|
self._imageBoxes = None
|
||||||
|
self._templateBoxes = []
|
||||||
|
self._activeItemPen = QPen( QBrush( QColor('green') ), 1 )
|
||||||
|
self._activeItemBrush = QBrush( QColor( 0, 255, 0, 50 ) )
|
||||||
|
self._boxItemPen = QPen( QBrush( QColor( 'red' ) ), 1 )
|
||||||
|
self._boxItemBrush = QBrush( QColor( 255, 0, 0, 50 ) )
|
||||||
|
self._selectionPen = QPen( QBrush( QColor( 'blue' ) ), 1 )
|
||||||
|
self._selectionBrush = QBrush( QColor( 0, 0, 255, 50 ) )
|
||||||
|
self._circleItemPen = QPen( QBrush( QColor( 'yellow' ) ), 1 )
|
||||||
|
self._circleItemBrush = QBrush( QColor( 255, 255, 0, 50 ) )
|
||||||
|
self.state = None
|
||||||
|
self.recognizer = None
|
||||||
|
self._image = None
|
||||||
|
self._oneBitImage = None
|
||||||
|
self._template = None
|
||||||
|
self.dotsPerMillimeterX = None
|
||||||
|
self.dotsPerMillimeterY = None
|
||||||
|
|
||||||
|
def setDocument(self, recognizer):
|
||||||
|
self.clearImage()
|
||||||
|
|
||||||
|
self.recognizer = recognizer
|
||||||
|
|
||||||
|
image = self.recognizer.image
|
||||||
|
self.dotsPerMillimeterX = float( image.dotsPerMeterX() ) / 1000.0
|
||||||
|
self.dotsPerMillimeterY = float( image.dotsPerMeterY() ) / 1000.0
|
||||||
|
print "DOTS PER MILLIMETER %s, %s" % (self.dotsPerMillimeterX, self.dotsPerMillimeterY)
|
||||||
|
|
||||||
|
self._image = self.addPixmap( QPixmap.fromImage( image ) )
|
||||||
|
self._imageBoxes = self.createItemGroup( [] )
|
||||||
|
for i in self.recognizer.boxes('text'):
|
||||||
|
#rect = QGraphicsRectItem( i.box, self._imageBoxes )
|
||||||
|
rect = QGraphicsRectItem( self.mapRectFromRecognizer( i.box ), self._imageBoxes )
|
||||||
|
rect.setPen( self._boxItemPen )
|
||||||
|
rect.setBrush( self._boxItemBrush )
|
||||||
|
self._imageBoxes.addToGroup( rect )
|
||||||
|
|
||||||
|
for i in self.recognizer.boxes('barcode'):
|
||||||
|
#circle = QGraphicsEllipseItem( i.position.x(), i.position.y(), 40, 40 )
|
||||||
|
rect = QRectF( i.position.x(), i.position.y(), 40, 40 )
|
||||||
|
circle = QGraphicsEllipseItem( self.mapRectFromRecognizer( rect ) )
|
||||||
|
circle.setPen( self._circleItemPen )
|
||||||
|
circle.setBrush( self._circleItemBrush )
|
||||||
|
self._imageBoxes.addToGroup( circle )
|
||||||
|
|
||||||
|
self.setImageBoxesVisible( self._imageBoxesVisible )
|
||||||
|
self._imageBoxes.setZValue( 2 )
|
||||||
|
|
||||||
|
self._oneBitImage = self.addPixmap( QPixmap.fromImage( self.recognizer.image ) )
|
||||||
|
self._oneBitImage.setZValue( 1 )
|
||||||
|
self.setBinarizedVisible( self._binarizedVisible )
|
||||||
|
|
||||||
|
self.setTemplateBoxesVisible( self._templateBoxesVisible )
|
||||||
|
|
||||||
|
def mapRectFromRecognizer(self, rect):
|
||||||
|
box = QRectF()
|
||||||
|
box.setX( rect.x() * self.dotsPerMillimeterX )
|
||||||
|
box.setY( rect.y() * self.dotsPerMillimeterY )
|
||||||
|
box.setWidth( rect.width() * self.dotsPerMillimeterX )
|
||||||
|
box.setHeight( rect.height() * self.dotsPerMillimeterY )
|
||||||
|
return box
|
||||||
|
|
||||||
|
def mapRectToRecognizer(self, rect):
|
||||||
|
box = QRectF()
|
||||||
|
box.setX( rect.x() / self.dotsPerMillimeterX )
|
||||||
|
box.setY( rect.y() / self.dotsPerMillimeterY )
|
||||||
|
box.setWidth( rect.width() / self.dotsPerMillimeterX )
|
||||||
|
box.setHeight( rect.height() / self.dotsPerMillimeterY )
|
||||||
|
return box
|
||||||
|
|
||||||
|
def mapPointFromRecognizer(self, point):
|
||||||
|
d = QPointF()
|
||||||
|
d.setX( point.x() * self.dotsPerMillimeterX )
|
||||||
|
d.setY( point.y() * self.dotsPerMillimeterY )
|
||||||
|
return d
|
||||||
|
|
||||||
|
def mapPointToRecognizer(self, point):
|
||||||
|
d = QPointF()
|
||||||
|
d.setX( point.x() / self.dotsPerMillimeterX )
|
||||||
|
d.setY( point.y() / self.dotsPerMillimeterY )
|
||||||
|
return d
|
||||||
|
|
||||||
|
def setTemplate(self, template):
|
||||||
|
self.clearTemplate()
|
||||||
|
self._template = template
|
||||||
|
self.connect( template, SIGNAL('boxAdded(PyQt_PyObject)'), self.templateBoxAdded )
|
||||||
|
self.connect( template, SIGNAL('boxRemoved(PyQt_PyObject)'), self.templateBoxRemoved )
|
||||||
|
for box in self._template.boxes:
|
||||||
|
self.addTemplateBox( box )
|
||||||
|
|
||||||
|
def templateBoxAdded(self, box):
|
||||||
|
self.addTemplateBox( box )
|
||||||
|
|
||||||
|
def templateBoxRemoved(self, box):
|
||||||
|
for x in self._templateBoxes:
|
||||||
|
if x.templateBox == box:
|
||||||
|
self.removeTemplateBox( x )
|
||||||
|
break
|
||||||
|
|
||||||
|
def isEnabled(self):
|
||||||
|
if self._template and self.recognizer:
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
return False
|
||||||
|
|
||||||
|
def clear(self):
|
||||||
|
if self._imageBoxes:
|
||||||
|
self.destroyItemGroup( self._imageBoxes )
|
||||||
|
for x in self.items():
|
||||||
|
self.removeItem( x )
|
||||||
|
|
||||||
|
def clearTemplate(self):
|
||||||
|
for x in self._templateBoxes:
|
||||||
|
self.removeItem( x )
|
||||||
|
self._templateBoxes = []
|
||||||
|
|
||||||
|
def clearImage(self):
|
||||||
|
if self._imageBoxes:
|
||||||
|
# When an Item Group is removed all children
|
||||||
|
# are reparented. So remove all children after
|
||||||
|
# destroying the group.
|
||||||
|
boxes = []
|
||||||
|
for x in self._imageBoxes.children():
|
||||||
|
boxes.append( x )
|
||||||
|
self.destroyItemGroup( self._imageBoxes )
|
||||||
|
for x in boxes:
|
||||||
|
self.removeItem( x )
|
||||||
|
if self._image:
|
||||||
|
self.removeItem( self._image )
|
||||||
|
if self._oneBitImage:
|
||||||
|
self.removeItem( self._oneBitImage )
|
||||||
|
|
||||||
|
def setImageBoxesVisible(self, value):
|
||||||
|
self._imageBoxesVisible = value
|
||||||
|
if self._imageBoxes:
|
||||||
|
self._imageBoxes.setVisible( value )
|
||||||
|
|
||||||
|
def setTemplateBoxesVisible(self, value):
|
||||||
|
self._templateBoxesVisible = value
|
||||||
|
for item in self.items():
|
||||||
|
if item and unicode(item.data( 0 ).toString()) == 'TemplateBox':
|
||||||
|
item.setVisible( value )
|
||||||
|
|
||||||
|
def setBinarizedVisible(self, value):
|
||||||
|
self._binarizedVisible = value
|
||||||
|
self._oneBitImage.setVisible( value )
|
||||||
|
|
||||||
|
def setMode(self, mode):
|
||||||
|
self._mode = mode
|
||||||
|
|
||||||
|
def setActiveItem(self, item):
|
||||||
|
previousBox = None
|
||||||
|
if self._activeItem:
|
||||||
|
self._activeItem.setPen( self._selectionPen )
|
||||||
|
self._activeItem.setBrush( self._selectionBrush )
|
||||||
|
previousBox = self._activeItem.templateBox
|
||||||
|
currentBox = None
|
||||||
|
self._activeItem = item
|
||||||
|
if item:
|
||||||
|
self._activeItem.setPen( self._activeItemPen )
|
||||||
|
self._activeItem.setBrush( self._activeItemBrush )
|
||||||
|
currentBox = self._activeItem.templateBox
|
||||||
|
self.emit( SIGNAL('currentTemplateBoxChanged(PyQt_PyObject,PyQt_PyObject)'), currentBox, previousBox )
|
||||||
|
|
||||||
|
def activeItem(self):
|
||||||
|
return self._activeItem
|
||||||
|
|
||||||
|
def createTemplateBox(self, rect):
|
||||||
|
item = TemplateBoxItem( rect )
|
||||||
|
item.setPen( self._selectionPen )
|
||||||
|
item.setBrush( self._selectionBrush )
|
||||||
|
item.setZValue( 5 )
|
||||||
|
item.setData( 0, QVariant( 'TemplateBox' ) )
|
||||||
|
self._templateBoxes.append( item )
|
||||||
|
self.addItem( item )
|
||||||
|
return item
|
||||||
|
|
||||||
|
def addTemplateBox(self, box):
|
||||||
|
item = TemplateBoxItem( self.mapRectFromRecognizer( box.rect ) )
|
||||||
|
item.setPen( self._selectionPen )
|
||||||
|
item.setBrush( self._selectionBrush )
|
||||||
|
item.setZValue( 5 )
|
||||||
|
item.setData( 0, QVariant( 'TemplateBox' ) )
|
||||||
|
item.templateBox = box
|
||||||
|
item.setVisible( self._templateBoxesVisible )
|
||||||
|
self._templateBoxes.append( item )
|
||||||
|
self.addItem( item )
|
||||||
|
self.setActiveItem( item )
|
||||||
|
return item
|
||||||
|
|
||||||
|
def removeTemplateBox(self, item):
|
||||||
|
if self._activeItem == item:
|
||||||
|
self.setActiveItem( None )
|
||||||
|
self._templateBoxes.remove( item )
|
||||||
|
self.removeItem( item )
|
||||||
|
|
||||||
|
def mousePressEvent(self, event):
|
||||||
|
if not self.isEnabled():
|
||||||
|
return
|
||||||
|
if self._mode == self.CreationMode:
|
||||||
|
item = self.itemAt( event.scenePos() )
|
||||||
|
if item and unicode(item.data( 0 ).toString()) == 'TemplateBox':
|
||||||
|
self.setActiveItem( item )
|
||||||
|
return
|
||||||
|
|
||||||
|
rect = QRectF(event.scenePos().x(), event.scenePos().y(), 1, 1)
|
||||||
|
self._selection = self.createTemplateBox( rect )
|
||||||
|
elif self._mode == self.SelectionMode:
|
||||||
|
item = self.itemAt( event.scenePos() )
|
||||||
|
if item != self._activeItem:
|
||||||
|
self._activeItem.setBrush( QBrush() )
|
||||||
|
self._activeItem.setPen( QPen() )
|
||||||
|
self._activeItem = item
|
||||||
|
self._activeItem.setBrush( self._activeItemBrush )
|
||||||
|
self._activeItem.setBrush( self._activeItemBrush )
|
||||||
|
|
||||||
|
def mouseReleaseEvent(self, event):
|
||||||
|
if not self.isEnabled():
|
||||||
|
return
|
||||||
|
if self._mode == self.CreationMode and self._selection:
|
||||||
|
# Remove the selection. Currently main window will handle
|
||||||
|
# the signaland add the box in the template.
|
||||||
|
rect = self._selection.rect()
|
||||||
|
self.removeItem( self._selection )
|
||||||
|
self._selection = None
|
||||||
|
self.emit( SIGNAL('newTemplateBox(QRectF)'), self.mapRectToRecognizer( rect ) )
|
||||||
|
|
||||||
|
def mouseMoveEvent(self, event):
|
||||||
|
if not self.isEnabled():
|
||||||
|
return
|
||||||
|
if self._mode == self.CreationMode and self._selection:
|
||||||
|
rect = self._selection.rect()
|
||||||
|
rect.setBottomRight( event.scenePos() )
|
||||||
|
self._selection.setRect( rect )
|
||||||
|
|
||||||
|
|
||||||
|
class MainWindow(QMainWindow):
|
||||||
|
Unnamed = _('unnamed')
|
||||||
|
|
||||||
|
def __init__(self, parent=None):
|
||||||
|
QMainWindow.__init__(self, parent)
|
||||||
|
loadUi( 'mainwindow.ui', self )
|
||||||
|
self.scene = DocumentScene()
|
||||||
|
self.uiView.setScene( self.scene )
|
||||||
|
self.uiView.setRenderHints( QPainter.Antialiasing | QPainter.TextAntialiasing | QPainter.SmoothPixmapTransform )
|
||||||
|
self.uiView.setCacheMode( QGraphicsView.CacheBackground )
|
||||||
|
|
||||||
|
self._template = Template( self.Unnamed )
|
||||||
|
self.scene.setTemplate(self._template)
|
||||||
|
|
||||||
|
self.uiTool = ToolWidget( self.uiToolDock )
|
||||||
|
|
||||||
|
self.undoGroup = QUndoGroup( self )
|
||||||
|
stack = QUndoStack( self.undoGroup )
|
||||||
|
self.undoGroup.setActiveStack( stack )
|
||||||
|
|
||||||
|
# Let default Qt Undo and Redo Actions handle the Undo/Redo actions
|
||||||
|
# And put them at the very beggining of the Edit menu
|
||||||
|
undoAction = self.undoGroup.createUndoAction( self.menuEdit )
|
||||||
|
undoAction.setShortcut( "Ctrl+Z" )
|
||||||
|
redoAction = self.undoGroup.createRedoAction( self.menuEdit )
|
||||||
|
redoAction.setShortcut( "Ctrl+Shift+Z" )
|
||||||
|
if self.menuEdit.actions():
|
||||||
|
firstAction = self.menuEdit.actions()[0]
|
||||||
|
else:
|
||||||
|
firstAction = None
|
||||||
|
self.menuEdit.insertAction( firstAction, undoAction )
|
||||||
|
self.menuEdit.insertAction( firstAction, redoAction )
|
||||||
|
|
||||||
|
self.connect( self.scene, SIGNAL('newTemplateBox(QRectF)'), self.newTemplateBox )
|
||||||
|
self.connect( self.scene, SIGNAL('currentTemplateBoxChanged(PyQt_PyObject,PyQt_PyObject)'), self.currentTemplateBoxChanged)
|
||||||
|
self.connect( self.actionExit, SIGNAL('triggered()'), self.close )
|
||||||
|
self.connect( self.actionOpenImage, SIGNAL('triggered()'), self.openImage )
|
||||||
|
self.connect( self.actionOpenTemplate, SIGNAL('triggered()'), self.openTemplate )
|
||||||
|
self.connect( self.actionToggleImageBoxes, SIGNAL('triggered()'), self.toggleImageBoxes )
|
||||||
|
self.connect( self.actionToggleTemplateBoxes, SIGNAL('triggered()'), self.toggleTemplateBoxes )
|
||||||
|
self.connect( self.actionToggleBinarized, SIGNAL('triggered()'), self.toggleBinarized )
|
||||||
|
self.connect( self.actionLogin, SIGNAL('triggered()'), self.login )
|
||||||
|
self.connect( self.actionSaveTemplate, SIGNAL('triggered()'), self.saveTemplate )
|
||||||
|
self.connect( self.actionSaveTemplateAs, SIGNAL('triggered()'), self.saveTemplateAs )
|
||||||
|
self.connect( self.actionNewTemplate, SIGNAL('triggered()'), self.newTemplate )
|
||||||
|
self.connect( self.actionDelete, SIGNAL('triggered()'), self.removeTemplateBox )
|
||||||
|
self.connect( self.actionZoom, SIGNAL('triggered()'), self.zoom )
|
||||||
|
self.connect( self.actionUnzoom, SIGNAL('triggered()'), self.unzoom )
|
||||||
|
self.toggleImageBoxes()
|
||||||
|
QTimer.singleShot( 1000, self.setup )
|
||||||
|
self.updateTitle()
|
||||||
|
self.updateActions()
|
||||||
|
|
||||||
|
def setup(self):
|
||||||
|
initOcrSystem()
|
||||||
|
#self.scene.setDocument( 'c-0.tif' )
|
||||||
|
|
||||||
|
self.connect( self.uiTool, SIGNAL('recognizerChanged(QString)'), self.recognizerChanged )
|
||||||
|
self.uiTool.show()
|
||||||
|
self.uiToolDock.setWidget( self.uiTool )
|
||||||
|
|
||||||
|
#rpc.session.login( 'http://admin:admin@127.0.0.1:8069', 'g1' )
|
||||||
|
|
||||||
|
def recognizerChanged(self, recognizer):
|
||||||
|
rect = self.uiTool.box.rect
|
||||||
|
self.uiTool.setText( self.scene.recognizer.textInRegion( rect, recognizer ) )
|
||||||
|
|
||||||
|
def newTemplateBox(self, rect):
|
||||||
|
# Creating and adding the box to the template
|
||||||
|
# will automatically create the Rect in the Scene
|
||||||
|
box = TemplateBox()
|
||||||
|
box.rect = rect
|
||||||
|
box.text = self.scene.recognizer.textInRegion( rect, 'text' )
|
||||||
|
add = AddTemplateBoxUndoCommand( self._template, box )
|
||||||
|
self.undoGroup.activeStack().push( add )
|
||||||
|
|
||||||
|
#def setCurrentTemplateBox(self, box):
|
||||||
|
#if self.uiTool.box:
|
||||||
|
#self.uiTool.store()
|
||||||
|
#self.uiTool.box = box
|
||||||
|
def currentTemplateBoxChanged(self, current, previous):
|
||||||
|
if self.uiTool.box:
|
||||||
|
self.uiTool.store()
|
||||||
|
self.uiTool.box = current
|
||||||
|
self.actionDelete.setEnabled( bool(current) )
|
||||||
|
|
||||||
|
def openImage(self):
|
||||||
|
self.fileName = QFileDialog.getOpenFileName( self )
|
||||||
|
if self.fileName.isNull():
|
||||||
|
return
|
||||||
|
|
||||||
|
QApplication.setOverrideCursor( Qt.BusyCursor )
|
||||||
|
self.recognizer = Recognizer()
|
||||||
|
self.connect( self.recognizer, SIGNAL('finished()'), self.recognized )
|
||||||
|
self.recognizer.startRecognition( QImage(self.fileName) )
|
||||||
|
|
||||||
|
def recognized(self):
|
||||||
|
self.scene.setDocument( self.recognizer )
|
||||||
|
QApplication.restoreOverrideCursor()
|
||||||
|
|
||||||
|
def toggleImageBoxes(self):
|
||||||
|
self.scene.setImageBoxesVisible( self.actionToggleImageBoxes.isChecked() )
|
||||||
|
|
||||||
|
def toggleTemplateBoxes(self):
|
||||||
|
self.scene.setTemplateBoxesVisible( self.actionToggleTemplateBoxes.isChecked() )
|
||||||
|
|
||||||
|
def toggleBinarized(self):
|
||||||
|
self.scene.setBinarizedVisible( self.actionToggleBinarized.isChecked() )
|
||||||
|
|
||||||
|
def removeTemplateBox(self):
|
||||||
|
if not self.uiTool.box:
|
||||||
|
return
|
||||||
|
delete = DeleteUndoCommand( self._template, self.uiTool.box )
|
||||||
|
self.undoGroup.activeStack().push( delete )
|
||||||
|
|
||||||
|
def zoom(self):
|
||||||
|
self.uiView.scale( 1.2, 1.2 )
|
||||||
|
|
||||||
|
def unzoom(self):
|
||||||
|
self.uiView.scale( 0.8, 0.8 )
|
||||||
|
|
||||||
|
def login(self):
|
||||||
|
dialog = LoginDialog( self )
|
||||||
|
if dialog.exec_() == QDialog.Rejected:
|
||||||
|
return False
|
||||||
|
if rpc.session.login( dialog.url, dialog.databaseName ) > 0:
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
return False
|
||||||
|
|
||||||
|
def newTemplate(self):
|
||||||
|
answer = QMessageBox.question(self, _('New Template'), _('Do you want to save changes to the current template?'), QMessageBox.Save | QMessageBox.No | QMessageBox.Cancel )
|
||||||
|
if answer == QMessageBox.Cancel:
|
||||||
|
return
|
||||||
|
elif answer == QMessageBox.Save:
|
||||||
|
if not self.saveTemplate():
|
||||||
|
return
|
||||||
|
self._template = Template( self.Unnamed )
|
||||||
|
self.scene.setTemplate( self._template )
|
||||||
|
self.updateTitle()
|
||||||
|
|
||||||
|
def saveTemplate(self):
|
||||||
|
self.uiTool.store()
|
||||||
|
if not rpc.session.logged():
|
||||||
|
if not self.login():
|
||||||
|
return False
|
||||||
|
|
||||||
|
if not self._template.id:
|
||||||
|
(name, ok) = QInputDialog.getText( self, _('Save template'), _('Template name:') )
|
||||||
|
if not ok:
|
||||||
|
return False
|
||||||
|
self._template.name = unicode(name)
|
||||||
|
|
||||||
|
|
||||||
|
if self._template.id:
|
||||||
|
rpc.session.call( '/object', 'execute', 'nan.template', 'write', [self._template.id], {'name': self._template.name } )
|
||||||
|
ids = rpc.session.call( '/object', 'execute', 'nan.template.box', 'search', [('template_id','=',self._template.id)] )
|
||||||
|
rpc.session.call( '/object', 'execute', 'nan.template.box', 'unlink', ids )
|
||||||
|
else:
|
||||||
|
self._template.id = rpc.session.call( '/object', 'execute', 'nan.template', 'create', {'name': self._template.name } )
|
||||||
|
for x in self._template.boxes:
|
||||||
|
values = { 'x': x.rect.x(), 'y': x.rect.y(),
|
||||||
|
'width': x.rect.width(), 'height': x.rect.height(), 'template_id': self._template.id,
|
||||||
|
'name': x.name, 'text': x.text, 'recognizer': x.recognizer, 'type': x.type, 'filter': x.filter }
|
||||||
|
rpc.session.call( '/object', 'execute', 'nan.template.box', 'create', values )
|
||||||
|
self.updateTitle()
|
||||||
|
return True
|
||||||
|
|
||||||
|
def saveTemplateAs(self):
|
||||||
|
id = self._template.id
|
||||||
|
self._template.id = 0
|
||||||
|
if not self.saveTemplate():
|
||||||
|
self._template.id = id
|
||||||
|
self.updateTitle()
|
||||||
|
|
||||||
|
def openTemplate(self):
|
||||||
|
if not rpc.session.logged():
|
||||||
|
if not self.login():
|
||||||
|
return
|
||||||
|
|
||||||
|
dialog = OpenTemplateDialog(self)
|
||||||
|
if dialog.exec_() == QDialog.Rejected:
|
||||||
|
return
|
||||||
|
model = dialog.group[dialog.id]
|
||||||
|
self._template = Template( model.value('name') )
|
||||||
|
self._template.id = model.id
|
||||||
|
|
||||||
|
fields = rpc.session.execute('/object', 'execute', 'nan.template.box', 'fields_get')
|
||||||
|
model.value('boxes').addFields( fields )
|
||||||
|
for x in model.value('boxes'):
|
||||||
|
box = TemplateBox()
|
||||||
|
box.rect = QRectF( x.value('x'), x.value('y'), x.value('width'), x.value('height') )
|
||||||
|
box.name = x.value('name')
|
||||||
|
box.text = x.value('text')
|
||||||
|
box.recognizer = x.value('recognizer')
|
||||||
|
box.type = x.value('type')
|
||||||
|
box.filter = x.value('filter')
|
||||||
|
self._template.addBox( box )
|
||||||
|
|
||||||
|
self.scene.setTemplate(self._template)
|
||||||
|
self.updateTitle()
|
||||||
|
|
||||||
|
def updateTitle(self):
|
||||||
|
self.setWindowTitle( "NaNnar - [%s]" % self._template.name )
|
||||||
|
|
||||||
|
def updateActions(self):
|
||||||
|
# Allow deleting if there's a TemplateBox selected
|
||||||
|
self.actionDelete.setEnabled( bool(self.uiTool.box) )
|
|
@ -0,0 +1,222 @@
|
||||||
|
<ui version="4.0" >
|
||||||
|
<class>MainWindow</class>
|
||||||
|
<widget class="QMainWindow" name="MainWindow" >
|
||||||
|
<property name="geometry" >
|
||||||
|
<rect>
|
||||||
|
<x>0</x>
|
||||||
|
<y>0</y>
|
||||||
|
<width>524</width>
|
||||||
|
<height>487</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="windowTitle" >
|
||||||
|
<string>MainWindow</string>
|
||||||
|
</property>
|
||||||
|
<widget class="QWidget" name="centralwidget" >
|
||||||
|
<property name="geometry" >
|
||||||
|
<rect>
|
||||||
|
<x>0</x>
|
||||||
|
<y>63</y>
|
||||||
|
<width>524</width>
|
||||||
|
<height>401</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<layout class="QHBoxLayout" >
|
||||||
|
<item>
|
||||||
|
<layout class="QVBoxLayout" >
|
||||||
|
<item>
|
||||||
|
<widget class="QDockWidget" name="uiToolDock" >
|
||||||
|
<property name="sizePolicy" >
|
||||||
|
<sizepolicy vsizetype="Preferred" hsizetype="Fixed" >
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="windowTitle" >
|
||||||
|
<string/>
|
||||||
|
</property>
|
||||||
|
<widget class="QWidget" name="dockWidgetContents" >
|
||||||
|
<property name="geometry" >
|
||||||
|
<rect>
|
||||||
|
<x>0</x>
|
||||||
|
<y>21</y>
|
||||||
|
<width>71</width>
|
||||||
|
<height>360</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QGraphicsView" name="uiView" />
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
<widget class="QMenuBar" name="menubar" >
|
||||||
|
<property name="geometry" >
|
||||||
|
<rect>
|
||||||
|
<x>0</x>
|
||||||
|
<y>0</y>
|
||||||
|
<width>524</width>
|
||||||
|
<height>30</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<widget class="QMenu" name="menuFile" >
|
||||||
|
<property name="title" >
|
||||||
|
<string>&File</string>
|
||||||
|
</property>
|
||||||
|
<addaction name="actionOpenImage" />
|
||||||
|
<addaction name="separator" />
|
||||||
|
<addaction name="actionLogin" />
|
||||||
|
<addaction name="actionNewTemplate" />
|
||||||
|
<addaction name="actionOpenTemplate" />
|
||||||
|
<addaction name="actionSaveTemplate" />
|
||||||
|
<addaction name="actionSaveTemplateAs" />
|
||||||
|
<addaction name="separator" />
|
||||||
|
<addaction name="actionExit" />
|
||||||
|
</widget>
|
||||||
|
<widget class="QMenu" name="menuView" >
|
||||||
|
<property name="title" >
|
||||||
|
<string>&View</string>
|
||||||
|
</property>
|
||||||
|
<addaction name="actionToggleImageBoxes" />
|
||||||
|
<addaction name="actionToggleTemplateBoxes" />
|
||||||
|
<addaction name="actionToggleBinarized" />
|
||||||
|
</widget>
|
||||||
|
<widget class="QMenu" name="menuEdit" >
|
||||||
|
<property name="title" >
|
||||||
|
<string>&Edit</string>
|
||||||
|
</property>
|
||||||
|
<addaction name="actionDelete" />
|
||||||
|
</widget>
|
||||||
|
<addaction name="menuFile" />
|
||||||
|
<addaction name="menuEdit" />
|
||||||
|
<addaction name="menuView" />
|
||||||
|
</widget>
|
||||||
|
<widget class="QStatusBar" name="statusbar" >
|
||||||
|
<property name="geometry" >
|
||||||
|
<rect>
|
||||||
|
<x>0</x>
|
||||||
|
<y>464</y>
|
||||||
|
<width>524</width>
|
||||||
|
<height>23</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
<widget class="QToolBar" name="toolBar" >
|
||||||
|
<property name="geometry" >
|
||||||
|
<rect>
|
||||||
|
<x>0</x>
|
||||||
|
<y>30</y>
|
||||||
|
<width>524</width>
|
||||||
|
<height>33</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="windowTitle" >
|
||||||
|
<string>toolBar</string>
|
||||||
|
</property>
|
||||||
|
<attribute name="toolBarArea" >
|
||||||
|
<enum>TopToolBarArea</enum>
|
||||||
|
</attribute>
|
||||||
|
<attribute name="toolBarBreak" >
|
||||||
|
<bool>false</bool>
|
||||||
|
</attribute>
|
||||||
|
<addaction name="actionToggleImageBoxes" />
|
||||||
|
<addaction name="actionToggleTemplateBoxes" />
|
||||||
|
<addaction name="actionToggleBinarized" />
|
||||||
|
<addaction name="separator" />
|
||||||
|
<addaction name="actionUnzoom" />
|
||||||
|
<addaction name="actionZoom" />
|
||||||
|
</widget>
|
||||||
|
<action name="actionOpenImage" >
|
||||||
|
<property name="text" >
|
||||||
|
<string>&Open Image</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
<action name="actionExit" >
|
||||||
|
<property name="text" >
|
||||||
|
<string>&Exit</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
<action name="actionToggleImageBoxes" >
|
||||||
|
<property name="checkable" >
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="checked" >
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="text" >
|
||||||
|
<string>&Show Image Boxes</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
<action name="actionLogin" >
|
||||||
|
<property name="text" >
|
||||||
|
<string>&Login</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
<action name="actionSaveTemplate" >
|
||||||
|
<property name="text" >
|
||||||
|
<string>&Save Template</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
<action name="actionOpenTemplate" >
|
||||||
|
<property name="text" >
|
||||||
|
<string>Open &Template</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
<action name="actionNewTemplate" >
|
||||||
|
<property name="text" >
|
||||||
|
<string>New Template</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
<action name="actionToggleTemplateBoxes" >
|
||||||
|
<property name="checkable" >
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="checked" >
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="text" >
|
||||||
|
<string>Show Template Boxes</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
<action name="actionToggleBinarized" >
|
||||||
|
<property name="checkable" >
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="checked" >
|
||||||
|
<bool>false</bool>
|
||||||
|
</property>
|
||||||
|
<property name="text" >
|
||||||
|
<string>Show Binarized</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
<action name="actionSaveTemplateAs" >
|
||||||
|
<property name="text" >
|
||||||
|
<string>Save Template &As...</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
<action name="actionDelete" >
|
||||||
|
<property name="text" >
|
||||||
|
<string>&Delete</string>
|
||||||
|
</property>
|
||||||
|
<property name="shortcut" >
|
||||||
|
<string>Del</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
<action name="actionZoom" >
|
||||||
|
<property name="text" >
|
||||||
|
<string>&Zoom</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
<action name="actionUnzoom" >
|
||||||
|
<property name="text" >
|
||||||
|
<string>Unzoom</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
</widget>
|
||||||
|
<resources/>
|
||||||
|
<connections/>
|
||||||
|
</ui>
|
|
@ -0,0 +1,78 @@
|
||||||
|
<ui version="4.0" >
|
||||||
|
<class>OpenTemplateDialog</class>
|
||||||
|
<widget class="QDialog" name="OpenTemplateDialog" >
|
||||||
|
<property name="geometry" >
|
||||||
|
<rect>
|
||||||
|
<x>0</x>
|
||||||
|
<y>0</y>
|
||||||
|
<width>531</width>
|
||||||
|
<height>355</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="windowTitle" >
|
||||||
|
<string>Dialog</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QVBoxLayout" >
|
||||||
|
<item>
|
||||||
|
<widget class="QTreeView" name="treeView" >
|
||||||
|
<property name="rootIsDecorated" >
|
||||||
|
<bool>false</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<layout class="QHBoxLayout" >
|
||||||
|
<item>
|
||||||
|
<spacer>
|
||||||
|
<property name="orientation" >
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" >
|
||||||
|
<size>
|
||||||
|
<width>40</width>
|
||||||
|
<height>20</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="pushOpen" >
|
||||||
|
<property name="text" >
|
||||||
|
<string>&Open</string>
|
||||||
|
</property>
|
||||||
|
<property name="default" >
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="pushCancel" >
|
||||||
|
<property name="text" >
|
||||||
|
<string>&Cancel</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
<resources/>
|
||||||
|
<connections>
|
||||||
|
<connection>
|
||||||
|
<sender>pushCancel</sender>
|
||||||
|
<signal>clicked()</signal>
|
||||||
|
<receiver>OpenTemplateDialog</receiver>
|
||||||
|
<slot>reject()</slot>
|
||||||
|
<hints>
|
||||||
|
<hint type="sourcelabel" >
|
||||||
|
<x>502</x>
|
||||||
|
<y>327</y>
|
||||||
|
</hint>
|
||||||
|
<hint type="destinationlabel" >
|
||||||
|
<x>522</x>
|
||||||
|
<y>349</y>
|
||||||
|
</hint>
|
||||||
|
</hints>
|
||||||
|
</connection>
|
||||||
|
</connections>
|
||||||
|
</ui>
|
|
@ -0,0 +1,59 @@
|
||||||
|
##############################################################################
|
||||||
|
#
|
||||||
|
# Copyright (c) 2007-2008 Albert Cervera i Areny <albert@nan-tic.com>
|
||||||
|
#
|
||||||
|
# WARNING: This program as such is intended to be used by professional
|
||||||
|
# programmers who take the whole responsability of assessing all potential
|
||||||
|
# consequences resulting from its eventual inadequacies and bugs
|
||||||
|
# End users who are looking for a ready-to-use solution with commercial
|
||||||
|
# garantees and support are strongly adviced to contract a Free Software
|
||||||
|
# Service Company
|
||||||
|
#
|
||||||
|
# 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 2
|
||||||
|
# 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
#
|
||||||
|
##############################################################################
|
||||||
|
|
||||||
|
from PyQt4.QtCore import *
|
||||||
|
from PyQt4.QtGui import *
|
||||||
|
from PyQt4.uic import *
|
||||||
|
import rpc
|
||||||
|
from widget.model.group import *
|
||||||
|
from widget.model.treemodel import *
|
||||||
|
|
||||||
|
class OpenTemplateDialog(QDialog):
|
||||||
|
def __init__(self, parent=None):
|
||||||
|
QDialog.__init__(self, parent)
|
||||||
|
loadUi( 'opentemplate.ui', self )
|
||||||
|
|
||||||
|
visible = ['name', 'boxes']
|
||||||
|
self.fields = rpc.session.execute('/object', 'execute', 'nan.template', 'fields_get', visible)
|
||||||
|
ids = rpc.session.execute('/object', 'execute', 'nan.template', 'search', [])
|
||||||
|
self.group = ModelRecordGroup( 'nan.template', self.fields, ids )
|
||||||
|
self.treeModel = TreeModel( self )
|
||||||
|
self.treeModel.setModelGroup( self.group )
|
||||||
|
self.treeModel.setFields( self.fields )
|
||||||
|
self.treeModel.setShowBackgroundColor( False )
|
||||||
|
self.treeModel.setMode( TreeModel.ListMode )
|
||||||
|
self.treeModel.setFieldsOrder( ['name', 'boxes'] )
|
||||||
|
|
||||||
|
self.treeView.setModel( self.treeModel )
|
||||||
|
|
||||||
|
self.connect( self.pushOpen, SIGNAL('clicked()'), self.open )
|
||||||
|
|
||||||
|
def open(self):
|
||||||
|
index = self.treeView.selectionModel().currentIndex()
|
||||||
|
self.id = self.treeModel.id(index)
|
||||||
|
self.accept()
|
||||||
|
|
|
@ -0,0 +1,53 @@
|
||||||
|
#!/usr/bin/python
|
||||||
|
|
||||||
|
##############################################################################
|
||||||
|
#
|
||||||
|
# Copyright (c) 2007-2008 Albert Cervera i Areny <albert@nan-tic.com>
|
||||||
|
#
|
||||||
|
# WARNING: This program as such is intended to be used by professional
|
||||||
|
# programmers who take the whole responsability of assessing all potential
|
||||||
|
# consequences resulting from its eventual inadequacies and bugs
|
||||||
|
# End users who are looking for a ready-to-use solution with commercial
|
||||||
|
# garantees and support are strongly adviced to contract a Free Software
|
||||||
|
# Service Company
|
||||||
|
#
|
||||||
|
# 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 2
|
||||||
|
# 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
#
|
||||||
|
##############################################################################
|
||||||
|
|
||||||
|
|
||||||
|
from common import localization
|
||||||
|
localization.initializeTranslations()
|
||||||
|
|
||||||
|
# Load this after localization as these modules depend on it
|
||||||
|
from common import notifier, common
|
||||||
|
|
||||||
|
# Declare notifier handlers for the whole application
|
||||||
|
notifier.errorHandler = common.error
|
||||||
|
notifier.warningHandler = common.warning
|
||||||
|
|
||||||
|
|
||||||
|
from PyQt4.QtGui import *
|
||||||
|
from PyQt4.QtCore import *
|
||||||
|
import sys
|
||||||
|
from mainwindow import *
|
||||||
|
|
||||||
|
|
||||||
|
app = QApplication( sys.argv )
|
||||||
|
|
||||||
|
localization.initializeQtTranslations()
|
||||||
|
window = MainWindow()
|
||||||
|
window.show()
|
||||||
|
app.exec_()
|
|
@ -0,0 +1,7 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# Gamera, KTiny and NaNScaN
|
||||||
|
#export PYTHONPATH=/home/albert/python/lib/python:../../bin:../../..
|
||||||
|
# NaNScaN
|
||||||
|
export PYTHONPATH=..:../../ktiny/bin
|
||||||
|
./planta.py $1
|
|
@ -0,0 +1,298 @@
|
||||||
|
<ui version="4.0" >
|
||||||
|
<class>Form</class>
|
||||||
|
<widget class="QWidget" name="Form" >
|
||||||
|
<property name="geometry" >
|
||||||
|
<rect>
|
||||||
|
<x>0</x>
|
||||||
|
<y>0</y>
|
||||||
|
<width>288</width>
|
||||||
|
<height>496</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="windowTitle" >
|
||||||
|
<string>Form</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout" >
|
||||||
|
<item>
|
||||||
|
<layout class="QGridLayout" >
|
||||||
|
<item row="0" column="0" >
|
||||||
|
<widget class="QLabel" name="label" >
|
||||||
|
<property name="text" >
|
||||||
|
<string>X:</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="0" column="1" >
|
||||||
|
<widget class="QDoubleSpinBox" name="uiX" >
|
||||||
|
<property name="enabled" >
|
||||||
|
<bool>false</bool>
|
||||||
|
</property>
|
||||||
|
<property name="specialValueText" >
|
||||||
|
<string>-</string>
|
||||||
|
</property>
|
||||||
|
<property name="minimum" >
|
||||||
|
<double>-1.000000000000000</double>
|
||||||
|
</property>
|
||||||
|
<property name="maximum" >
|
||||||
|
<double>9999.000000000000000</double>
|
||||||
|
</property>
|
||||||
|
<property name="value" >
|
||||||
|
<double>-1.000000000000000</double>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="0" >
|
||||||
|
<widget class="QLabel" name="label_2" >
|
||||||
|
<property name="text" >
|
||||||
|
<string>Y:</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="1" >
|
||||||
|
<widget class="QDoubleSpinBox" name="uiY" >
|
||||||
|
<property name="enabled" >
|
||||||
|
<bool>false</bool>
|
||||||
|
</property>
|
||||||
|
<property name="specialValueText" >
|
||||||
|
<string>-</string>
|
||||||
|
</property>
|
||||||
|
<property name="minimum" >
|
||||||
|
<double>-1.000000000000000</double>
|
||||||
|
</property>
|
||||||
|
<property name="maximum" >
|
||||||
|
<double>99999.000000000000000</double>
|
||||||
|
</property>
|
||||||
|
<property name="value" >
|
||||||
|
<double>-1.000000000000000</double>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="2" column="0" >
|
||||||
|
<widget class="QLabel" name="label_3" >
|
||||||
|
<property name="text" >
|
||||||
|
<string>Width:</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="2" column="1" >
|
||||||
|
<widget class="QDoubleSpinBox" name="uiWidth" >
|
||||||
|
<property name="enabled" >
|
||||||
|
<bool>false</bool>
|
||||||
|
</property>
|
||||||
|
<property name="specialValueText" >
|
||||||
|
<string>-</string>
|
||||||
|
</property>
|
||||||
|
<property name="minimum" >
|
||||||
|
<double>-1.000000000000000</double>
|
||||||
|
</property>
|
||||||
|
<property name="maximum" >
|
||||||
|
<double>99999.000000000000000</double>
|
||||||
|
</property>
|
||||||
|
<property name="value" >
|
||||||
|
<double>-1.000000000000000</double>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="3" column="0" >
|
||||||
|
<widget class="QLabel" name="label_4" >
|
||||||
|
<property name="text" >
|
||||||
|
<string>Height:</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="3" column="1" >
|
||||||
|
<widget class="QDoubleSpinBox" name="uiHeight" >
|
||||||
|
<property name="enabled" >
|
||||||
|
<bool>false</bool>
|
||||||
|
</property>
|
||||||
|
<property name="specialValueText" >
|
||||||
|
<string>-</string>
|
||||||
|
</property>
|
||||||
|
<property name="minimum" >
|
||||||
|
<double>-1.000000000000000</double>
|
||||||
|
</property>
|
||||||
|
<property name="maximum" >
|
||||||
|
<double>99999.000000000000000</double>
|
||||||
|
</property>
|
||||||
|
<property name="value" >
|
||||||
|
<double>-1.000000000000000</double>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<layout class="QVBoxLayout" >
|
||||||
|
<item>
|
||||||
|
<layout class="QHBoxLayout" >
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="label_7" >
|
||||||
|
<property name="text" >
|
||||||
|
<string>Name</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<spacer>
|
||||||
|
<property name="orientation" >
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0" >
|
||||||
|
<size>
|
||||||
|
<width>40</width>
|
||||||
|
<height>20</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLineEdit" name="uiName" />
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<layout class="QVBoxLayout" name="_2" >
|
||||||
|
<item>
|
||||||
|
<layout class="QHBoxLayout" name="_3" >
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="label_9" >
|
||||||
|
<property name="text" >
|
||||||
|
<string>Recognizer:</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<spacer>
|
||||||
|
<property name="orientation" >
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0" >
|
||||||
|
<size>
|
||||||
|
<width>40</width>
|
||||||
|
<height>20</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QComboBox" name="uiRecognizer" />
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<layout class="QVBoxLayout" >
|
||||||
|
<item>
|
||||||
|
<layout class="QHBoxLayout" >
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="label_5" >
|
||||||
|
<property name="text" >
|
||||||
|
<string>Type:</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<spacer>
|
||||||
|
<property name="orientation" >
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0" >
|
||||||
|
<size>
|
||||||
|
<width>40</width>
|
||||||
|
<height>20</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QComboBox" name="uiType" />
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<layout class="QVBoxLayout" >
|
||||||
|
<item>
|
||||||
|
<layout class="QHBoxLayout" >
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="label_6" >
|
||||||
|
<property name="text" >
|
||||||
|
<string>Filter:</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<spacer>
|
||||||
|
<property name="orientation" >
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0" >
|
||||||
|
<size>
|
||||||
|
<width>40</width>
|
||||||
|
<height>20</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QComboBox" name="uiFilter" />
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<layout class="QVBoxLayout" >
|
||||||
|
<item>
|
||||||
|
<layout class="QHBoxLayout" >
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="label_8" >
|
||||||
|
<property name="text" >
|
||||||
|
<string>Text:</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<spacer>
|
||||||
|
<property name="orientation" >
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0" >
|
||||||
|
<size>
|
||||||
|
<width>40</width>
|
||||||
|
<height>20</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLineEdit" name="uiText" />
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<spacer>
|
||||||
|
<property name="orientation" >
|
||||||
|
<enum>Qt::Vertical</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0" >
|
||||||
|
<size>
|
||||||
|
<width>20</width>
|
||||||
|
<height>91</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
<zorder>layoutWidget</zorder>
|
||||||
|
<zorder></zorder>
|
||||||
|
</widget>
|
||||||
|
<resources/>
|
||||||
|
<connections/>
|
||||||
|
</ui>
|
Loading…
Reference in New Issue