bzr branch
http://bzr.ed.am/gtk/eog-manage-raws
2
by edam
- added status bar information |
1 |
import eog, gtk, os, re |
1
by edam
initial comit |
2 |
|
3 |
class HelloWorldPlugin(eog.Plugin): |
|
4 |
||
5 |
raw_file_extensions = [ 'cr2', '3fr', 'ari', 'arw', 'srf', 'sr2', 'bay', |
|
6 |
'crw', 'cr2', 'cap', 'iiq', 'eip', 'dcs', 'dcr', 'drf', 'k25', 'kdc', |
|
7 |
'dng', 'erf', 'fff', 'mef', 'mos', 'mrw', 'nef', 'nrw', 'orf', 'ptx', |
|
8 |
'pef', 'pxn', 'r3d', 'raf', 'raw', 'rw2', 'rwl', 'rwz', 'x3f' ] |
|
9 |
||
10 |
def __init__( self ): |
|
11 |
eog.Plugin.__init__( self ) |
|
12 |
||
13 |
def activate( self, window ): |
|
14 |
self._window = window |
|
15 |
||
16 |
# insert menu item |
|
17 |
manager = window.get_ui_manager() |
|
2
by edam
- added status bar information |
18 |
self._action_group = gtk.ActionGroup( 'EogRawToolsPluginActions' ) |
19 |
self._action_group.add_actions( [ ( 'EogPluginRunKeepRaw', None, |
|
20 |
_( 'Keep Raw Image' ), 'K', |
|
21 |
_( "Move the accompanying raw file to a 'raw' subdirectory" ), |
|
1
by edam
initial comit |
22 |
self.on_keep_raw_image ) ] ) |
2
by edam
- added status bar information |
23 |
self._action_group.add_actions( [ ( 'EogPluginRunDeleteRaw', None, |
24 |
_( 'Delete Unkept Raw Images' ), None, |
|
25 |
_( "Delete all raw files in the current image's directory (the unkept ones)" ), |
|
26 |
self.on_delete_raw_images ) ] ) |
|
1
by edam
initial comit |
27 |
manager.insert_action_group( self._action_group, -1 ) |
28 |
self._ui_id = manager.add_ui_from_string( """ |
|
29 |
<ui> |
|
30 |
<menubar name="MainMenu"> |
|
31 |
<menu name="ToolsMenu" action="Tools"> |
|
32 |
<separator /> |
|
2
by edam
- added status bar information |
33 |
<menuitem name="EogPluginRunKeepRaw" |
1
by edam
initial comit |
34 |
action="EogPluginRunKeepRaw" /> |
2
by edam
- added status bar information |
35 |
<menuitem name="EogPluginRunDeleteRaw" |
36 |
action="EogPluginRunDeleteRaw" /> |
|
1
by edam
initial comit |
37 |
<separator /> |
38 |
</menu> |
|
39 |
</menubar> |
|
40 |
<popup name="ViewPopup"> |
|
41 |
<separator /> |
|
42 |
<menuitem action="EogPluginRunKeepRaw" /> |
|
43 |
<separator /> |
|
44 |
</popup> |
|
45 |
</ui> |
|
46 |
""" ) |
|
47 |
||
2
by edam
- added status bar information |
48 |
# insert status bar |
49 |
self._statusbar = gtk.Statusbar() |
|
50 |
self._statusbar.set_has_resize_grip( False ) |
|
51 |
self._statusbar.set_size_request( 85, 10 ) |
|
52 |
statusbar = window.get_statusbar() |
|
53 |
statusbar.pack_end( self._statusbar, False, False, 0 ); |
|
54 |
self._statusbar.show() |
|
55 |
||
1
by edam
initial comit |
56 |
# connect to selection change |
57 |
thumb_view = window.get_thumb_view() |
|
58 |
self._on_selection_change_id = thumb_view.connect_after( \ |
|
2
by edam
- added status bar information |
59 |
'selection_changed', self.on_selection_change, window ) |
1
by edam
initial comit |
60 |
|
61 |
# init ui state |
|
2
by edam
- added status bar information |
62 |
self.update_status( window ) |
1
by edam
initial comit |
63 |
|
64 |
def deactivate( self, window ): |
|
65 |
||
2
by edam
- added status bar information |
66 |
# disconnect handlers |
67 |
thumb_view = window.get_thumb_view() |
|
68 |
thumb_view.disconnect( self._on_selection_change_id ) |
|
69 |
||
1
by edam
initial comit |
70 |
# remove menu items |
71 |
manager = window.get_ui_manager() |
|
72 |
manager.remove_ui( self._ui_id ) |
|
73 |
manager.remove_action_group( self._action_group ) |
|
74 |
manager.ensure_update() |
|
75 |
||
2
by edam
- added status bar information |
76 |
# remove status bar entry |
77 |
statusbar = window.get_statusbar() |
|
78 |
statusbar.remove( self._statusbar ) |
|
1
by edam
initial comit |
79 |
|
80 |
def on_selection_change( self, view, data ): |
|
2
by edam
- added status bar information |
81 |
self.update_status( data ) |
82 |
||
83 |
def get_raw_filename_from_image( self, image ): |
|
1
by edam
initial comit |
84 |
fname = image.get_file().get_path() |
85 |
||
2
by edam
- added status bar information |
86 |
# get the base fileanme (with no extension), read for searching |
1
by edam
initial comit |
87 |
base_fname = image.get_file().get_path() |
88 |
pos = base_fname.rfind( '.' ) |
|
89 |
if( pos != -1 ): |
|
2
by edam
- added status bar information |
90 |
|
91 |
# check if the extension of the current image makes it a raw file |
|
92 |
for ext in self.raw_file_extensions + \ |
|
93 |
map( lambda x: x.upper(), self.raw_file_extensions ): |
|
94 |
if( base_fname[ pos : ] == ext ): |
|
95 |
return False; |
|
96 |
||
97 |
# remove extension from base filename |
|
1
by edam
initial comit |
98 |
base_fname = base_fname[ 0 : pos ] |
99 |
||
100 |
# check for stupidity |
|
101 |
if( base_fname[ -1 : None ] == '/' ): |
|
2
by edam
- added status bar information |
102 |
return False |
103 |
||
104 |
# loop through valid raw file extensions, uppercase and lowercase |
|
105 |
for ext in self.raw_file_extensions + \ |
|
106 |
map( lambda x: x.upper(), self.raw_file_extensions ): |
|
107 |
||
108 |
# if the raw file exists, we found it |
|
109 |
if( os.path.isfile( base_fname + '.' + ext ) ): |
|
110 |
return os.path.basename( base_fname + '.' + ext ); |
|
1
by edam
initial comit |
111 |
|
112 |
# path the raw images will be moved to |
|
113 |
raw_path = os.path.dirname( fname ) + '/raw'; |
|
114 |
||
2
by edam
- added status bar information |
115 |
# loop through valid raw file extensions, uppercase and lowercase |
1
by edam
initial comit |
116 |
for ext in self.raw_file_extensions + \ |
2
by edam
- added status bar information |
117 |
map( lambda x: x.upper(), self.raw_file_extensions ): |
118 |
||
119 |
# if the raw file exists, we found it |
|
120 |
if( os.path.isfile( os.path.dirname( fname ) + '/raw/' + \ |
|
121 |
os.path.basename( base_fname + '.' + ext ) ) ): |
|
122 |
return os.path.basename( base_fname + '.' + ext ); |
|
123 |
||
124 |
# not found |
|
125 |
return False; |
|
126 |
||
127 |
def update_status( self, window ): |
|
128 |
thumb_view = window.get_thumb_view() |
|
129 |
||
130 |
# do we have just the one selected image? we can't handle multiple |
|
131 |
# images because EogThumbView.get_selected_images() doesn't work. |
|
132 |
self._action_group.set_sensitive( \ |
|
133 |
thumb_view.get_n_selected() == 1 ) |
|
134 |
||
135 |
# update the status bar |
|
136 |
if( thumb_view.get_n_selected() > 0 ): |
|
137 |
image = thumb_view.get_first_selected_image() |
|
138 |
raw_fname = self.get_raw_filename_from_image( image ) |
|
139 |
path = os.path.dirname( image.get_file().get_path() ) |
|
140 |
self._statusbar.pop( 0 ) |
|
141 |
if( raw_fname is False ): |
|
142 |
self._statusbar.push( 0, _( 'raw: -' ) ) |
|
143 |
elif( os.path.isfile( path + '/' + raw_fname ) ): |
|
144 |
self._statusbar.push( 0, _( 'raw: delete' ) ) |
|
145 |
else: |
|
146 |
self._statusbar.push( 0, _( 'raw: keep' ) ) |
|
147 |
||
148 |
def on_keep_raw_image( self, action ): |
|
149 |
||
150 |
# do we have just the one selected image? we can't handle multiple |
|
151 |
# images because EogThumbView.get_selected_images() doesn't work. |
|
152 |
thumb_view = self._window.get_thumb_view() |
|
153 |
if( thumb_view.get_n_selected() == 1 ): |
|
154 |
||
155 |
# get the image |
|
156 |
image = thumb_view.get_first_selected_image() |
|
157 |
if( image != None ): |
|
158 |
self.keep_raw_image( image ) |
|
159 |
||
160 |
# update ui |
|
161 |
self.update_status( self._window ) |
|
162 |
||
163 |
def keep_raw_image( self, image ): |
|
164 |
||
165 |
raw_fname = self.get_raw_filename_from_image( image ) |
|
166 |
if( raw_fname is False ): |
|
167 |
dialog = gtk.MessageDialog( None, gtk.DIALOG_MODAL, |
|
168 |
gtk.MESSAGE_INFO, gtk.BUTTONS_CLOSE, |
|
169 |
_( 'Raw file not found!' ) ) |
|
170 |
dialog.format_secondary_text( _( "This image doesn't appear to " + |
|
171 |
"have an accompanying raw file." ) ) |
|
1
by edam
initial comit |
172 |
dialog.run() |
173 |
dialog.destroy() |
|
174 |
return |
|
2
by edam
- added status bar information |
175 |
|
176 |
# does raw file exist? |
|
177 |
path = os.path.dirname( image.get_file().get_path() ) |
|
178 |
if( os.path.isfile( path + '/' + raw_fname ) ): |
|
179 |
||
180 |
# create the raw directory, if it doesn't exist |
|
181 |
if( not os.path.isdir( path + '/raw' ) ): |
|
182 |
os.mkdir( path + '/raw' ); |
|
183 |
||
184 |
# move the raw file in to the raw directory |
|
185 |
os.rename( path + '/' + raw_fname, path + '/raw/' + raw_fname ) |
|
186 |
||
187 |
def on_delete_raw_images( self, action ): |
|
188 |
||
189 |
# get path to first selected image, if there is one |
|
190 |
thumb_view = self._window.get_thumb_view() |
|
191 |
if( thumb_view.get_n_selected() == 1 ): |
|
192 |
image = thumb_view.get_first_selected_image() |
|
193 |
path = os.path.dirname( image.get_file().get_path() ) |
|
194 |
||
195 |
# build a regex that will match raw filenames |
|
196 |
regex = re.compile( |
|
197 |
'.*\.(' + '|'.join( self.raw_file_extensions ) + ')', re.I ) |
|
198 |
||
199 |
# itterate through files in the dir |
|
200 |
files = set() |
|
201 |
for file in os.listdir( path ): |
|
202 |
if( regex.match( file ) ): |
|
203 |
files.add( file ) |
|
204 |
||
205 |
# do we have any files to delete? |
|
206 |
if( len( files ) > 0 ): |
|
207 |
||
208 |
# ask the user if they are sure |
|
209 |
dialog = gtk.MessageDialog( None, gtk.DIALOG_MODAL, |
|
210 |
gtk.MESSAGE_QUESTION, gtk.BUTTONS_YES_NO, |
|
211 |
_( 'Delete Raw Files?' ) ) |
|
212 |
if( len( files ) == 1 ): |
|
213 |
subject = _( ' remaining raw file' ) |
|
214 |
else: |
|
215 |
subject = _( ' remaining raw files' ) |
|
216 |
dialog.format_secondary_text( |
|
217 |
_( 'You are about to delete the ' ) + |
|
218 |
str( len( files ) ) + subject + |
|
219 |
_( " that you haven't specifically asked to keep from " + |
|
220 |
"the directory that the current image is in.\n\n" + |
|
221 |
"Do you want to continue?" ) ) |
|
222 |
result = dialog.run() |
|
223 |
dialog.destroy() |
|
224 |
if( result != gtk.RESPONSE_YES ): |
|
225 |
return |
|
226 |
||
227 |
# delete the files |
|
228 |
for file in files: |
|
229 |
os.unlink( path + '/' + file ) |
|
230 |
||
231 |
self.update_status( self._window ) |
|
232 |
||
233 |
# else, tell the user there aren't any raw files! |
|
234 |
else: |
|
235 |
dialog = gtk.MessageDialog( None, gtk.DIALOG_MODAL, |
|
236 |
gtk.MESSAGE_INFO, gtk.BUTTONS_CLOSE, |
|
237 |
_( 'No raw files to delete!' ) ) |
|
238 |
dialog.format_secondary_text( |
|
239 |
_( 'There are no raw files to delete!' ) ) |
|
240 |
dialog.run() |
|
241 |
dialog.destroy() |