示例#1
0
文件: gui.py 项目: jpasserin/brigks
def fileDialog(parent, title, initPath, filters, save=True):
    '''Create a file dialog 

	Args:
		parent (QWidget): Parent Widget
		title (str): Dialog title
		initPath (str): Initial Path
		filters (list of str): List of valid extension ie:["ma", "mb"]
		save (bool): Open dialog in save mode

	Returns:
		str
	'''
    filters = ";;".join(["%s (*.%s)" % (filter, filter)
                         for filter in filters] + ["All files (*.*)"])
    fileDialog = QFileDialog(parent, title, initPath, filters)

    if save:
        fileDialog.setAcceptMode(QFileDialog.AcceptSave)
    else:
        fileDialog.setAcceptMode(QFileDialog.AcceptOpen)

    fileDialog.exec_()
    if not fileDialog.result():
        return

    path = str(fileDialog.selectedFiles()[0])
    if not save and not os.path.exists(path):
        return

    return path
示例#2
0
    def ask_dir(self):
        """Show a dialog ask user.  """

        file_dialog = QFileDialog()
        _dir = file_dialog.getExistingDirectory(dir=os.path.dirname(self.dir))
        if _dir:
            self.dir = _dir
示例#3
0
    def save(self, save_as=False):
        if save_as:
            name_filter = "Graph files (*.json)"
            savepath = QFileDialog.getSaveFileName(filter=name_filter)
            if type(savepath) in [tuple, list]:
                pth = savepath[0]
            else:
                pth = savepath
            if not pth == '':
                self._current_file_name = pth
            else:
                self._current_file_name = "Untitled"
        else:
            if not os.path.isfile(self._current_file_name):
                name_filter = "Graph files (*.json)"
                savepath = QFileDialog.getSaveFileName(filter=name_filter)
                if type(savepath) in [tuple, list]:
                    pth = savepath[0]
                else:
                    pth = savepath
                if not pth == '':
                    self._current_file_name = pth
                else:
                    self._current_file_name = "Untitled"

        if self._current_file_name in ["", "Untitled"]:
            return

        if not self._current_file_name == '':
            with open(self._current_file_name, 'w') as f:
                saveData = self.graphManager.serialize()
                json.dump(saveData, f, indent=4)

            print(str("// saved: '{0}'".format(self._current_file_name)))
示例#4
0
    def importFbx(self):
        #Opens File Dialog
        self.consoleOut("Opening File Prompt...")
        options = QFileDialog.Options()
        #options |= QFileDialog.DontUseNativeDialog
        fbx_fileName, _ = QFileDialog.getOpenFileName(
            self,
            "Select FBX File.",
            "",
            "Filmbox FBX (*fbx);;All Files (*)",
            options=options)

        if fbx_fileName:
            #Debug Line
            print(fbx_fileName)
            #Try importing FBX
            try:
                print("Importing FBX...")
                self.consoleOut("Importing FBX...")
                fbx = hou.hipFile.importFBX(fbx_fileName)
                print("Imported Complete.")
                self.consoleOut("Importing Complete.")
            except:
                print("ERROR_IMPORTING_FBX 001")
                self.consoleOut("ERROR_IMPORTING_FBX_001")
示例#5
0
    def ask_dir(self):
        """Show a dialog ask user CONFIG['DIR'].  """

        file_dialog = QFileDialog()
        dir_ = file_dialog.getExistingDirectory(
            dir=unicode(Path(self.directory).parent))
        if dir_:
            self.directory = dir_
示例#6
0
 def onExport(self, root=None):
     try:
         savePath, selectedFilter = QFileDialog.getSaveFileName(filter="Python node data (*.pynode)", dir=root)
     except:
         savePath, selectedFilter = QFileDialog.getSaveFileName(filter="Python node data (*.pynode)")
     if savePath != "":
         with open(savePath, 'w') as f:
             f.write(self.nodeData)
         logger.info("{0} data successfully exported!".format(self.getName()))
示例#7
0
    def _on_show_browse_image_dialog(self):
        """
        Internal callback function that shows a file dialog for choosing an image from disk
        """

        file_dialog = QFileDialog(self,
                                  caption='Open Image',
                                  filter='Image Files (*.png *.jpg)')
        file_dialog.fileSelected.connect(self.set_thumbnail_path)
        file_dialog.exec_()
 def onExport(self, root=None):
     try:
         savePath, selectedFilter = QFileDialog.getSaveFileName(
             filter="Subgraph data (*.compound)", dir=root)
     except:
         savePath, selectedFilter = QFileDialog.getSaveFileName(
             filter="Subgraph data (*.compound)")
     if savePath != "":
         with open(savePath, 'w') as f:
             json.dump(self._rawNode.rawGraph.serialize(), f, indent=4)
         logger.info("{0} data successfully exported!".format(
             self.getName()))
