Imported Upstream version 3.2.2
[debian/gnuradio] / grc / gui / FileDialogs.py
1 """
2 Copyright 2007 Free Software Foundation, Inc.
3 This file is part of GNU Radio
4
5 GNU Radio Companion is free software; you can redistribute it and/or
6 modify it under the terms of the GNU General Public License
7 as published by the Free Software Foundation; either version 2
8 of the License, or (at your option) any later version.
9
10 GNU Radio Companion is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
18 """
19
20 import pygtk
21 pygtk.require('2.0')
22 import gtk
23 from Dialogs import MessageDialogHelper
24 from Constants import \
25         DEFAULT_FILE_PATH, IMAGE_FILE_EXTENSION, \
26         NEW_FLOGRAPH_TITLE
27 import Preferences
28 from os import path
29 import Utils
30
31 ##################################################
32 # Constants
33 ##################################################
34 OPEN_FLOW_GRAPH = 'open flow graph'
35 SAVE_FLOW_GRAPH = 'save flow graph'
36 SAVE_IMAGE = 'save image'
37
38 FILE_OVERWRITE_MARKUP_TMPL="""\
39 File <b>$encode($filename)</b> Exists!\nWould you like to overwrite the existing file?"""
40
41 FILE_DNE_MARKUP_TMPL="""\
42 File <b>$encode($filename)</b> Does not Exist!"""
43
44 ##################################################
45 # File Filters
46 ##################################################
47 ##the filter for flow graph files
48 def get_flow_graph_files_filter():
49         filter = gtk.FileFilter()
50         filter.set_name('Flow Graph Files')
51         filter.add_pattern('*'+Preferences.file_extension())
52         return filter
53
54 ##the filter for image files
55 def get_image_files_filter():
56         filter = gtk.FileFilter()
57         filter.set_name('Image Files')
58         filter.add_pattern('*'+IMAGE_FILE_EXTENSION)
59         return filter
60
61 ##the filter for all files
62 def get_all_files_filter():
63         filter = gtk.FileFilter()
64         filter.set_name('All Files')
65         filter.add_pattern('*')
66         return filter
67
68 ##################################################
69 # File Dialogs
70 ##################################################
71 class FileDialogHelper(gtk.FileChooserDialog):
72         """
73         A wrapper class for the gtk file chooser dialog.
74         Implement a file chooser dialog with only necessary parameters.
75         """
76
77         def __init__(self, action, title):
78                 """
79                 FileDialogHelper contructor.
80                 Create a save or open dialog with cancel and ok buttons.
81                 Use standard settings: no multiple selection, local files only, and the * filter.
82                 @param action gtk.FILE_CHOOSER_ACTION_OPEN or gtk.FILE_CHOOSER_ACTION_SAVE
83                 @param title the title of the dialog (string)
84                 """
85                 ok_stock = {gtk.FILE_CHOOSER_ACTION_OPEN : 'gtk-open', gtk.FILE_CHOOSER_ACTION_SAVE : 'gtk-save'}[action]
86                 gtk.FileChooserDialog.__init__(self, title, None, action, ('gtk-cancel', gtk.RESPONSE_CANCEL, ok_stock, gtk.RESPONSE_OK))
87                 self.set_select_multiple(False)
88                 self.set_local_only(True)
89                 self.add_filter(get_all_files_filter())
90
91 class FileDialog(FileDialogHelper):
92         """A dialog box to save or open flow graph files. This is a base class, do not use."""
93
94         def __init__(self, current_file_path=''):
95                 """
96                 FileDialog constructor.
97                 @param current_file_path the current directory or path to the open flow graph
98                 """
99                 if not current_file_path: current_file_path = path.join(DEFAULT_FILE_PATH, NEW_FLOGRAPH_TITLE + Preferences.file_extension())
100                 if self.type == OPEN_FLOW_GRAPH:
101                         FileDialogHelper.__init__(self, gtk.FILE_CHOOSER_ACTION_OPEN, 'Open a Flow Graph from a File...')
102                         self.add_and_set_filter(get_flow_graph_files_filter())
103                         self.set_select_multiple(True)
104                 elif self.type == SAVE_FLOW_GRAPH:
105                         FileDialogHelper.__init__(self, gtk.FILE_CHOOSER_ACTION_SAVE, 'Save a Flow Graph to a File...')
106                         self.add_and_set_filter(get_flow_graph_files_filter())
107                         self.set_current_name(path.basename(current_file_path)) #show the current filename
108                 elif self.type == SAVE_IMAGE:
109                         FileDialogHelper.__init__(self, gtk.FILE_CHOOSER_ACTION_SAVE, 'Save a Flow Graph Screen Shot...')
110                         self.add_and_set_filter(get_image_files_filter())
111                         current_file_path = current_file_path + IMAGE_FILE_EXTENSION
112                         self.set_current_name(path.basename(current_file_path)) #show the current filename
113                 self.set_current_folder(path.dirname(current_file_path)) #current directory
114
115         def add_and_set_filter(self, filter):
116                 """
117                 Add the gtk file filter to the list of filters and set it as the default file filter.
118                 @param filter a gtk file filter.
119                 """
120                 self.add_filter(filter)
121                 self.set_filter(filter)
122
123         def get_rectified_filename(self):
124                 """
125                 Run the dialog and get the filename.
126                 If this is a save dialog and the file name is missing the extension, append the file extension.
127                 If the file name with the extension already exists, show a overwrite dialog.
128                 If this is an open dialog, return a list of filenames.
129                 @return the complete file path
130                 """
131                 if gtk.FileChooserDialog.run(self) != gtk.RESPONSE_OK: return None #response was cancel
132                 #############################################
133                 # Handle Save Dialogs
134                 #############################################
135                 if self.type in (SAVE_FLOW_GRAPH, SAVE_IMAGE):
136                         filename = self.get_filename()
137                         extension = {
138                                 SAVE_FLOW_GRAPH: Preferences.file_extension(),
139                                 SAVE_IMAGE: IMAGE_FILE_EXTENSION,
140                         }[self.type]
141                         #append the missing file extension if the filter matches
142                         if path.splitext(filename)[1].lower() != extension: filename += extension
143                         self.set_current_name(path.basename(filename)) #show the filename with extension
144                         if path.exists(filename): #ask the user to confirm overwrite
145                                 if MessageDialogHelper(
146                                         gtk.MESSAGE_QUESTION, gtk.BUTTONS_YES_NO, 'Confirm Overwrite!',
147                                         Utils.parse_template(FILE_OVERWRITE_MARKUP_TMPL, filename=filename),
148                                 ) == gtk.RESPONSE_NO: return self.get_rectified_filename()
149                         return filename
150                 #############################################
151                 # Handle Open Dialogs
152                 #############################################
153                 elif self.type in (OPEN_FLOW_GRAPH,):
154                         filenames = self.get_filenames()
155                         for filename in filenames:
156                                 if not path.exists(filename): #show a warning and re-run
157                                         MessageDialogHelper(
158                                                 gtk.MESSAGE_WARNING, gtk.BUTTONS_CLOSE, 'Cannot Open!',
159                                                 Utils.parse_template(FILE_DNE_MARKUP_TMPL, filename=filename),
160                                         )
161                                         return self.get_rectified_filename()
162                         return filenames
163
164         def run(self):
165                 """
166                 Get the filename and destroy the dialog.
167                 @return the filename or None if a close/cancel occured.
168                 """
169                 filename = self.get_rectified_filename()
170                 self.destroy()
171                 return filename
172
173 class OpenFlowGraphFileDialog(FileDialog): type = OPEN_FLOW_GRAPH
174 class SaveFlowGraphFileDialog(FileDialog): type = SAVE_FLOW_GRAPH
175 class SaveImageFileDialog(FileDialog): type = SAVE_IMAGE