Exemple #1
0
    def uploadException(self,err):
        """Upload an exception to the website"""
        try:
            """Ask if the error can be uploaded.  Unless the user doesn't want to be bothered with asking."""
            if not redREnviron.settings['askToUploadError']:
                res = redREnviron.settings['uploadError']
            else:
                import redRQTCore
                self.msg = redRQTCore.dialog(parent=qApp.canvasDlg,title='Red-R Error')
                
                error = redRQTCore.widgetBox(self.msg,orientation='vertical')
                redRQTCore.widgetLabel(error, label='Do you wish to report the Error Log?')
                buttons = redRQTCore.widgetBox(error,orientation='horizontal')

                redRQTCore.button(buttons, label = _('Yes'), callback = self.uploadYes)
                redRQTCore.button(buttons, label = _('No'), callback = self.uploadNo)
                self.checked = False
                self.remember = redRQTCore.checkBox(error,label='response', displayLabel=None,
                buttons=[_('Remember my Response')],callback=self.rememberResponse)
                res = self.msg.exec_()
                redREnviron.settings['uploadError'] = res
            
            """If errors can be uploaded then send them"""
            if res == 1:
                # print 'in res'
                err['version'] = redREnviron.version['SVNVERSION']
                err['type'] = redREnviron.version['TYPE']
                err['redRversion'] = redREnviron.version['REDRVERSION']
                if os.name == 'nt':
                    err['os'] = 'Windows'
                if redREnviron.settings['canContact']:
                    err['email'] = redREnviron.settings['email']
                params = urllib.urlencode(err)
                headers = {"Content-type": "application/x-www-form-urlencoded", "Accept": "text/plain"}
                conn = httplib.HTTPConnection("red-r.org",80)
                conn.request("POST", "/errorReport.php", params,headers)
                log(REDRCORE, INFO, '<strong>Error data posted to the server</strong>')
            else:
                return
        except: 
            pass
    def createReportsMenu(self, widgets = None, schemaImage=True):
        qname = QFileDialog.getSaveFileName(self, _("Write Report to File"), 
        redREnviron.directoryNames['documentsDir'] + "/Report-"+unicode(datetime.date.today())+".odt", 
        "Open Office Text (*.odt);; HTML (*.html);; LaTeX (*.tex)")
        if qname.isEmpty(): return
        qname = unicode(qname)
        
        name = unicode(qname) # this is the file name of the Report
        # name = os.path.join(redREnviron.directoryNames['redRDir'],'restr.odt')
        
        if os.path.splitext(name)[1].lower() not in [".odt", ".html", ".tex"]: name = name + '.odt'
        
        fileDir = os.path.split(name)[0]
        try:
            fileDir2 = os.path.join(fileDir, os.path.splitext("Data-"+os.path.split(name)[1])[0])
            fileDir2 = fileDir2.replace('\\', '/')
            fd3 = []
            for p in fileDir2.split('/'):
                if len(p) > 8 and ' ' in p:
                    fd3.append(p.replace(' ', '')[:6]+'~1')
                else:
                    fd3.append(p)
            fileDir2 = '/'.join(fd3)
            if os.path.isdir(fileDir2):
                shutil.rmtree(fileDir2)

            # makes a file to place the temp data into.  
            #This will be deleted once the odt file is made.
            os.mkdir(fileDir2)  
        
        except Exception as inst:
            redRLog.log(redRLog.REDRCORE, redRLog.ERROR,redRLog.formatException())
        
        
        # show the report list and allow the user to select widgets to include in the report.
        ## get the report info for the included widgets.
        # reportData = self.getReportData(fileDir2,name)
        if not widgets:
            import redRObjects
            import redRSignalManager
            widgets = redRObjects.instances()
            
            """The widgets may be stored in a seemingly random manner in the instances section.  We would like to show the report in a way that makes sense.  There is no real easy way to do this but the general plan that seems to work most often is to ensure that we don't make a report on a widget that has signaling widgets that aren't reported on yet.  That is we report widgets as they send data.  Note that this might not be the chronological order in which the analysis was carried out but it will be close to the order in which processing occurs from the data's point of view."""
            
            widgetscopy = widgets
            widgetsnew = []
            def copywidget(w, widgetscopy, widgetsnew):
                """Copies the widget to the right place."""
                widgetscopy.remove(w)
                widgetsnew.append(w)
            def parentsIndexed(olist, widgetsnew):
                """Checks if the parent widgets have been indexed or not"""
                for o in olist:
                    if o not in widgetsnew: return False
                return True
            while len(widgetscopy) > 0:
                for w in widgetscopy:
                    if len(w.inputs.inputs.keys()) == 0 or len(redRSignalManager.getInputInstances(w)) == 0:
                        copywidget(w, widgetscopy, widgetsnew)
                        print 'Copy widget %s' % unicode(w)
                    elif parentsIndexed(redRSignalManager.getInputInstances(w), widgetsnew):
                        copywidget(w, widgetscopy, widgetsnew)
                        print 'Copy widget %s' % unicode(w)
            print unicode(widgetsnew)
            print unicode(widgets)
            widgets = widgetsnew
        done = self.createReport(fileDir2,name,widgets,schemaImage)
        if not done:
            return
        if os.name =='nt':
            #os.startfile
            doneDialog = redRQTCore.dialog(self.schema,title=_("Report Generated"))
            redRQTCore.widgetLabel(doneDialog,label=_('Your report is ready to view.'))
            buttonBox = redRQTCore.widgetBox(doneDialog,orientation='horizontal')
            acceptButton = redRQTCore.button(buttonBox,_('View Report'))
            QObject.connect(acceptButton, SIGNAL("clicked()"), doneDialog.accept)
            acceptButton = redRQTCore.button(buttonBox,_('Done'))
            QObject.connect(acceptButton, SIGNAL("clicked()"), doneDialog.reject)
            if doneDialog.exec_() == QDialog.Accepted:
                try:
                    os.startfile(name,'open')
                except:
                    redRLog.log(redRLog.REDRCORE, redRLog.ERROR, redRLog.formatException())
                    mb = QMessageBox(_("Cannot Open File"), 
                    _("Red-R cannot open the reports file. Please open the file manually.\nThis is not a problem with Red-R, it is a problem with your document viewer."), 
                    QMessageBox.Information, 
                    QMessageBox.Ok | QMessageBox.Default, QMessageBox.NoButton, QMessageBox.NoButton,self)
                    mb.exec_()

        else:
            QMessageBox.information(self, _("Red-R Canvas"), _("Your report is ready to view."), 
            QMessageBox.Ok + QMessageBox.Default )          
    def __init__(self, parent=None, signalManager=None, title=_("Generic Red-R Widget"), 
    savePosition=True, wantGUIDialog = 0, resizingEnabled=1, **args):
        """
        Initialization
        Parameters:
            title - The title of the\ widget, including a "&" (for shortcut in about box)
            wantGraph - displays a save graph button or not
        """

        # if resizingEnabled: 
        QMainWindow.__init__(self, parent, Qt.Window)
        # else:               
        #QMainWindow.__init__(self, parent, Qt.Dialog | Qt.MSWindowsFixedSizeDialogHint)# | Qt.WindowMinimizeButtonHint)

        # directories are better defined this way, otherwise .ini files get written in many places
        #self.__dict__.update(redREnviron.directoryNames)

        # self.setCaption(title.replace("&","")) # used for widget caption

        self.captionTitle = self._widgetInfo.widgetName
        self.progressBarHandler = None  # handler for progress bar events
        self.processingHandler = None   # handler for processing events


        self.widgetStateHandler = None
        self.widgetState = {"Info":{}, "Warning":{}, "Error":{}}

        self.windowState = {}
        self.rVariableNameEdits = {}
        self.savePosition = True
        self.hasBeenShown = False
        self.hasAdvancedOptions = wantGUIDialog
        # print 'setting layout for widget'
        # print 'printing the layout', self.layout()
        #self.setLayout(QVBoxLayout())
        self.layout().setMargin(2)
        self.setSizePolicy(QSizePolicy.Minimum,QSizePolicy.Minimum)
        topWidgetPart = redRQTCore.widgetBox(self, orientation="vertical", margin=0)
        topWidgetPart.setSizePolicy(QSizePolicy.Minimum,QSizePolicy.Minimum)
        self.setCentralWidget(topWidgetPart)
        self.controlArea = redRQTCore.widgetBox(topWidgetPart, orientation="vertical", margin=4)
        #self.controlArea.setLayout(QVBoxLayout())
        #self.controlArea.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
        self.controlArea.setMinimumWidth(300)
        topWidgetPart.layout().setAlignment(self.controlArea,Qt.AlignTop | Qt.AlignLeft)
        #self.layout().addWidget(self.controlArea)
        bottomArea = redRQTCore.widgetBox(topWidgetPart, orientation="horizontal", margin=4)
        self.bottomAreaLeft = redRQTCore.widgetBox(bottomArea, orientation = 'horizontal')
        self.bottomAreaCenter = redRQTCore.widgetBox(bottomArea, sizePolicy = QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed),
        orientation = 'horizontal')
        self.bottomAreaRight = redRQTCore.widgetBox(bottomArea, orientation = 'horizontal')
        #start widget GUI
        
        
        ### status bar ###
        self.statusBar = QStatusBar()
        self.statusBar.setSizeGripEnabled(False)
        
        self.setStatusBar(self.statusBar)
        
        self.RIndicator = redRQTCore.widgetLabel(self.statusBar)
        self.statusBar.addWidget(self.RIndicator)
        self.setRIndicator(False)
        
        
        
        self.status = redRQTCore.statusLabel(self.statusBar, '')
        self.status.setStatus(0)
        self.status.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Minimum)
        self.statusBar.addPermanentWidget(self.status,4)
        #self.statusBar.setStyleSheet("QStatusBar { border-top: 2px solid gray; } ")
        # self.statusBar.setStyleSheet("QLabel { border-top: 2px solid red; } ")

        ################
        # Notes Dock ###
        ################
        minWidth = 200
        self.notesDock=QDockWidget(_('Notes'))
        self.notesDock.setObjectName('widgetNotes')
        
        QObject.connect(self.notesDock,SIGNAL('topLevelChanged(bool)'),self.updateDock)
        
        self.notesDock.setFeatures(QDockWidget.DockWidgetMovable | QDockWidget.DockWidgetFloatable)
        self.notesDock.setMinimumWidth(minWidth)
        self.notesDock.setAllowedAreas(Qt.RightDockWidgetArea | Qt.TopDockWidgetArea | Qt.BottomDockWidgetArea)
        self.addDockWidget(Qt.RightDockWidgetArea,self.notesDock)

        self.notesBox = redRQTCore.widgetBox(None,orientation=QVBoxLayout())
        self.notesDock.setWidget(self.notesBox)
        
        self.notesBox.setMinimumWidth(minWidth)
        self.notesBox.setMinimumHeight(50)
        self.notesBox.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)

        redRQTCore.widgetLabel(self.notesBox, label="Notes:", icon=redRStyle.notesIcon)

        self.notes = redRQTCore.textEdit(self.notesBox, label = _('Notes'), displayLabel=False)
        self.notes.setMinimumWidth(minWidth)
        self.notes.setMinimumHeight(50)
        self.notes.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)

        
        #####################
        # Rvariable Names ###
        #####################
        self.RvarNamesDock=QDockWidget(_('R Varibale Names'))
        self.RvarNamesDock.setObjectName('RvarNamesDock')
        
        QObject.connect(self.RvarNamesDock,SIGNAL('topLevelChanged(bool)'),self.updateDock)
        
        self.RvarNamesDock.setFeatures(QDockWidget.DockWidgetMovable | QDockWidget.DockWidgetFloatable)
        self.RvarNamesDock.setMinimumWidth(minWidth)
        self.RvarNamesDock.setAllowedAreas(Qt.RightDockWidgetArea | Qt.TopDockWidgetArea | Qt.BottomDockWidgetArea)
        
        self.addDockWidget(Qt.RightDockWidgetArea,self.RvarNamesDock)

        self.RVarNamesBox = redRQTCore.widgetBox(None,orientation=QVBoxLayout())
        self.RvarNamesDock.setWidget(self.RVarNamesBox)

        self.RVarNamesBox.setMinimumHeight(50)
        redRQTCore.widgetLabel(self.RVarNamesBox, label=_("R variable names for this widget:"),
        icon=redRStyle.RIcon)

        #self.ROutput = redRQTCore.textEdit(self.RVarNamesBox, label = _('R Output'),displayLabel=False)
        #self.ROutput.setMinimumWidth(minWidth)
        #self.ROutput.setMinimumHeight(50)
        #self.ROutput.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
        redRQTCore.button(self.RVarNamesBox, label = _('Accept Names'), callback = self._acceptNameChanges, toolTip = _('This resets the R variable names for this widget to the indicated names.  This should only be done if the user really knows what she is doing!!'))
        
        
        ################
        # R output ###
        ################
        self.RoutputDock=QDockWidget(_('R Output'))
        self.RoutputDock.setObjectName('RoutputDock')
        
        QObject.connect(self.RoutputDock,SIGNAL('topLevelChanged(bool)'),self.updateDock)
        
        self.RoutputDock.setFeatures(QDockWidget.DockWidgetMovable | QDockWidget.DockWidgetFloatable)
        self.RoutputDock.setMinimumWidth(minWidth)
        self.RoutputDock.setAllowedAreas(Qt.RightDockWidgetArea | Qt.TopDockWidgetArea | Qt.BottomDockWidgetArea)
        
        self.addDockWidget(Qt.RightDockWidgetArea,self.RoutputDock)

        self.ROutputBox = redRQTCore.widgetBox(None,orientation=QVBoxLayout())
        self.RoutputDock.setWidget(self.ROutputBox)

        self.ROutputBox.setMinimumHeight(50)
        redRQTCore.widgetLabel(self.ROutputBox, label=_("R code executed in this widget:"),
        icon=redRStyle.RIcon)

        self.ROutput = redRQTCore.textEdit(self.ROutputBox, label = _('R Output'),displayLabel=False)
        self.ROutput.setMinimumWidth(minWidth)
        self.ROutput.setMinimumHeight(50)
        self.ROutput.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
        redRQTCore.button(self.ROutputBox, label = _('Run Selected Code'), callback = self._runSelectedRCode, toolTip = _('You may select any code to execute in the R session.  This will override anything that other widgets have done to this point and will be overriden when this widget executes again.  Use this with great caution.'))
        
        ### help ####
        self.helpFile = None
        
        if hasattr(self,'_widgetInfo'):
            (file,ext) = os.path.basename(self._widgetInfo.fullName).split('.')
            path = os.path.join(redREnviron.directoryNames['libraryDir'],
            self._widgetInfo.package['Name'],'help',file+'.html')
            if os.path.exists(path):
                self.helpFile = path
        if not self.helpFile:
            self.helpFile = 'http://www.red-r.org/documentation'

                
        
        
        ################
        # Status Bar ###
        ################
        
        self.windowState['documentationState'] = {'notesBox':True,'ROutputBox':False,'RVarNamesBox':False}

        docBox = redRQTCore.widgetBox(self.controlArea,orientation='horizontal',spacing=4)
         
        self.collapseDataButton = redRQTCore.button(docBox, 'Collapse Data', toggleButton = True, toolTip = _('Collapses data to a saved file and sets the widget as collapsed'), callback = self.collapseData)
        self.neverCollapseDataButton = redRQTCore.button(docBox, 'Never Collapse', toggleButton = True, toolTip = _('Sets this data to never be collapsed by the data collapsing system'), callback = self.neverCollapseData)
        self.collapseDataButton.hide() # these are set to hidden by default because we don't want to belaybor widgets that don't set R data.
        self.neverCollapseDataButton.hide()

        self.showNotesButton = redRQTCore.button(docBox, '',toggleButton=True, 
        icon=os.path.join(redREnviron.directoryNames['picsDir'], 'Notes-icon.png'),
        toolTip=_('Notes'),
        callback = self.updateDocumentationDock)
        
        self.showRVarNamesButton = redRQTCore.button(docBox, '',toggleButton=True, 
        icon=os.path.join(redREnviron.directoryNames['picsDir'], 'options.png'),
        toolTip=_('RVarNames'),
        callback = self.updateDocumentationDock)
        
        self.showROutputButton = redRQTCore.button(docBox, '',toggleButton=True, 
        icon=os.path.join(redREnviron.directoryNames['picsDir'], 'R_icon.png'),
        toolTip=_('R Code'),
        callback = self.updateDocumentationDock)
        
        self.printButton = redRQTCore.button(docBox, "",
        icon=os.path.join(redREnviron.directoryNames['picsDir'], 'printer_icon.png'),
        toolTip=_('Print'),
        callback = self.createReport)

        self.showHelpButton = redRQTCore.button(docBox, '',
        icon=os.path.join(redREnviron.directoryNames['picsDir'], 'help_icon.png'),
        toolTip=_('Help'),
        callback = self.showHelp)

        self.includeInReport = redRQTCore.button(docBox, '', 
        icon=os.path.join(redREnviron.directoryNames['picsDir'], 'report_icon.png'),
        toolTip=_('Include In Report'), toggleButton = True)
        self.includeInReport.setChecked(True)
        
        ###############################################
        self.statusBar.addPermanentWidget(docBox)
        # self.statusBar.addPermanentWidget(self.showNotesButton)
        # self.statusBar.addPermanentWidget(self.showROutputButton)
        # self.statusBar.addPermanentWidget(self.showHelpButton)        
        # self.statusBar.addPermanentWidget(self.printButton)
        # self.statusBar.addPermanentWidget(self.includeInReport)
        
        
        self.GUIDialogDialog = None
        self.windowState['leftDockState'] = False
        if self.hasAdvancedOptions:
            self.leftDock=QDockWidget(_('Advanced Options'))
            self.leftDock.setObjectName('leftDock')
            self.connect(self.leftDock,SIGNAL('topLevelChanged(bool)'),self.updateDock)
            self.leftDock.setFeatures(QDockWidget.DockWidgetMovable | QDockWidget.DockWidgetFloatable)
            self.leftDock.setSizePolicy(QSizePolicy.Minimum, QSizePolicy.Minimum)
            self.addDockWidget(Qt.LeftDockWidgetArea,self.leftDock)
            self.GUIDialog = redRQTCore.widgetBox(self.leftDock,orientation='vertical')
            self.GUIDialog.setSizePolicy(QSizePolicy.Minimum, QSizePolicy.Minimum)
            self.leftDock.setWidget(self.GUIDialog)
            self.leftDockButton = redRQTCore.button(self.bottomAreaLeft, _('Advanced Options'),toggleButton=True, callback = self.showLeftDock)
            self.statusBar.insertPermanentWidget(2,self.leftDockButton)
            self.windowState['leftDockState'] = True