示例#9
0
def browse_file(self):
    filter_list = 'File({})'.format(' '.join(
        ['*' + e for e in self.filters])) if self.filters else 'Any File(*)'
    if self.multiple:
        r_files, _ = QFileDialog.getOpenFileNames(self, 'Browse Files',
                                                  self.path, filter_list)
        if r_files:
            self.filesChanged.emit(r_files)
            self.path = r_files[0]
    else:
        r_file, _ = QFileDialog.getOpenFileName(self, 'Browse File', self.path,
                                                filter_list)
        if r_file:
            self.fileChanged.emit(r_file)
            self.path = r_file
示例#10
0
def get_file(directory, parent=None):
    """
    Show a open file dialog
    :param directory: str, root directory
    :param parent: QWidget
    :return: str, selected folder or None if no folder is selected
    """

    file_dialog = QFileDialog(parent)
    if directory:
        file_dialog.setDirectory(directory)
    directory = file_dialog.getOpenFileName()
    directory = python.force_list(directory)
    if directory:
        return directory
示例#11
0
    def browse_local(self, job):
        #for some reason, this doesn't use the native file browser if i just do QFileDialog
        filename, _ = QFileDialog.getOpenFileName(
            directory=os.path.abspath(job.scratch_dir))

        if filename:
            run(self.session, "open \"%s\"" % filename)
示例#12
0
def run_script(session):
    from chimerax.core.errors import UserError
    from chimerax.isolde.parmed import install_parmed_if_necessary
    install_parmed_if_necessary(session)
    from Qt.QtWidgets import QFileDialog
    import os
    filter = "AMBER Parameter files (*.mol2 *.frcmod)"
    files, _ = QFileDialog.getOpenFileNames(None, "Choose one .mol2 and one .frcmod file", "", filter)
    if len(files)!=2:
        raise UserError("Please select exactly one .mol2 and one .frcmod file!")
    matched_files = {}
    for f in files:
        matched_files[os.path.splitext(f)[1].lower()] = f
    if '.mol2' not in matched_files.keys() or '.frcmod' not in matched_files.keys():
        raise UserError('Please select exactly one .mol2 and one .frcmod file!')
    mol2, frcmod = matched_files['.mol2'], matched_files['.frcmod']
    from chimerax.isolde.openmm.amberff.amber_convert import amber_to_ffxml
    try:
        ffxml = amber_to_ffxml(frcmod, mol2)
    except Exception as e:
        raise UserError(f'ParmEd failed to run with the following error. Do your .mol2 and .frcmod match?\n {str(e)}')
    session.logger.info(f'Converted AMBER files {mol2} and {frcmod} to OpenMM FFXML file {ffxml}.')
    if hasattr(session, 'isolde'):
        ff_name = session.isolde.sim_params.forcefield
        forcefield = session.isolde.forcefield_mgr[ff_name]
        forcefield.loadFile(ffxml, resname_prefix='USER_')
        session.logger.info('This has been loaded into ISOLDE\'s forcefield for this session. For '
            'future sessions you should add it using the "Load residue MD definition(s)" button.')
    else:
        session.logger.info('On starting ISOLDE you can add it to the forcefield using the '
            '"Load residue MD definition(s)" button.')
        
示例#13
0
 def pickPath(self):
     initialPath = self.uiFilenameTXT.text() or self.defaultLocation
     initialPath = str(initialPath)
     while not os.path.exists(initialPath):
         if os.path.dirname(initialPath) == initialPath:
             break
         else:
             initialPath = os.path.dirname(initialPath)
     if QApplication.keyboardModifiers() == Qt.ControlModifier:
         import blurdev
         blurdev.osystem.explore(initialPath)
     else:
         if self._pickFolder:
             filepath = QFileDialog.getExistingDirectory(
                 self, self._caption, initialPath)
         elif self._openFile:
             filepath, _ = QtCompat.QFileDialog.getOpenFileName(
                 self, self._caption, initialPath, self._filters)
         else:
             filepath, _ = QtCompat.QFileDialog.getSaveFileName(
                 self, self._caption, initialPath, self._filters)
         if filepath:
             self.uiFilenameTXT.setText(filepath)
             if (not self.signalsBlocked()):
                 self.filenamePicked.emit(filepath)
