/gtk/eog-manage-raws

To get this branch, use:
bzr branch http://bzr.ed.am/gtk/eog-manage-raws

« back to all changes in this revision

Viewing changes to src/manage-raws.py

  • Committer: edam
  • Date: 2012-01-22 01:26:39 UTC
  • Revision ID: edam@waxworlds.org-20120122012639-hluj34f6th75s040
Tags: 0.1
refer to raw files as files, not images

Show diffs side-by-side

added added

removed removed

1
 
import eog, gtk, os, re
2
 
 
3
 
class HelloWorldPlugin(eog.Plugin):
4
 
 
 
1
# manage-raws.py
 
2
#
 
3
# Copyright (C) 2011 Tim Marston <edam@waxworlds.org>
 
4
#
 
5
# This file is part of Manage Raws (hereafter referred to as "this
 
6
# program").  See http://ed.am/dev/gtk/eog-manage-raws for more
 
7
# information.
 
8
#
 
9
# This program is free software: you can redistribute it and/or modify
 
10
# it under the terms of the GNU General Public License as published by
 
11
# the Free Software Foundation, either version 3 of the License, or
 
12
# (at your option) any later version.
 
13
#
 
14
# This program is distributed in the hope that it will be useful,
 
15
# but WITHOUT ANY WARRANTY; without even the implied warranty of
 
16
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
17
# GNU General Public License for more details.
 
18
#
 
19
# You should have received a copy of the GNU General Public License
 
20
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
21
 
 
22
 
 
23
# version 0.1
 
24
 
 
25
from gi.repository import GObject, Gtk, Eog, Gio
 
26
import os, re
 
27
 
 
28
class ManageRawsPlugin( GObject.Object, Eog.WindowActivatable ):
 
29
 
 
30
    # Override EogWindowActivatable's window property
 
31
    window = GObject.property( type = Eog.Window )
 
32
 
 
33
    # list of file extension to recognise as RAW files
5
34
    raw_file_extensions = [ 'cr2', '3fr', 'ari', 'arw', 'srf', 'sr2', 'bay',
6
35
        'crw', 'cr2', 'cap', 'iiq', 'eip', 'dcs', 'dcr', 'drf', 'k25', 'kdc',
7
36
        'dng', 'erf', 'fff', 'mef', 'mos', 'mrw', 'nef', 'nrw', 'orf', 'ptx',
8
37
        'pef', 'pxn', 'r3d', 'raf', 'raw', 'rw2', 'rwl', 'rwz', 'x3f' ]
9
38
 
10
39
    def __init__( self ):
11
 
        eog.Plugin.__init__( self )
 
40
        GObject.Object.__init__( self )
12
41
 
13
 
    def activate( self, window ):
14
 
        self._window = window
 
42
    def do_activate( self ):
15
43
 
16
44
        # insert menu item
17
 
        manager = window.get_ui_manager()
18
 
        self._action_group = gtk.ActionGroup( 'EogRawToolsPluginActions' )
