00001 """
00002 Copyright 2007 Free Software Foundation, Inc.
00003 This file is part of GNU Radio
00004
00005 GNU Radio Companion is free software; you can redistribute it and/or
00006 modify it under the terms of the GNU General Public License
00007 as published by the Free Software Foundation; either version 2
00008 of the License, or (at your option) any later version.
00009
00010 GNU Radio Companion is distributed in the hope that it will be useful,
00011 but WITHOUT ANY WARRANTY; without even the implied warranty of
00012 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
00013 GNU General Public License for more details.
00014
00015 You should have received a copy of the GNU General Public License
00016 along with this program; if not, write to the Free Software
00017 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
00018 """
00019
00020
00021
00022
00023 import pygtk
00024 pygtk.require('2.0')
00025 import gtk
00026 from Dialogs import MessageDialogHelper
00027 from grc.Constants import DEFAULT_FILE_PATH,FLOW_GRAPH_FILE_EXTENSION,IMAGE_FILE_EXTENSION,NEW_FLOGRAPH_TITLE
00028 from os import path
00029
00030 OPEN_FLOW_GRAPH = 'open flow graph'
00031 SAVE_FLOW_GRAPH = 'save flow graph'
00032 SAVE_IMAGE = 'save image'
00033
00034
00035 FLOW_GRAPH_FILE_FILTER = gtk.FileFilter()
00036 FLOW_GRAPH_FILE_FILTER.set_name('GRC Files')
00037 FLOW_GRAPH_FILE_FILTER.add_pattern('*'+FLOW_GRAPH_FILE_EXTENSION)
00038 FLOW_GRAPH_FILE_FILTER.add_pattern('*.xml')
00039
00040
00041 IMAGE_FILE_FILTER = gtk.FileFilter()
00042 IMAGE_FILE_FILTER.set_name('Image Files')
00043 IMAGE_FILE_FILTER.add_pattern('*'+IMAGE_FILE_EXTENSION)
00044
00045
00046 ALL_FILE_FILTER = gtk.FileFilter()
00047 ALL_FILE_FILTER.set_name('All Files')
00048 ALL_FILE_FILTER.add_pattern('*')
00049
00050 class FileDialogHelper(gtk.FileChooserDialog):
00051 """
00052 A wrapper class for the gtk file chooser dialog.
00053 Implement a file chooser dialog with only necessary parameters.
00054 """
00055
00056 def __init__(self, action, title):
00057 """!
00058 FileDialogHelper contructor.
00059 Create a save or open dialog with cancel and ok buttons.
00060 Use standard settings: no multiple selection, local files only, and the * filter.
00061 @param action gtk.FILE_CHOOSER_ACTION_OPEN or gtk.FILE_CHOOSER_ACTION_SAVE
00062 @param title the title of the dialog (string)
00063 """
00064 ok_stock = {gtk.FILE_CHOOSER_ACTION_OPEN : 'gtk-open', gtk.FILE_CHOOSER_ACTION_SAVE : 'gtk-save'}[action]
00065 gtk.FileChooserDialog.__init__(self, title, None, action, ('gtk-cancel', gtk.RESPONSE_CANCEL, ok_stock, gtk.RESPONSE_OK))
00066 self.set_select_multiple(False)
00067 self.set_local_only(True)
00068 self.add_filter(ALL_FILE_FILTER)
00069
00070 class FileDialog(FileDialogHelper):
00071 """A dialog box to save or open flow graph files. This is a base class, do not use."""
00072
00073 def __init__(self, current_file_path=''):
00074 """!
00075 FileDialog constructor.
00076 @param current_file_path the current directory or path to the open flow graph
00077 """
00078 if not current_file_path: current_file_path = path.join(DEFAULT_FILE_PATH, NEW_FLOGRAPH_TITLE + FLOW_GRAPH_FILE_EXTENSION)
00079 if self.type == OPEN_FLOW_GRAPH:
00080 FileDialogHelper.__init__(self, gtk.FILE_CHOOSER_ACTION_OPEN, 'Open a Flow Graph from a File...')
00081 self.add_and_set_filter(FLOW_GRAPH_FILE_FILTER)
00082 self.set_select_multiple(True)
00083 elif self.type == SAVE_FLOW_GRAPH:
00084 FileDialogHelper.__init__(self, gtk.FILE_CHOOSER_ACTION_SAVE, 'Save a Flow Graph to a File...')
00085 self.add_and_set_filter(FLOW_GRAPH_FILE_FILTER)
00086 self.set_current_name(path.basename(current_file_path))
00087 elif self.type == SAVE_IMAGE:
00088 FileDialogHelper.__init__(self, gtk.FILE_CHOOSER_ACTION_SAVE, 'Save a Flow Graph Screen Shot...')
00089 self.add_and_set_filter(IMAGE_FILE_FILTER)
00090 current_file_path = current_file_path + IMAGE_FILE_EXTENSION
00091 self.set_current_name(path.basename(current_file_path))
00092 self.set_current_folder(path.dirname(current_file_path))
00093
00094 def add_and_set_filter(self, filter):
00095 """!
00096 Add the gtk file filter to the list of filters and set it as the default file filter.
00097 @param filter a gtk file filter.
00098 """
00099 self.add_filter(filter)
00100 self.set_filter(filter)
00101
00102 def get_rectified_filename(self):
00103 """!
00104 Run the dialog and get the filename.
00105 If this is a save dialog and the file name is missing the extension, append the file extension.
00106 If the file name with the extension already exists, show a overwrite dialog.
00107 If this is an open dialog, return a list of filenames.
00108 @return the complete file path
00109 """
00110 if gtk.FileChooserDialog.run(self) != gtk.RESPONSE_OK: return None
00111
00112
00113
00114 if self.type in (SAVE_FLOW_GRAPH, SAVE_IMAGE):
00115 filename = self.get_filename()
00116 for extension, filter in (
00117 (FLOW_GRAPH_FILE_EXTENSION, FLOW_GRAPH_FILE_FILTER),
00118 (IMAGE_FILE_EXTENSION, IMAGE_FILE_FILTER),
00119 ):
00120 if filename[len(filename)-len(extension):] != extension \
00121 and filter == self.get_filter(): filename += extension
00122 self.set_current_name(path.basename(filename))
00123 if path.exists(filename):
00124 if MessageDialogHelper(
00125 gtk.MESSAGE_QUESTION, gtk.BUTTONS_YES_NO, 'Confirm Overwrite!',
00126 'File <b>"%s"</b> Exists!\nWould you like to overwrite the existing file?'%filename,
00127 ) == gtk.RESPONSE_NO: return self.get_rectified_filename()
00128 return filename
00129
00130
00131
00132 elif self.type in (OPEN_FLOW_GRAPH,):
00133 filenames = self.get_filenames()
00134 for filename in filenames:
00135 if not path.exists(filename):
00136 MessageDialogHelper(
00137 gtk.MESSAGE_WARNING, gtk.BUTTONS_CLOSE, 'Cannot Open!',
00138 'File <b>"%s"</b> Does not Exist!'%filename,
00139 )
00140 return self.get_rectified_filename()
00141 return filenames
00142
00143 def run(self):
00144 """!
00145 Get the filename and destroy the dialog.
00146 @return the filename or None if a close/cancel occured.
00147 """
00148 filename = self.get_rectified_filename()
00149 self.destroy()
00150 return filename
00151
00152 class OpenFlowGraphFileDialog(FileDialog): type = OPEN_FLOW_GRAPH
00153 class SaveFlowGraphFileDialog(FileDialog): type = SAVE_FLOW_GRAPH
00154 class SaveImageFileDialog(FileDialog): type = SAVE_IMAGE
00155