00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030 import gettext
00031 import re
00032 from Koo.Common import Common
00033 from Koo.Common import Numeric
00034 from Koo.Common import Api
00035
00036 from Koo import Rpc
00037 from Koo.Model.Group import RecordGroup
00038
00039 from PyQt4.QtGui import *
00040 from PyQt4.QtCore import *
00041 from PyQt4.uic import *
00042 from PyQt4.QtWebKit import *
00043 from PyQt4.QtNetwork import *
00044
00045
00046 (FullTextSearchDialogUi, FullTextSearchDialogBase) = loadUiType( Common.uiPath('full_text_search.ui') )
00047
00048
00049
00050
00051
00052 class FullTextSearchDialog( QDialog, FullTextSearchDialogUi ):
00053 def __init__(self, parent = None):
00054 QDialog.__init__( self, parent )
00055 FullTextSearchDialogUi.__init__( self )
00056 self.setupUi( self )
00057
00058 self.setModal( True )
00059
00060 self.result = None
00061
00062 self.setQueriesEnabled( False, _('Loading...') )
00063
00064 self.title = _('Full Text Search')
00065 self.title_results = _('Full Text Search (%%d result(s))')
00066
00067 self.setWindowTitle( self.title )
00068 self.uiWeb.page().setLinkDelegationPolicy( QWebPage.DelegateAllLinks )
00069 self.connect( self.uiWeb, SIGNAL('linkClicked(QUrl)'), self.open )
00070
00071 self.shortcuts = {}
00072 self.related = []
00073 self.limit = 10
00074 self.offset = 0
00075 self.pushNext.setEnabled( False )
00076 self.pushPrevious.setEnabled( False )
00077
00078 self.connect( self.uiHelp, SIGNAL('linkActivated(QString)'), self.showHelp )
00079 self.connect( self.pushClose, SIGNAL( "clicked()"), self.accept )
00080 self.connect( self.pushFind, SIGNAL( "clicked()"), self.find )
00081 self.connect( self.pushPrevious, SIGNAL( "clicked()" ), self.previous )
00082 self.connect( self.pushNext, SIGNAL( "clicked()" ), self.next )
00083 self.show()
00084
00085 QApplication.setOverrideCursor( Qt.WaitCursor )
00086 QTimer.singleShot( 0, self.initGui )
00087
00088 def showHelp(self, link):
00089 QApplication.postEvent( self.sender(), QEvent( QEvent.WhatsThis ) )
00090
00091 def initGui(self):
00092 try:
00093 answer = Rpc.session.call('/fulltextsearch', 'indexedModels', Rpc.session.context )
00094 self.uiModel.addItem( _('(Everywhere)'), QVariant( False ) )
00095 for x in answer:
00096 self.uiModel.addItem( x['name'], QVariant( x['id'] ) )
00097 if len(answer) == 0:
00098 self.setQueriesEnabled( False, _('<b>Full text search is not configured.</b><br/>Go to <i>Administration - Configuration - Full Text Search - Indexes</i>. Then add the fields you want to be indexed and finally use <i>Update Full Text Search</i>.') )
00099 QApplication.restoreOverrideCursor()
00100 return
00101 except:
00102 self.setQueriesEnabled( False, _('<b>Full text search module not installed.</b><br/>Go to <i>Administration - Modules administration - Uninstalled Modules</i> and add the <i>full_text_search</i> module.') )
00103 QApplication.restoreOverrideCursor()
00104 return
00105 self.setQueriesEnabled( True )
00106 self.uiText.setFocus()
00107 if QApplication.keyboardModifiers() & Qt.AltModifier:
00108 clipboard = QApplication.clipboard()
00109 if clipboard.supportsFindBuffer():
00110 text = clipboard.text( QClipboard.FindBuffer )
00111 elif clipboard.supportsSelection():
00112 text = clipboard.text( QClipboard.Selection )
00113 else:
00114 text = clipboard.text( QClipboard.Clipboard )
00115 self.uiText.setText( text )
00116 self.find()
00117 QApplication.restoreOverrideCursor()
00118
00119 def setQueriesEnabled(self, value, text = ''):
00120 self.uiModel.setEnabled( value )
00121 self.pushFind.setEnabled( value )
00122 self.uiText.setEnabled( value )
00123 self.uiWeb.page().mainFrame().setHtml( "<span style='font-size: large'>%s</span>" % text )
00124
00125 def textToQuery(self):
00126 q = unicode( self.uiText.text() ).strip()
00127 return re.sub(' +', '|', q)
00128
00129 def query(self):
00130 QApplication.setOverrideCursor( Qt.WaitCursor )
00131 if self.uiModel.currentIndex() == 0:
00132 model = False
00133 else:
00134 model = unicode( self.uiModel.itemData( self.uiModel.currentIndex() ).toString() )
00135
00136 answer = Rpc.session.execute('/fulltextsearch', 'search', self.textToQuery(), self.limit+1, self.offset , model, Rpc.session.context)
00137 if len(answer) < self.limit:
00138 self.pushNext.setEnabled( False )
00139 else:
00140
00141 answer = answer[:-1]
00142 self.pushNext.setEnabled( True )
00143 if self.offset == 0:
00144 self.pushPrevious.setEnabled( False )
00145 else:
00146 self.pushPrevious.setEnabled( True )
00147 self.showResults( answer )
00148 QApplication.restoreOverrideCursor()
00149
00150 def showResults(self, answer):
00151 for shortcut in self.shortcuts.keys():
00152 shortcut.setParent( None )
00153 self.shortcuts = {}
00154 number = 1
00155 page = ''
00156 for item in answer:
00157
00158 related = Rpc.session.execute('/object', 'execute', 'ir.values', 'get', 'action', 'client_action_relate', [(item['model_name'], False)], False, Rpc.session.context)
00159 actions = [x[2] for x in related]
00160 block = []
00161 related = ''
00162 for action in actions:
00163 f = lambda action: lambda: self.executeRelation(action)
00164 action['model_name'] = item['model_name']
00165 self.related.append( action )
00166 block.append( "<a href='relate/%d/%d'>%s</a>" % ( len(self.related)-1, item['id'], action['name'] ) )
00167 if len(block) == 3:
00168 related += '<div style="padding-left: 40px">%s</div>' % ' - '.join( block )
00169 block = []
00170 if block:
00171 related += '<div style="padding-left: 40px">%s</div>' % ' - '.join( block )
00172
00173 if related:
00174 related = '<div style="padding-top: 5px">%s</div>' % related
00175
00176
00177 url = 'open/%s/%s' % ( item['model_name'], item['id'] )
00178
00179
00180
00181 if number <= 10:
00182 self.shortcut = QShortcut( self )
00183 self.shortcut.setKey( 'Ctrl+%s' % number )
00184 self.shortcut.setContext( Qt.WidgetWithChildrenShortcut )
00185 self.connect( self.shortcut, SIGNAL('activated()'), self.openShortcut )
00186 self.shortcuts[ self.shortcut ] = url
00187 shortcut = ' - <span style="color: green; font-size: medium">[Ctrl+%d]</span>' % ( number % 10 )
00188 else:
00189 shortcut = ''
00190 number += 1
00191
00192
00193 page += """
00194 <div style="padding: 5px; font-size: large">
00195 <a href="%(url)s">%(model_label)s: %(name)s</a> %(shortcut)s - <span style="font-size: medium">[ %(ranking).2f ]</span></a>
00196 <div style="font-size: medium">%(headline)s</div>
00197 <div style="font-size: medium">%(related)s</div>
00198 </div>""" % {
00199 'url': url,
00200 'model_label': item['model_label'],
00201 'name': item['name'],
00202 'shortcut': shortcut,
00203 'ranking': item['ranking'],
00204 'headline': item['headline'],
00205 'related': related,
00206 }
00207
00208 page = '<html>%s</html>' % page
00209 self.uiWeb.page().mainFrame().setHtml( page )
00210
00211
00212 def previous(self):
00213 self.offset = max(0, self.offset - self.limit )
00214 self.query()
00215
00216 def next(self):
00217 self.offset = self.offset + self.limit
00218 self.query()
00219
00220 def find(self):
00221 self.offset = 0
00222 self.query()
00223
00224 def openShortcut( self ):
00225 self.open( self.shortcuts[ self.sender() ] )
00226
00227 def open( self, url ):
00228 QApplication.setOverrideCursor( Qt.WaitCursor )
00229 if isinstance( url, QUrl ):
00230 url = unicode( url.toString() )
00231 url = url.split('/')
00232 if url[0] == 'open':
00233 model = url[1]
00234 id = int(url[2])
00235
00236 if model == 'ir.ui.menu':
00237 Api.instance.executeKeyword('tree_but_open', {
00238 'model': model,
00239 'id': id,
00240 'report_type': 'pdf',
00241 'ids': [id]
00242 }, Rpc.session.context)
00243 else:
00244 Api.instance.createWindow(None, model, id, view_type='form', mode='form,tree')
00245 elif url[0] == 'relate':
00246 action = int(url[1])
00247 id = int(url[2])
00248 self.executeRelation( self.related[ action ], id )
00249 QApplication.restoreOverrideCursor()
00250 self.accept()
00251
00252 def executeRelation(self, action, id):
00253 group = RecordGroup( action['model_name'] )
00254 group.load( [id] )
00255 record = group.modelByIndex( 0 )
00256 action['domain'] = record.evaluateExpression( action['domain'], checkLoad=False)
00257 action['context'] = str( record.evaluateExpression( action['context'], checkLoad=False) )
00258 Api.instance.executeAction( action )
00259
00260