19
 
        self._action_group.add_actions( [ ( 'EogPluginRunKeepRaw', None,
20
 
            _( 'Keep Raw Image' ), 'K',
 
45
        ui_manager = self.window.get_ui_manager()
 
46
        self.action_group = Gtk.ActionGroup( 'EogManageRawsPluginActions' )
 
47
        self.action_group.add_actions( [ ( 'EogPluginRunKeepRaw', None,
 
48
            _( 'Keep Raw File' ), 'K',
21
49
            _( "Move the accompanying raw file to a 'raw' subdirectory" ),
22
 
            self.on_keep_raw_image ) ] )
23
 
        self._action_group.add_actions( [ ( 'EogPluginRunDeleteRaw', None,
24
 
            _( 'Delete Unkept Raw Images' ), None,
 
50
            self.do_keep_raw_file ) ], self.window )
 
51
        self.action_group.add_actions( [ ( 'EogPluginRunUnkeepRaw', None,
 
52
            _( 'Unkeep Raw File' ), 'U',
 
53
            _( "Move the accompanying raw file back to the image's directory" ),
 
54
            self.do_unkeep_raw_file ) ], self.window )
 
55
        self.action_group.add_actions( [ ( 'EogPluginRunDeleteRaw', None,
 
56
            _( 'Delete Unkept Raw Files' ), None,
25
57
            _( "Delete all raw files in the current image's directory (the unkept ones)" ),
26
 
            self.on_delete_raw_images ) ] )
27
 
        manager.insert_action_group( self._action_group, -1 )
28
 
        self._ui_id = manager.add_ui_from_string( """
 
58
            self.do_delete_raw_files ) ], self.window )
 
59
        ui_manager.insert_action_group( self.action_group, -1 )
 
60
        self.ui_id = ui_manager.add_ui_from_string( """
29
61
            <ui>
30
62
                <menubar name="MainMenu">
31
63
                    <menu name="ToolsMenu" action="Tools">
32
64
                        <separator />
33
65
                        <menuitem name="EogPluginRunKeepRaw"
34
66
                            action="EogPluginRunKeepRaw" />
 
67
                        <menuitem name="EogPluginRunUnkeepRaw"
 
68
                            action="EogPluginRunUnkeepRaw" />
35
69
                        <menuitem name="EogPluginRunDeleteRaw"
36
70
                            action="EogPluginRunDeleteRaw" />
37
71
                        <separator />
46
80
        """ )
47
81
 
48
82
        # 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()
 
83
        self.statusbar = Gtk.Statusbar()
 
84
        #self.statusbar.set_size_request( 100, 10 )
 
85
        statusbar = self.window.get_statusbar()
 
86
        statusbar.pack_end( self.statusbar, False, False, 0 );
 
87
        self.statusbar.show()
55
88
 
56
89
        # connect to selection change
57
 
        thumb_view = window.get_thumb_view()
58
 
        self._on_selection_change_id = thumb_view.connect_after( \
59
 
            'selection_changed', self.on_selection_change, window )
 
90
        thumb_view = self.window.get_thumb_view()
 
91
        self.on_selection_change_id = thumb_view.connect_after( \
 
92
            'selection_changed', self.on_selection_change, self.window )
60
93
 
61
94
        # init ui state
62
 
        self.update_status( window )
63
 
 
64
 
    def deactivate( self, window ):
 
95
        self.update_status( self.window )
 
96
 
 
97
    def do_deactivate( self ):
 
98
 
 
99
        # remove menu items
 
100
        ui_manager = self.window.get_ui_manager()
 
101
        ui_manager.remove_ui( self.ui_id )
 
102
        self.ui_id = 0
 
103
        ui_manager.remove_action_group( self.action_group )
 
104
        self.action_group = None
 
105
        ui_manager.ensure_update()
65
106
 
66
107
        # disconnect handlers
67
 
        thumb_view = window.get_thumb_view()
68
 
        thumb_view.disconnect( self._on_selection_change_id )
69
 
 
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()
 
108
        thumb_view = self.window.get_thumb_view()
 
109
        thumb_view.disconnect( self.on_selection_change_id )
75
110
 
76
111
        # remove status bar entry
77
 
        statusbar = window.get_statusbar()
78
 
        statusbar.remove( self._statusbar )
 
112
        statusbar =  self.window.get_statusbar()
 
113
        Gtk.Container.remove( statusbar, self.statusbar )
79
114
 
80
115
    def on_selection_change( self, view, data ):
81
116
        self.update_status( data )
109
144
            if( os.path.isfile( base_fname + '.' + ext ) ):
110
145
                return os.path.basename( base_fname + '.' + ext );
111
146
 
112
 
        # path the raw images will be moved to
 
147
        # path the raw files will be moved to
113
148
        raw_path = os.path.dirname( fname ) + '/raw';
114
149
 
115
150
        # loop through valid raw file extensions, uppercase and lowercase
129
164
 
130
165
        # do we have just the one selected image? we can't handle multiple
131
166
        # images because EogThumbView.get_selected_images() doesn't work.
132
 
        self._action_group.set_sensitive( \
 
167
        self.action_group.set_sensitive( \
133
168
            thumb_view.get_n_selected() == 1 )
134
169
 
135
170
        # update the status bar
137
172
            image = thumb_view.get_first_selected_image()
138
173
            raw_fname = self.get_raw_filename_from_image( image )
139
174
            path = os.path.dirname( image.get_file().get_path() )
140
 
            self._statusbar.pop( 0 )
 
175
            self.statusbar.pop( 0 )
141
176
            if( raw_fname is False ):
142
 
                self._statusbar.push( 0, _( 'raw: -' ) )
 
177
                self.statusbar.push( 0, "  " + _( 'raw: -' ) )
143
178
            elif( os.path.isfile( path + '/' + raw_fname ) ):
144
 
                self._statusbar.push( 0, _( 'raw: delete' ) )
 
179
                self.statusbar.push( 0, "  " + _( 'raw: unkept' ) )
145
180
            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 ):
 
181
                self.statusbar.push( 0, "  " + _( 'raw: keep' ) )
 
182
 
 
183
    def do_keep_raw_file( self, action, window ):
 
184
 
 
185
        # do we have just the one selected image? we can't handle multiple
 
186
        # images because EogThumbView.get_selected_images() doesn't work.
 
187
        thumb_view = window.get_thumb_view()
 
188
        if( thumb_view.get_n_selected() == 1 ):
 
189
 
 
190
            # get the image
 
191
            image = thumb_view.get_first_selected_image()
 
192
            if( image != None ):
 
193
                self.keep_raw_file( image )
 
194
 
 
195
            # update ui
 
196
            self.update_status( window )
 
197
 
 
198
    def do_unkeep_raw_file( self, action, window ):
 
199
 
 
200
        # do we have just the one selected image? we can't handle multiple
 
201
        # images because EogThumbView.get_selected_images() doesn't work.
 
202
        thumb_view = window.get_thumb_view()
 
203
        if( thumb_view.get_n_selected() == 1 ):
 
204
 
 
205
            # get the image
 
206
            image = thumb_view.get_first_selected_image()
 
207
            if( image != None ):
 
208
                self.unkeep_raw_file( image )
 
209
 
 
210
            # update ui
 
211
            self.update_status( window )
 
212
 
 
213
    def keep_raw_file( self, image ):
164
214
 
165
215
        raw_fname = self.get_raw_filename_from_image( image )
166
216
        if( raw_fname is False ):
167
 
            dialog = gtk.MessageDialog( None, gtk.DIALOG_MODAL,
168
 
                gtk.MESSAGE_INFO, gtk.BUTTONS_CLOSE,
 
217
            dialog = Gtk.MessageDialog( None, Gtk.DialogFlags.MODAL,
 
218
                Gtk.MessageType.INFO, Gtk.ButtonsType.CLOSE,
169
219
                _( 'Raw file not found!' ) )
170
220
            dialog.format_secondary_text( _( "This image doesn't appear to " +
171
221
                "have an accompanying raw file." ) )
184
234
            # move the raw file in to the raw directory
185
235
            os.rename( path + '/' + raw_fname, path + '/raw/' + raw_fname )
186
236
 
187
 
    def on_delete_raw_images( self, action ):
 
237
    def unkeep_raw_file( self, image ):
 
238
 
 
239
        raw_fname = self.get_raw_filename_from_image( image )
 
240
        if( raw_fname is False ):
 
241
            dialog = Gtk.MessageDialog( None, Gtk.DialogFlags.MODAL,
 
242
                Gtk.MessageType.INFO, Gtk.ButtonsType.CLOSE,
 
243
                _( 'Raw file not found!' ) )
 
244
            dialog.format_secondary_text( _( "This image doesn't appear to " +
 
245
                "have an accompanying raw file." ) )
 
246
            dialog.run()
 
247
            dialog.destroy()
 
248
            return
 
249
 
 
250
        # does raw file exist?
 
251
        path = os.path.dirname( image.get_file().get_path() )
 
252
        if( os.path.isfile( path + '/raw/' + raw_fname ) ):
 
253
 
 
254
            # move the raw file back to the parent directory
 
255
            os.rename( path + '/raw/' + raw_fname, path + '/' + raw_fname )
 
256
 
 
257
            # if the raw directory is empty, remove it
 
258
            if( len( os.listdir( path + '/raw' ) ) == 0 ):
 
259
                os.rmdir( path + '/raw' )
 
260
 
 
261
    def do_delete_raw_files( self, action, window ):
188
262
 
189
263
        # get path to first selected image, if there is one
190
 
        thumb_view = self._window.get_thumb_view()
 
264
        thumb_view = window.get_thumb_view()
191
265
        if( thumb_view.get_n_selected() == 1 ):
192
266
            image = thumb_view.get_first_selected_image()
193
267
            path = os.path.dirname( image.get_file().get_path() )
206
280
            if( len( files ) > 0 ):
207
281
 
208
282
                # ask the user if they are sure
209
 
                dialog = gtk.MessageDialog( None, gtk.DIALOG_MODAL,
210
 
                    gtk.MESSAGE_QUESTION, gtk.BUTTONS_YES_NO,
 
283
                dialog = Gtk.MessageDialog( None, Gtk.DialogFlags.MODAL,
 
284
                    Gtk.MessageType.QUESTION, Gtk.ButtonsType.YES_NO,
211
285
                    _( 'Delete Raw Files?' ) )
212
286
                if( len( files ) == 1 ):
213
287
                    subject = _( ' remaining raw file' )
221
295
                        "Do you want to continue?" ) )
222
296
                result = dialog.run()
223
297
                dialog.destroy()
224
 
                if( result != gtk.RESPONSE_YES ):
 
298
                if( result != Gtk.ResponseType.YES ):
225
299
                    return
226
300
 
227
301
                # delete the files
228
302
                for file in files:
229
 
                    os.unlink( path + '/' + file )
 
303
                    Gio.file_parse_name( path + '/' + file ).trash( None )
 
304
                    #os.unlink( path + '/' + file )
230
305
 
231
 
                self.update_status( self._window )
 
306
                self.update_status( window )
232
307
        
233
308
            # else, tell the user there aren't any raw files!
234
309
            else:
235
 
                dialog = gtk.MessageDialog( None, gtk.DIALOG_MODAL,
236
 
                    gtk.MESSAGE_INFO, gtk.BUTTONS_CLOSE,
 
310
                dialog = Gtk.MessageDialog( None, Gtk.DialogFlags.MODAL,
 
311
                    Gtk.MessageType.INFO, Gtk.ButtonsType.CLOSE,
237
312
                    _( 'No raw files to delete!' ) )
238
313
                dialog.format_secondary_text(
239
314
                    _( 'There are no raw files to delete!' ) )