another distcheck fix
[debian/gnuradio] / grc / src / 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 ##@package grc.gui.FileDialogs
20 #The open/save dialog for flow graph fFileDialogiles and screen shots.
21
22 import pygtk
23 pygtk.require('2.0')
24 import gtk
25 from Dialogs import MessageDialogHelper
26 from grc.Constants import DEFAULT_FILE_PATH,FLOW_GRAPH_FILE_EXTENSION,IMAGE_FILE_EXTENSION,NEW_FLOGRAPH_TITLE
27 from os import path
28
29 OPEN_FLOW_GRAPH = 'open flow graph'
30 SAVE_FLOW_GRAPH = 'save flow graph'
31 SAVE_IMAGE = 'save image'
32
33 ##the filter for flow graph files
34 FLOW_GRAPH_FILE_FILTER = gtk.FileFilter()
35 FLOW_GRAPH_FILE_FILTER.set_name('GRC Files')
36 FLOW_GRAPH_FILE_FILTER.add_pattern('*'+FLOW_GRAPH_FILE_EXTENSION)
37 FLOW_GRAPH_FILE_FILTER.add_pattern('*.xml') #TEMP
38
39 ##the filter for image files
40 IMAGE_FILE_FILTER = gtk.FileFilter()
41 IMAGE_FILE_FILTER.set_name('Image Files')
42 IMAGE_FILE_FILTER.add_pattern('*'+IMAGE_FILE_EXTENSION)
43
44 ##the filter for all files
45 ALL_FILE_FILTER = gtk.FileFilter()
46 ALL_FILE_FILTER.set_name('All Files')
47 ALL_FILE_FILTER.add_pattern('*')
48
49 class FileDialogHelper(gtk.FileChooserDialog):
50         """
51         A wrapper class for the gtk file chooser dialog.
52         Implement a file chooser dialog with only necessary parameters.
53         """
54
55         def __init__(self, action, title):
56                 """!
57                 FileDialogHelper contructor.
58                 Create a save or open dialog with cancel and ok buttons.
59                 Use standard settings: no multiple selection, local files only, and the * filter.
60                 @param action gtk.FILE_CHOOSER_ACTION_OPEN or gtk.FILE_CHOOSER_ACTION_SAVE
61                 @param title the title of the dialog (string)
62                 """
63                 ok_stock = {gtk.FILE_CHOOSER_ACTION_OPEN : 'gtk-open', gtk.FILE_CHOOSER_ACTION_SAVE : 'gtk-save'}[action]
64                 gtk.FileChooserDialog.__init__(self, title, None, action, ('gtk-cancel', gtk.RESPONSE_CANCEL, ok_stock, gtk.RESPONSE_OK))
65                 self.set_select_multiple(False)
66                 self.set_local_only(True)
67                 self.add_filter(ALL_FILE_FILTER)
68
69 class FileDialog(FileDialogHelper):
70         """A dialog box to save or open flow graph files. This is a base class, do not use."""
71
72         def __init__(self, current_file_path=''):
73                 """!
74                 FileDialog constructor.
75                 @param current_file_path the current directory or path to the open flow graph
76                 """
77                 if not current_file_path: current_file_path = path.join(DEFAULT_FILE_PATH, NEW_FLOGRAPH_TITLE + FLOW_GRAPH_FILE_EXTENSION)
78                 if self.type == OPEN_FLOW_GRAPH:
79                         FileDialogHelper.__init__(self, gtk.FILE_CHOOSER_ACTION_OPEN, 'Open a Flow Graph from a File...')
80                         self.add_and_set_filter(FLOW_GRAPH_FILE_FILTER)
81                         self.set_select_multiple(True)
82                 elif self.type == SAVE_FLOW_GRAPH:
83                         FileDialogHelper.__init__(self, gtk.FILE_CHOOSER_ACTION_SAVE, 'Save a Flow Graph to a File...')
84                         self.add_and_set_filter(FLOW_GRAPH_FILE_FILTER)
85                         self.set_current_name(path.basename(current_file_path)) #show the current filename
86                 elif self.type == SAVE_IMAGE:
87                         FileDialogHelper.__init__(self, gtk.FILE_CHOOSER_ACTION_SAVE, 'Save a Flow Graph Screen Shot...')
88                         self.add_and_set_filter(IMAGE_FILE_FILTER)
89                         current_file_path = current_file_path + IMAGE_FILE_EXTENSION
90                         self.set_current_name(path.basename(current_file_path)) #show the current filename
91                 self.set_current_folder(path.dirname(current_file_path)) #current directory
92
93         def add_and_set_filter(self, filter):
94                 """!
95                 Add the gtk file filter to the list of filters and set it as the default file filter.
96                 @param filter a gtk file filter.
97                 """
98                 self.add_filter(filter)
99                 self.set_filter(filter)
100
101         def get_rectified_filename(self):
102                 """!
103                 Run the dialog and get the filename.
104                 If this is a save dialog and the file name is missing the extension, append the file extension.
105                 If the file name with the extension already exists, show a overwrite dialog.
106                 If this is an open dialog, return a list of filenames.
107                 @return the complete file path
108                 """
109                 if gtk.FileChooserDialog.run(self) != gtk.RESPONSE_OK: return None #response was cancel
110                 #############################################
111                 # Handle Save Dialogs
112                 #############################################
113                 if self.type in (SAVE_FLOW_GRAPH, SAVE_IMAGE):
114                         filename = self.get_filename()
115                         for extension, filter in (
116                                 (FLOW_GRAPH_FILE_EXTENSION, FLOW_GRAPH_FILE_FILTER),
117                                 (IMAGE_FILE_EXTENSION, IMAGE_FILE_FILTER),
118                         ): #append the missing file extension if the filter matches
119                                 if filename[len(filename)-len(extension):] != extension \
120                                         and filter == self.get_filter(): filename += extension
121                         self.set_current_name(path.basename(filename)) #show the filename with extension
122                         if path.exists(filename): #ask the user to confirm overwrite
123                                 if MessageDialogHelper(
124                                         gtk.MESSAGE_QUESTION, gtk.BUTTONS_YES_NO, 'Confirm Overwrite!',
125                                         'File <b>"%s"</b> Exists!\nWould you like to overwrite the existing file?'%filename,
126                                 ) == gtk.RESPONSE_NO: return self.get_rectified_filename()
127                         return filename
128                 #############################################
129                 # Handle Open Dialogs
130                 #############################################
131                 elif self.type in (OPEN_FLOW_GRAPH,):
132                         filenames = self.get_filenames()
133                         for filename in filenames:
134                                 if not path.exists(filename): #show a warning and re-run
135                                         MessageDialogHelper(
136                                                 gtk.MESSAGE_WARNING, gtk.BUTTONS_CLOSE, 'Cannot Open!',
137                                                 'File <b>"%s"</b> Does not Exist!'%filename,
138                                         )
139                                         return self.get_rectified_filename()
140                         return filenames
141
142         def run(self):
143                 """!
144                 Get the filename and destroy the dialog.
145                 @return the filename or None if a close/cancel occured.
146                 """
147                 filename = self.get_rectified_filename()
148                 self.destroy()
149                 return filename
150
151 class OpenFlowGraphFileDialog(FileDialog): type = OPEN_FLOW_GRAPH
152 class SaveFlowGraphFileDialog(FileDialog): type = SAVE_FLOW_GRAPH
153 class SaveImageFileDialog(FileDialog): type = SAVE_IMAGE
154