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 
00032 import Api
00033 from Settings import *
00034 from Koo import Rpc
00035 
00036 import os
00037 import sys
00038 import Debug
00039 
00040 from PyQt4.QtCore  import  *
00041 from PyQt4.QtGui import *
00042 from PyQt4.uic import *
00043 
00044 from Paths import *
00045 
00046 try:
00047         if Settings.value('kde.enabled'):
00048                 from PyKDE4.kdecore import ki18n
00049                 isKdeAvailable = True
00050         else:
00051                 isKdeAvailable = False
00052 except:
00053         isKdeAvailable = False
00054 
00055 def isQtVersion45():
00056         return PYQT_VERSION >= 0x40500
00057 
00058 
00059 import common_rc
00060 
00061 
00062 
00063 sys.path.append( os.path.abspath(os.path.dirname(__file__)) )
00064 
00065 
00066 
00067 def nodeAttributes(node):
00068    result = {}
00069    attrs = node.attributes
00070    if attrs is None:
00071         return {}
00072    for i in range(attrs.length):
00073         result[attrs.item(i).localName] = attrs.item(i).nodeValue
00074    return result
00075 
00076 def sendEMail(to, subject, body):
00077         
00078         import smtplib
00079 
00080         
00081         from email.mime.text import MIMEText
00082 
00083         source = Settings.value('koo.smtp_from')
00084 
00085         msg = MIMEText(body)
00086 
00087         
00088         
00089         msg['Subject'] = subject
00090         msg['From'] = source
00091         msg['To'] = to
00092 
00093         
00094         
00095         s = smtplib.SMTP( Settings.value('koo.smtp_server') )
00096         s.sendmail(source, [to], msg.as_string())
00097         s.quit()
00098 
00099 
00100 (SelectionDialogUi, SelectionDialogBase) = loadUiType( uiPath('win_selection.ui') )
00101 
00102 
00103 
00104 
00105 
00106 
00107 class SelectionDialog(QDialog, SelectionDialogUi):      
00108         def __init__(self, title, values, parent=None):
00109                 QDialog.__init__(self, parent)
00110                 SelectionDialogUi.__init__(self)
00111                 self.setupUi( self )
00112 
00113                 if title:
00114                         self.uiTitle.setText( title )
00115                 for x in values.keys():
00116                         item = QListWidgetItem()
00117                         item.setText(x)
00118                         item.value = values[x]
00119                         self.uiList.addItem( item )
00120                 self.connect( self.pushAccept, SIGNAL('clicked()'), self.selected )
00121 
00122         def selected(self):
00123                 self.result = ""
00124                 item = self.uiList.currentItem()
00125                 self.result = ( unicode(item.text()), item.value )
00126                 self.accept()
00127 
00128 
00129 
00130 
00131 
00132 
00133 
00134 
00135 def selection(title, values, alwaysask=False):
00136         if len(values) == 0:
00137                 return None
00138         elif len(values)==1 and (not alwaysask):
00139                 key = values.keys()[0]
00140                 return (key, values[key])
00141         s = SelectionDialog(title, values)
00142         if s.exec_() == QDialog.Accepted:
00143                 return s.result
00144         else:
00145                 return False
00146         
00147 
00148 def warning(title, message):
00149         QApplication.setOverrideCursor( Qt.ArrowCursor )
00150         QMessageBox.warning(None, title, message)
00151         QApplication.restoreOverrideCursor()
00152 
00153 
00154 
00155 class ConcurrencyErrorDialog(QMessageBox):
00156         def __init__(self, parent=None):
00157                 QMessageBox.__init__(self, parent)      
00158                 self.setIcon( QMessageBox.Warning )
00159                 self.setWindowTitle( _('Concurrency warning') )
00160                 self.setText( _('<b>Write concurrency warning:</b><br/>This document has been modified while you were editing it.') )
00161                 self.addButton( _('Save anyway'), QMessageBox.AcceptRole )
00162                 self.addButton( _('Compare'), QMessageBox.ActionRole )
00163                 self.addButton( _('Do not save'), QMessageBox.RejectRole )
00164         
00165 
00166 def concurrencyError(model, id, context):
00167         QApplication.setOverrideCursor( Qt.ArrowCursor )
00168         dialog = ConcurrencyErrorDialog()
00169         result = dialog.exec_()
00170         QApplication.restoreOverrideCursor()
00171         if result == 0:
00172                 return True
00173         if result == 1:
00174                 Api.instance.createWindow( False, model, id, context=context )
00175 
00176         return False
00177 
00178 (ErrorDialogUi, ErrorDialogBase) = loadUiType( uiPath('error.ui') )
00179 
00180 
00181 
00182 
00183 
00184 
00185 
00186 class ErrorDialog( QDialog, ErrorDialogUi ):
00187         def __init__(self, title, message, details='', parent=None):
00188                 QDialog.__init__(self, parent)
00189                 ErrorDialogUi.__init__(self)
00190                 self.setupUi( self )
00191 
00192                 self.uiDetails.setText( details )
00193                 self.uiErrorInfo.setText( message )
00194                 self.uiErrorTitle.setText( title )
00195 
00196                 from Koo.Common import RemoteHelp
00197                 self.pushRemoteHelp.setVisible( RemoteHelp.isRemoteHelpAvailable() )
00198 
00199                 self.connect( self.pushSend, SIGNAL('clicked()'), self.send )
00200                 self.connect( self.pushRemoteHelp, SIGNAL('clicked()'), self.remoteHelp )
00201         
00202         def done(self, r):
00203                 QDialog.done(self, r)
00204 
00205         def remoteHelp(self):
00206                 from Koo.Common import RemoteHelp
00207                 RemoteHelp.remoteHelp( self )
00208 
00209         def send(self):
00210                 to = Settings.value('koo.smtp_backtraces_to')
00211 
00212                 button = QMessageBox.question(self, _('Send Error Information'), _('You are about to send the details of this error, database name, user ID, and server URL to %s. Do you want to proceed?') % to, QMessageBox.Yes | QMessageBox.No, QMessageBox.No)
00213                 if button == QMessageBox.No:
00214                         return
00215 
00216                 subject = 'Backtrace information: %s' % Rpc.session.databaseName
00217                 body = ''
00218                 body += 'Database: %s\n' % Rpc.session.databaseName
00219                 body += 'User ID: %s\n' % Rpc.session.uid
00220                 body += 'URL: %s\n\n' % Rpc.session.url
00221                 body += 'Backtrace:\n\n'
00222                 body += unicode( self.uiDetails.toPlainText() ).encode('ascii', 'replace')
00223                 try:
00224                         sendEMail( Settings.value('koo.smtp_backtraces_to'), subject, body)
00225                 except:
00226                         QMessageBox.warning( self, _('Send Error Information'), _('Error information could not be sent.') )
00227                         return
00228 
00229                 QMessageBox.information( self, _('Send Error Information'), _('Error information was successfully sent.') )
00230                 self.pushSend.setEnabled( False )
00231 
00232 
00233 
00234 
00235 def error(title, message, details=''):
00236         QApplication.setOverrideCursor( Qt.ArrowCursor )
00237         dialog = ErrorDialog( unicode(title), unicode(message), unicode(details) )
00238         dialog.exec_()
00239         QApplication.restoreOverrideCursor()
00240 
00241 
00242 (LostConnectionDialogUi, LostConnectionDialogBase) = loadUiType( uiPath('lostconnection.ui') )
00243 
00244 
00245 
00246 
00247 
00248 
00249 class LostConnectionDialog( QDialog, LostConnectionDialogUi ):
00250         def __init__(self, count, parent=None):
00251                 QDialog.__init__(self, parent)
00252                 LostConnectionDialogUi.__init__(self)
00253                 self.setupUi( self )
00254 
00255                 self.count = count
00256                 self.retry = True
00257                 self.remaining = 10
00258                 self.updateMessage()
00259                 self.uiTitle.setText( _('<b>Connection Lost:</b> %s') % count )
00260 
00261                 self.timer = QTimer()
00262                 self.timer.setInterval( 1000 )
00263                 self.connect( self.timer, SIGNAL('timeout()'), self.updateMessage )
00264                 self.connect( self, SIGNAL('rejected()'), self.stopTimer )
00265                 self.timer.start()
00266 
00267         def updateMessage(self):
00268                 self.uiMessage.setText( _('Connection with the server has been lost. Will retry connection in %d seconds.') % self.remaining )
00269                 self.remaining -= 1
00270                 if self.remaining < 0:
00271                         self.timer.stop()
00272                         self.accept()
00273 
00274         def stopTimer(self):
00275                 self.timer.stop()
00276 
00277 
00278 
00279 def lostConnectionError(count):
00280         QApplication.setOverrideCursor( Qt.ArrowCursor )
00281         dialog = LostConnectionDialog( count )
00282         if dialog.exec_() == QDialog.Rejected:
00283                 result = QMessageBox.warning( None, _("Quit"), _("Leaving the application now will lose all unsaved changes. Are you sure you want to quit?"), QMessageBox.Yes | QMessageBox.No, QMessageBox.No )
00284                 if result == QMessageBox.Yes:
00285                         QApplication.quit()
00286                         sys.exit(0)
00287         QApplication.restoreOverrideCursor()
00288         return True
00289 
00290 
00291 (ProgressDialogUi, ProgressDialogBase) = loadUiType( uiPath('progress.ui') )
00292                 
00293 
00294 
00295 
00296 
00297 
00298 
00299 
00300 
00301 class ProgressDialog(QDialog, ProgressDialogUi):
00302         def __init__(self, parent=None):
00303                 QDialog.__init__(self, parent)
00304                 ProgressDialogUi.__init__(self)
00305                 self.setupUi( self )
00306                 self.progressBar.setMinimum( 0 )
00307                 self.progressBar.setMaximum( 0 )
00308                 
00309         def start(self):
00310                 self.timer = QTimer()
00311                 self.connect( self.timer, SIGNAL('timeout()'), self.timeout )
00312                 self.timer.start( 2000 )
00313 
00314         def timeout(self):
00315                 self.timer.stop()
00316                 self.show()
00317                 
00318         def stop(self):
00319                 self.timer.stop()
00320                 self.accept()
00321 
00322 
00323 def openFile( fileName ):
00324         if os.name == 'nt':
00325                 os.startfile(fileName)
00326         elif os.uname()[0] == 'Darwin':
00327                 os.system('/usr/bin/open -a Preview %s' % fileName)
00328         else:
00329                 os.spawnlp(os.P_NOWAIT, 'xdg-open', 'xdg-open', fileName)
00330 
00331 
00332 
00333 
00334 
00335 def normalizeLabel( text ):
00336         res = ''
00337         underscore = False
00338         for x in text:
00339                 if x == '_':
00340                         if underscore:
00341                                 res += '_'
00342                                 underscore = False
00343                         else:
00344                                 underscore = True
00345                 else:
00346                         if underscore:
00347                                 res += '&'
00348                                 underscore = False
00349                         if x == '&':
00350                                 res += '&&'
00351                         else:
00352                                 res += x
00353         return res
00354 
00355 
00356 
00357 
00358 
00359 
00360 
00361 def stringToBool(text):
00362         if isinstance(text, str) or isinstance(text, unicode):
00363                 text = text.strip()
00364                 if text.lower() == 'true' or text == '1':
00365                         return True
00366                 if text.lower() == 'false' or text == '0':
00367                         return False
00368         return bool(text)
00369 
00370 
00371 
00372 
00373 def simplifyHtml(html):
00374         if isinstance(html, QString):
00375                 html = unicode( html )
00376         if '<p' in html:
00377                 index = html.find('<p')
00378                 html = html[index:]
00379                 index = html.rfind('</p>') + 4
00380                 html = html[:index]
00381         return html