示例#14
0
文件: pyxpad.py 项目: ZedThree/pyxpad
 def loadState(self, filename=None):
     """Load program state from a previous save file"""
     if filename is None:
         tr = self.tr
         filename, _ = QFileDialog.getOpenFileName(
             self,
             tr("Open file"),
             ".",
             filter=tr("PyXPad save file (*.pyx)"))
     if (filename is None) or (filename == ""):
         return  # Cancelled
     if not os.path.exists(filename):
         self.write("Could not find " + filename)
         return
     try:
         with open(filename, "rb") as f:
             self.sources.loadState(f)
             self.data = pickle.load(f)
     except EOFError:
         self.data = OrderedDict()
     except:
         e = sys.exc_info()
         self.write("Could not load state from file '" + filename + "'")
         self.write("\t ->" + str(e[1]))
         raise
     else:
         # If no exception raised, then update tables, lists
         self.data = OrderedDict(self.data)
         self.updateDataTable()
         self.write("** Loaded state from file '" + filename + "'")
 def onImport(self):
     openPath, selectedFilter = QFileDialog.getOpenFileName(
         filter="Subgraph data (*.compound)")
     if openPath != "":
         with open(openPath, 'r') as f:
             data = json.load(f)
             self.assignData(data)
示例#16
0
    def handle_scheme(self, url):
        command = url.path()

        if command.startswith("log"):
            self.session.logger.info(command[len("log_"):])
        elif command == "Open":
            self.openFile()
        elif command.startswith("FrameChange"):
            frame = int(command[len("FrameChange_T_"):])
            self.changeModel(frame, command[12] == 'T')
        elif command == "MovieDone":
            movie_encode(self.session, output=[self.movieName], format="h264")
        elif command == "MovieStart":
            fileName, filt = QFileDialog.getSaveFileName(
                caption="Save Movie", filter="MP4 File (*.mp4)")

            if fileName == "":
                return

            if fileName[-4:] != ".mp4":
                fileName = fileName + ".mp4"

            self.movieName = fileName
            movie_record(self.session)
            self.html_view.runJavaScript("startMovie()")
        elif command == "Attribute":
            self.loadAttributeFile()
        else:
            self.session.logger.info("Unknown Command: " + str(url))
示例#17
0
def ask_filename():
    # type: () -> Text
    """Ask user for filename.  """
    dummy = application()
    filename, _ = QFileDialog.getOpenFileName(
        None, caption='选择要读取的文件…', filter='*.xlsx')
    return filename
示例#18
0
文件: pyxpad.py 项目: ZedThree/pyxpad
    def addNetCDF(self):
        """
        Add a NetCDF file as a data source
        """
        try:
            from pyxpad.datafile import NetCDFDataSource
        except ImportError:
            self.main.write("Sorry, no NetCDF support")
            return
        try:
            # Get the file name
            tr = self.main.tr
            fname, _ = QFileDialog.getOpenFileName(
                self.main,
                tr("Open file"),
                ".",
                filter=tr("NetCDF files (*.nc *.cdl)"))
            if (fname is None) or (fname == ""):
                return  # Cancelled

            s = NetCDFDataSource(fname)

            self.addSource(s)
            self.updateDisplay()
        except:
            self.main.write("Error creating NetCDFDataSource")
            self.main.write(str(sys.exc_info()))
示例#19
0
    def loadFromFile(self):
        if self.sharedMemory.isAttached():
            self.detach()

        self.ui.label.setText(self.tr("Select an image file"))

        fileName, _ = QFileDialog.getOpenFileName(
            None, "", "", self.tr("Images (*.png *.xpm *.jpg)"))

        image = QImage()
        if not image.load(fileName):
            self.ui.label.setText(
                self.tr(
                    "Selected file is not an image, please select another."))
            return
        self.ui.label.setPixmap(QPixmap.fromImage(image))

        buffer = QBuffer()
        buffer.open(QBuffer.ReadWrite)
        out = QDataStream(buffer)
        out << image
        size = buffer.size()

        if not self.sharedMemory.create(size):
            self.ui.label.setText(
                self.tr("Unable to create shared memory segment."))
            return

        self.sharedMemory.lock()
        size = min(self.sharedMemory.size(), size)
        self.sharedMemory.data()[:size] = buffer.data()[:size]
        self.sharedMemory.unlock()
