1
# Copyright (C) 2007-2008 www.stani.be
3
# This program is free software: you can redistribute it and/or modify
4
# it under the terms of the GNU General Public License as published by
5
# the Free Software Foundation, either version 3 of the License, or
6
# (at your option) any later version.
8
# This program is distributed in the hope that it will be useful,
9
# but WITHOUT ANY WARRANTY; without even the implied warranty of
10
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11
# GNU General Public License for more details.
13
# You should have received a copy of the GNU General Public License
14
# along with this program. If not, see http://www.gnu.org/licenses/
18
if __name__ == '__main__':
19
sys.path.extend(['../..','../../core/lib'])
23
import wx.grid as gridlib
25
import droplet, inspectorTag
26
from formField import IMAGE_READ_EXTENSIONS, is_file
27
from wildcard import wildcard_list
28
from clipboard import copy_text
29
from graphics import bitmap_open
30
from core.pil import extract_info, pyexiv2, DOT, image_open
33
TAGS = ['Select','All','Pil']
35
TAGS.extend(['Exif','Iptc'])
36
TAGS.extend(['Pexif','Zexif'])
41
def extract_data(filename,info):
43
extract_info(info,image_open(filename),filename)
44
return [(shortcut(key),'<%s>'%key,value) for key, value in info.items()]
46
class Grid(droplet.Mixin,inspectorTag.Grid):
48
wildcard_list(_('Images'),IMAGE_READ_EXTENSIONS),_('All files'),'*'])
50
super(Grid,self)._init()
52
self.SetAsFileDropTarget(self,self.OnDrop)
53
self.SetAsFileDropTarget(self.GetEmpty(),self.OnDrop)
54
self.SetAsFileDropTarget(self.GetDialog(),self.OnDrop)
55
self.Bind(wx.EVT_KEY_DOWN, self.OnKeyDown)
57
def OnKeyDown(self,event):
58
if event.ControlDown() and event.GetKeyCode() == 67:
63
def show_message(self,message,title='',style=wx.OK | wx.ICON_EXCLAMATION):
64
dlg = wx.MessageDialog(self,
69
answer = dlg.ShowModal()
74
def OnDrop(self,filenames,x,y):
79
self.show_message(_('Only an image file is allowed.'))
80
#path = ct.PATH_DELIMITER.join(filenames)
82
def SetTag(self,tag,autosize=True):
83
super(Grid,self).SetTag(tag)
85
self.tag_data = self.all_data
86
elif tag == _('Select'):
87
self.tag_data = [row for row in self.all_data\
88
if not(DOT in row[1])]
92
self.tag_data = [row for row in self.all_data if row[1][:n]==tag]
95
def SetFilter(self,filter=None):
97
filter = self.GetFilter().GetValue()
99
self.data = [row for row in self.tag_data
100
if filter.lower() in str(row).lower()]
102
self.data = self.tag_data
104
if not self.CheckEmpty():
107
def OpenImage(self,filename):
109
self.filename = filename
110
self.SetData(extract_data(filename,self.info),_('Select'))
112
def OnCopy(self,event=None):
115
self.data[self.GetGridCursorRow()][self.GetGridCursorCol()]))
117
class SingleGrid(Grid):
118
def OnOpen(self,event):
119
style = wx.OPEN | wx.CHANGE_DIR
120
if hasattr(wx,'FD_PREVIEW'):
121
style |= wx.FD_PREVIEW
122
dlg = wx.FileDialog(self, _("Choose an image"),
123
defaultDir = os.path.dirname(self.filename),
124
wildcard = self.wildcard,
127
if dlg.ShowModal() == wx.ID_OK:
128
self.OpenImage(dlg.GetPath())
131
def OnOpenUrl(self,event):
132
dlg = wx.TextEntryDialog(self, _("Enter an image url"))
133
if dlg.ShowModal() == wx.ID_OK:
134
self.OpenImage(dlg.GetValue())
137
def OpenImage(self,filename):
138
super(SingleGrid,self).OpenImage(filename)
139
self.GetDialog()._OpenImage(filename)
141
def SetFilter(self,filter=None):
142
super(SingleGrid,self).SetFilter(filter)
143
dlg = self.GetDialog().EnableImage(bool(self.data))
146
return wx.GetTopLevelParent(self)
148
class Browser(inspectorTag.Browser):
152
self.GetContent().SetTag(_('Select'))
154
def GetPaintMessage(self):
155
content = self.GetContent()
157
return _('drag & drop any image here')
159
return _('broaden your search')
160
tag = self.tag.GetStringSelection().lower()
161
if tag == 'Exif' and not pyexiv2:
162
return _('please install pyexiv2')
163
return _('no %s tags found')%tag
165
class SingleBrowser(Browser):
166
ContentCtrl = SingleGrid
168
class SingleFrame(inspectorTag.Frame):
169
Browser = SingleBrowser
170
def __init__(self,parent,filename='',*args,**keyw):
171
super(SingleFrame,self).__init__(parent,[],TAGS, *args,**keyw)
172
if not os.path.isfile(filename):filename = ''
173
self.GetGrid().OpenImage(filename)
174
self.filename = ''#forces refresh of thumb
176
def _OpenImage(self,filename):
177
"""To be called from the grid."""
179
di, ba = os.path.split(filename)
180
self.SetTitle('%s %s'%(ba,di))
182
self.SetTitle(_('Image Inspector'))
183
if self.thumb.IsShown():
187
self.thumb_height = 128
188
size = (self.thumb_height,self.thumb_height)
189
bmp = wx.ArtProvider_GetBitmap(wx.ART_MISSING_IMAGE,
190
wx.ART_OTHER,size=size)
191
self.thumb = wx.StaticBitmap(self, -1, bmp, size=size)
193
grid = self.GetGrid()
194
grid.SetAsFileDropTarget(self.thumb,grid.OnDrop)
197
def _layout_top(self,main_sizer):
199
main_sizer.Add(self.thumb, 0, wx.LEFT|wx.TOP, 8)
201
def _layout_buttons(self,btn_sizer):
202
self.preview = wx.CheckBox(self, -1, _("&Preview"))
203
self.preview.Disable()
204
self.open = self.CreateBitmapButton(wx.ART_FOLDER_OPEN,
205
_("Open image file"))
206
self.open_url = self.CreateBitmapButton(wx.ART_GO_HOME,
208
self.copy = self.CreateBitmapButton(wx.ART_COPY,
211
btn_sizer.Add(self.preview, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 4)
212
btn_sizer.Add(self.open, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 4)
213
btn_sizer.Add(self.open_url, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 4)
214
btn_sizer.Add(self.copy, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 4)
215
super(SingleFrame,self)._layout_buttons(btn_sizer)
218
super(SingleFrame,self)._events()
219
grid = self.GetGrid()
220
self.open.Bind(wx.EVT_BUTTON,grid.OnOpen)
221
self.open_url.Bind(wx.EVT_BUTTON,grid.OnOpenUrl)
222
self.copy.Bind(wx.EVT_BUTTON,grid.OnCopy)
223
self.preview.Bind(wx.EVT_CHECKBOX,self.OnPreview)
225
def OnPreview(self,event):
226
state = event.IsChecked()
227
self.thumb.Show(state)
228
if state: self.UpdateThumb()
231
def UpdateThumb(self):
232
grid = self.GetGrid()
233
if self.filename != grid.filename:
234
self.filename = grid.filename
236
bmp = bitmap_open(grid.filename,self.thumb_height)
237
self.thumb.SetBitmap(bmp)
238
size = (bmp.GetWidth(),bmp.GetHeight())
239
self.thumb.SetSize(size)
240
self.thumb.SetMinSize(size)
243
def EnableImage(self,state):
244
if not hasattr(self,'copy'): return
245
for ctrl in [self.copy,self.preview]:
248
if __name__ == '__main__':
249
app = wx.PySimpleApp()
253
#'/home/stani/sync/photos/20070118-verhuis/IMG_1077.JPG',