Imported Upstream version 3.2.2
[debian/gnuradio] / grc / gui / FileDialogs.py
diff --git a/grc/gui/FileDialogs.py b/grc/gui/FileDialogs.py
new file mode 100644 (file)
index 0000000..3b210c3
--- /dev/null
@@ -0,0 +1,175 @@
+"""
+Copyright 2007 Free Software Foundation, Inc.
+This file is part of GNU Radio
+
+GNU Radio Companion is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+GNU Radio Companion is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
+"""
+
+import pygtk
+pygtk.require('2.0')
+import gtk
+from Dialogs import MessageDialogHelper
+from Constants import \
+       DEFAULT_FILE_PATH, IMAGE_FILE_EXTENSION, \
+       NEW_FLOGRAPH_TITLE
+import Preferences
+from os import path
+import Utils
+
+##################################################
+# Constants
+##################################################
+OPEN_FLOW_GRAPH = 'open flow graph'
+SAVE_FLOW_GRAPH = 'save flow graph'
+SAVE_IMAGE = 'save image'
+
+FILE_OVERWRITE_MARKUP_TMPL="""\
+File <b>$encode($filename)</b> Exists!\nWould you like to overwrite the existing file?"""
+
+FILE_DNE_MARKUP_TMPL="""\
+File <b>$encode($filename)</b> Does not Exist!"""
+
+##################################################
+# File Filters
+##################################################
+##the filter for flow graph files
+def get_flow_graph_files_filter():
+       filter = gtk.FileFilter()
+       filter.set_name('Flow Graph Files')
+       filter.add_pattern('*'+Preferences.file_extension())
+       return filter
+
+##the filter for image files
+def get_image_files_filter():
+       filter = gtk.FileFilter()
+       filter.set_name('Image Files')
+       filter.add_pattern('*'+IMAGE_FILE_EXTENSION)
+       return filter
+
+##the filter for all files
+def get_all_files_filter():
+       filter = gtk.FileFilter()
+       filter.set_name('All Files')
+       filter.add_pattern('*')
+       return filter
+
+##################################################
+# File Dialogs
+##################################################
+class FileDialogHelper(gtk.FileChooserDialog):
+       """
+       A wrapper class for the gtk file chooser dialog.
+       Implement a file chooser dialog with only necessary parameters.
+       """
+
+       def __init__(self, action, title):
+               """
+               FileDialogHelper contructor.
+               Create a save or open dialog with cancel and ok buttons.
+               Use standard settings: no multiple selection, local files only, and the * filter.
+               @param action gtk.FILE_CHOOSER_ACTION_OPEN or gtk.FILE_CHOOSER_ACTION_SAVE
+               @param title the title of the dialog (string)
+               """
+               ok_stock = {gtk.FILE_CHOOSER_ACTION_OPEN : 'gtk-open', gtk.FILE_CHOOSER_ACTION_SAVE : 'gtk-save'}[action]
+               gtk.FileChooserDialog.__init__(self, title, None, action, ('gtk-cancel', gtk.RESPONSE_CANCEL, ok_stock, gtk.RESPONSE_OK))
+               self.set_select_multiple(False)
+               self.set_local_only(True)
+               self.add_filter(get_all_files_filter())
+
+class FileDialog(FileDialogHelper):
+       """A dialog box to save or open flow graph files. This is a base class, do not use."""
+
+       def __init__(self, current_file_path=''):
+               """
+               FileDialog constructor.
+               @param current_file_path the current directory or path to the open flow graph
+               """
+               if not current_file_path: current_file_path = path.join(DEFAULT_FILE_PATH, NEW_FLOGRAPH_TITLE + Preferences.file_extension())
+               if self.type == OPEN_FLOW_GRAPH:
+                       FileDialogHelper.__init__(self, gtk.FILE_CHOOSER_ACTION_OPEN, 'Open a Flow Graph from a File...')
+                       self.add_and_set_filter(get_flow_graph_files_filter())
+                       self.set_select_multiple(True)
+               elif self.type == SAVE_FLOW_GRAPH:
+                       FileDialogHelper.__init__(self, gtk.FILE_CHOOSER_ACTION_SAVE, 'Save a Flow Graph to a File...')
+                       self.add_and_set_filter(get_flow_graph_files_filter())
+                       self.set_current_name(path.basename(current_file_path)) #show the current filename
+               elif self.type == SAVE_IMAGE:
+                       FileDialogHelper.__init__(self, gtk.FILE_CHOOSER_ACTION_SAVE, 'Save a Flow Graph Screen Shot...')
+                       self.add_and_set_filter(get_image_files_filter())
+                       current_file_path = current_file_path + IMAGE_FILE_EXTENSION
+                       self.set_current_name(path.basename(current_file_path)) #show the current filename
+               self.set_current_folder(path.dirname(current_file_path)) #current directory
+
+       def add_and_set_filter(self, filter):
+               """
+               Add the gtk file filter to the list of filters and set it as the default file filter.
+               @param filter a gtk file filter.
+               """
+               self.add_filter(filter)
+               self.set_filter(filter)
+
+       def get_rectified_filename(self):
+               """
+               Run the dialog and get the filename.
+               If this is a save dialog and the file name is missing the extension, append the file extension.
+               If the file name with the extension already exists, show a overwrite dialog.
+               If this is an open dialog, return a list of filenames.
+               @return the complete file path
+               """
+               if gtk.FileChooserDialog.run(self) != gtk.RESPONSE_OK: return None #response was cancel
+               #############################################
+               # Handle Save Dialogs
+               #############################################
+               if self.type in (SAVE_FLOW_GRAPH, SAVE_IMAGE):
+                       filename = self.get_filename()
+                       extension = {
+                               SAVE_FLOW_GRAPH: Preferences.file_extension(),
+                               SAVE_IMAGE: IMAGE_FILE_EXTENSION,
+                       }[self.type]
+                       #append the missing file extension if the filter matches
+                       if path.splitext(filename)[1].lower() != extension: filename += extension
+                       self.set_current_name(path.basename(filename)) #show the filename with extension
+                       if path.exists(filename): #ask the user to confirm overwrite
+                               if MessageDialogHelper(
+                                       gtk.MESSAGE_QUESTION, gtk.BUTTONS_YES_NO, 'Confirm Overwrite!',
+                                       Utils.parse_template(FILE_OVERWRITE_MARKUP_TMPL, filename=filename),
+                               ) == gtk.RESPONSE_NO: return self.get_rectified_filename()
+                       return filename
+               #############################################
+               # Handle Open Dialogs
+               #############################################
+               elif self.type in (OPEN_FLOW_GRAPH,):
+                       filenames = self.get_filenames()
+                       for filename in filenames:
+                               if not path.exists(filename): #show a warning and re-run
+                                       MessageDialogHelper(
+                                               gtk.MESSAGE_WARNING, gtk.BUTTONS_CLOSE, 'Cannot Open!',
+                                               Utils.parse_template(FILE_DNE_MARKUP_TMPL, filename=filename),
+                                       )
+                                       return self.get_rectified_filename()
+                       return filenames
+
+       def run(self):
+               """
+               Get the filename and destroy the dialog.
+               @return the filename or None if a close/cancel occured.
+               """
+               filename = self.get_rectified_filename()
+               self.destroy()
+               return filename
+
+class OpenFlowGraphFileDialog(FileDialog): type = OPEN_FLOW_GRAPH
+class SaveFlowGraphFileDialog(FileDialog): type = SAVE_FLOW_GRAPH
+class SaveImageFileDialog(FileDialog): type = SAVE_IMAGE