示例#20
0
文件: pyxpad.py 项目: ZedThree/pyxpad
    def addXPADtree(self):
        """Add an XPad tree as a data source, if UDA is available"""
        try:
            from pyxpad.xpadsource import XPadSource
        except ImportError:
            self.main.write("Sorry, no XPAD tree support")
            self.main.write(str(sys.exc_info()))
            return

        try:
            # Select the directory
            tr = self.main.tr
            dname = QFileDialog.getExistingDirectory(self.main,
                                                     tr("Open XPAD directory"),
                                                     QDir.currentPath())
            if (dname == "") or (dname is None):
                return
            # Create data source
            s = XPadSource.from_tree(dname)

            # Add data source and update
            self.addSource(s)
            self.updateDisplay()
        except:
            self.main.write("Error creating XPadSource")
            self.main.write(str(sys.exc_info()))
            raise
示例#21
0
文件: pyxpad.py 项目: ZedThree/pyxpad
    def addXPADtree(self):
        try:
            from pyxpad.xpadsource import XPadSource
        except ImportError:
            self.main.write("Sorry, no XPAD tree support")
            self.main.write(str(sys.exc_info()))
            return

        try:
            # Select the directory
            tr = self.main.tr
            dname = QFileDialog.getExistingDirectory(self.main, tr('Open XPAD directory'),
                                                     QDir.currentPath())
            if (dname == "") or (dname is None):
                return
            # Create data source
            s = XPadSource(dname)

            # Add data source and update
            self.addSource(s)
            self.updateDisplay()
        except:
            self.main.write("Error creating XPadSource")
            self.main.write(str(sys.exc_info()))
            raise
示例#22
0
 def onImport(self):
     openPath, selectedFilter = QFileDialog.getOpenFileName(filter="Python node data (*.pynode)")
     if openPath != "":
         with open(openPath, 'r') as f:
             dataString = f.read()
             self.tryApplyNodeData(dataString)
         EditorHistory().saveState("Import python node data", modify=True)
示例#23
0
 def do(self):
     name_filter = "Image (*.{0})".format(self.format.lower())
     fName = QFileDialog.getSaveFileName(filter=name_filter)
     if not fName[0] == '':
         print("save screen to {0}".format(fName[0]))
         img = self.canvas.grab()
         img.save(fName[0], format=self.format, quality=100)
示例#24
0
文件: pyxpad.py 项目: ZedThree/pyxpad
 def loadState(self, filename=None):
     """
     Loads program state from the given filename.
     If no filename is specified, then a dialog is created
     to ask the user for a file name.
     """
     if filename is None:
         tr = self.tr
         filename, _ = QFileDialog.getOpenFileName(self, tr('Open file'), '.',
                                                   filter=tr("PyXPad save file (*.pyx)"))
     if (filename is None) or (filename == ""):
         return  # Cancelled
     if not os.path.exists(filename):
         self.write("Could not find " + filename)
         return
     try:
         with open(filename, 'rb') as f:
             self.sources.loadState(f)
             self.data = pickle.load(f)
     except EOFError:
         self.data = OrderedDict()
     except:
         e = sys.exc_info()
         self.write("Could not load state from file '"+filename+"'")
         self.write("\t ->" + str(e[1]))
         raise
     else:
         # If no exception raised, then update tables, lists
         self.data = OrderedDict(self.data)
         self.updateDataTable()
         self.write("** Loaded state from file '"+filename+"'")
示例#25
0
    def do(self):
        try:
            rootGraph = self.pyFlowInstance.graphManager.get().findRootGraph()
            nodes = []
            connections = []
            global_config = {}
            for node in rootGraph.getNodesList():
                if node.name == GlobalPropertiesNode.__name__:
                    global_config["pipeline_version"] = "test"
                    global_config["Leon OS frequency [kHz]"] = get_pin_value(
                        node.inputs.values(), 'leon_os_freq')
                elif not isinstance(node, ExportableNode):
                    continue
                node, node_connections = node.export()
                nodes.append(node)
                connections += node_connections

            export = json.dumps({
                "globalProperties": global_config,
                "nodes": nodes,
                "connections": connections
            })

            outFilePath, filterString = QFileDialog.getSaveFileName(
                filter="Pipeline config (*.json)")
            if outFilePath != "":
                with open(outFilePath, 'w') as f:
                    f.write(export)
            print("saved!")
        except Exception as e:
            QMessageBox.warning(self.pyFlowInstance, "Warning", str(e))
示例#26
0
文件: scanner.py 项目: tws0002/Nuke-2
    def ask_path(self):
        """Show a dialog ask user self._config['DIR'].  """

        default_dir = os.path.dirname(self.path)

        _dir = QFileDialog.getExistingDirectory(self, dir=default_dir)
        if _dir:
            self.path = _dir
示例#27
0
 def saveOperation(self):
     filename = QFileDialog.getSaveFileName(self, 'Save file',
                                            './screenshot.png',
                                            '*.png;;*.jpg')
     if len(filename[0]) == 0:
         return
     else:
         self.saveScreenshot(False, filename[0], filename[1][2:])
         self.close()
示例#28
0
def select_folder_dialog(title, start_directory=None):
    """
    Shows select folder dialog
    :param title: str
    :param start_directory: str
    :return: str
    """

    return QFileDialog.getExistingDirectory(None, title, start_directory)
示例#29
0
    def _on_browse(self):
        """
        Opens file dialog
        """

        path = self.value()
        path = QFileDialog.getExistingDirectory(None, 'Browse Folder', path)
        if path:
            self.set_value(path)
示例#30
0
    def doExport(pyFlowInstance):

        supportedDataTypes = {
            "IntPin", "FloatPin", "BoolPin", "StringPin", "ExecPin"
        }
        supportedStructures = {PinStructure.Single}

        script = "# -*- coding: utf-8 -*-\n\n"
        script += "# This file was auto-generated by PyFlow exporter '{0} v{1}'\n".format(
            PythonScriptExporter.displayName(),
            str(PythonScriptExporter.version()))
        script += "#\tCreated: {0}\n\n".format(
            PythonScriptExporter.creationDateString())
        script += "EXPORTER_NAME = '{}'\n".format(
            PythonScriptExporter.displayName())
        script += "EXPORTER_VERSION = '{}'\n\n".format(
            str(PythonScriptExporter.version()))

        rootGraph = pyFlowInstance.graphManager.get().findRootGraph()

        if len(rootGraph.getNodesList()) == 0:
            QMessageBox.warning(pyFlowInstance, "Warning",
                                "Nothing to export!")
            return

        try:
            # create root level nodes
            graphScript = ""
            for node in rootGraph.getNodesList():
                graphScript += nodeToScript(node, supportedDataTypes,
                                            supportedStructures)

            graphScript += "\n# connect pins\n"

            # create connections
            # for node in rootGraph.getNodesList():
            #     for outPin in node.outputs.values():
            #         for inPinName in outPin.linkedTo:
            #             inPin = pyFlowInstance.graphManager.get().findPinByName(inPinName)
            #             graphScript += "{0} = ROOT_GRAPH.graphManager.findPinByName('{1}')\n".format(outPin.getFullName(), outPin.getFullName())
            #             graphScript += "{0} = ROOT_GRAPH.graphManager.findPinByName('{1}')\n".format(inPin.getFullName(), inPin.getFullName())
            #             graphScript += "connectPins({0}, {1})\n".format(outPin.getFullName(), inPin.getFullName())

            wrappedGraphScript = wrapStringToFunctionDef(
                "createScene", graphScript, {"ROOT_GRAPH": None})

            script += wrappedGraphScript + "\n"

            outFilePath, filterString = QFileDialog.getSaveFileName(
                filter=PythonScriptExporter.name_filter)
            if outFilePath != "":
                with open(outFilePath, 'w') as f:
                    f.write(script)
            print("saved!")
        except Exception as e:
            QMessageBox.warning(pyFlowInstance, "Warning", str(e))
示例#31
0
def save_file(self):
    filter_list = 'File({})'.format(' '.join(
        ['*' + e for e in self.filters])) if self.filters else 'Any File(*)'
    r_file, _ = QFileDialog.getSaveFileName(self, 'Save File', self.path,
                                            filter_list)
    if not r_file:
        return

    self.fileChanged.emit(r_file)
    self.path = r_file
示例#32
0
    def save_csv(self):
        """save data on current tab to CSV file"""
        filename, _ = QFileDialog.getSaveFileName(filter="CSV Files (*.csv)")
        if filename:
            s = self.get_csv()

            with open(filename, 'w') as f:
                f.write(s.strip())

            self.session.logger.status("saved to %s" % filename)
示例#33
0
文件: partedit.py 项目: wdas/partio
    def openSlot(self):
        """ Callback from Open button """

        # TODO: Check for edits and prompt to save dirty
        if self.data.filename:
            dirname = os.path.dirname(self.data.filename)
        else:
            dirname = os.getcwd()
        filename = QFileDialog.getOpenFileName(self, "Open particle file", dirname, "(*.bgeo *.geo *.bhclassic *.ptc *.pdb)")
        if filename:
            if isinstance(filename, tuple):
                filename = filename[0]
            self.open(str(filename))
示例#34
0
文件: qt.py 项目: renemilk/pyMor
 def save(self):
     if not config.HAVE_PYVTK:
         msg = QMessageBox(QMessageBox.Critical, 'Error', 'VTK output disabled. Pleas install pyvtk.')
         msg.exec_()
         return
     filename = QFileDialog.getSaveFileName(self, 'Save as vtk file')[0]
     base_name = filename.split('.vtu')[0].split('.vtk')[0].split('.pvd')[0]
     if base_name:
         if len(self.U) == 1:
             write_vtk(self.grid, NumpyVectorSpace.make_array(self.U[0]), base_name, codim=self.codim)
         else:
             for i, u in enumerate(self.U):
                 write_vtk(self.grid, NumpyVectorSpace.make_array(u), '{}-{}'.format(base_name, i),
                           codim=self.codim)
示例#35
0
文件: partedit.py 项目: wdas/partio
 def save(self, delta):
     """ Saves the file, either as full or delta """
     if self.data.filename:
         filename = self.data.filename
     else:
         filename = os.getcwd()
     filename = QFileDialog.getSaveFileName(self, "Save particle file", filename,
                                            'Particle Files (*.bgeo *.geo *.bhclassic *.ptc *.pdb );;All files(*)')
     if isinstance(filename, tuple):
         filename = filename[0]
     filename = str(filename)
     if not filename:
         return
     self.data.write(filename, delta)
示例#36
0
文件: pyxpad.py 项目: ZedThree/pyxpad
 def saveState(self, filename=None):
     """
     Saves program state to given file. If no file is specified,
     then a dialog is created to ask the user for one.
     """
     if filename is None:
         tr = self.tr
         defaultfile = os.path.join(self.config_dir, "saved_state.pyx")
         filename, _ = QFileDialog.getSaveFileName(self, dir=defaultfile,
                                                   filter=tr("PyXPad save file (*.pyx)"))
     if (filename is None) or (filename == ""):
         return
     try:
         with open(filename, 'wb') as f:
             self.sources.saveState(f)
             pickle.dump(self.data, f)
         self.write("** Saved state to file '"+filename+"'")
     except:
         e = sys.exc_info()
         self.write("Could not save state to file '"+filename+"'")
         self.write("\t ->" + str(e[1]))
示例#37
0
文件: pyxpad.py 项目: ZedThree/pyxpad
    def addBOUT(self):
        """
        Add a BOUT++ directory source
        """
        try:
            from pyxpad.boutsource import BoutDataSource

            # Select the directory
            tr = self.main.tr
            dname = QFileDialog.getExistingDirectory(self.main, tr('Open BOUT++ directory'),
                                                     QDir.currentPath())
            if (dname == "") or (dname is None):
                return
            # Create data source
            s = BoutDataSource(dname)

            # Add data source and update
            self.addSource(s)
            self.updateDisplay()
        except:
            self.main.write("Sorry, no BOUT++ support")
            raise
            return
示例#38
0
文件: pyxpad.py 项目: ZedThree/pyxpad
    def addNetCDF(self):
        """
        Add a NetCDF file as a data source
        """
        try:
            from pyxpad.datafile import NetCDFDataSource
        except ImportError:
            self.main.write("Sorry, no NetCDF support")
            return
        try:
            # Get the file name
            tr = self.main.tr
            fname, _ = QFileDialog.getOpenFileName(self.main, tr('Open file'), '.',
                                                   filter=tr("NetCDF files (*.nc *.cdl)"))
            if (fname is None) or (fname == ""):
                return  # Cancelled

            s = NetCDFDataSource(fname)

            self.addSource(s)
            self.updateDisplay()
        except:
            self.main.write("Error creating NetCDFDataSource")
            self.main.write(str(sys.exc_info()))