1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 from __future__ import with_statement
17 import os
18 import copy
19 import cStringIO
20 import time
21 import base64
22 import phone_media_codec
23 import wx
24 import guihelper
25 import aggregatedisplay
26 import pubsub
27 import common
28 import widgets
29 import guiwidgets
30 import shutil
31 import database
32 import helpids
33 import tempfile
34
35
36 basename=common.basename
37 stripext=common.stripext
38 getext=common.getext
51 mediaobjectfactory=database.dataobjectfactory(MediaDataObject)
55 _id_index=0
56 _max_id_index=999
58 self._data={ 'serials': [] }
59 self._create_id()
60
62 res=copy.deepcopy(self._data, None, {})
63
64 if res.has_key('mediadata'):
65 if res['mediadata'] is not None:
66 res['mediadata']=[{'data': buffer(res['mediadata']) }]
67 else:
68 del res['mediadata']
69 return res
71 self._data={}
72 self._data.update(d)
73
74 if d.get('mediadata', None) is not None:
75 self._data['mediadata']=str(d['mediadata'][0]['data'])
76
81
92 s=self._data.get('serials', [])
93 for n in s:
94 if n.get('sourcetype', None)=='bitpim':
95 return n.get('id', None)
96 return None
98 s=self._data.get('serials', [])
99 for n in s:
100 if n.get('sourcetype', None)=='bitpim':
101 n['id']=id
102 return
103 self._data['serials'].append({'sourcetype': 'bitpim', 'id': id } )
104 id=property(fget=_get_id, fset=_set_id)
105
107 if v is None or v in v_list:
108 if self._data.has_key(key):
109 del self._data[key]
110 else:
111 self._data[key]=v
112
114 return self._data.get('origin', '')
116 if v is None:
117 if self._data.has_key('origin'):
118 del self._data['origin']
119 return
120 if not isinstance(v, (str, unicode)):
121 raise TypeError,'not a string or unicode type'
122 self._data['origin']=v
123 origin=property(fget=_get_origin, fset=_set_origin)
124
126 return self._data.get('mediadata', None)
128 if v is not None:
129 self._set_or_del('mediadata', v, [])
130 mediadata=property(fget=_get_mediadata, fset=_set_mediadata)
131
133 return self._data.get('name', '')
136 name=property(fget=_get_name, fset=_set_name)
137
139 return self._data.get('index', -1)
142 index=property(fget=_get_index, fset=_set_index)
143
145 return self._data.get('timestamp', None)
147 if v is not None:
148 if not isinstance(v, (int, float)):
149 raise TypeError('timestamp property is an int arg')
150 v=int(v)
151 self._set_or_del('timestamp', v)
152 timestamp=property(fget=_get_timestamp, fset=_set_timestamp)
153
154 -def DrawTextWithLimit(dc, x, y, text, widthavailable, guardspace, term="..."):
155 """Draws text and if it will overflow the width available, truncates and puts ... at the end
156
157 @param x: start position for text
158 @param y: start position for text
159 @param text: the string to draw
160 @param widthavailable: the total amount of space available
161 @param guardspace: if the text is longer than widthavailable then this amount of space is
162 reclaimed from the right handside and term put there instead. Consequently
163 this value should be at least the width of term
164 @param term: the string that is placed in the guardspace if it gets truncated. Make sure guardspace
165 is at least the width of this string!
166 @returns: The extent of the text that was drawn in the end as a tuple of (width, height)
167 """
168 w,h=dc.GetTextExtent(text)
169 if w<widthavailable:
170 dc.DrawText(text,x,y)
171 return w,h
172 extents=dc.GetPartialTextExtents(text)
173 limit=widthavailable-guardspace
174
175 for i,offset in enumerate(extents):
176 if offset>limit:
177 break
178
179 if i:
180 i-=1
181 text=text[:i]+term
182 w,h=dc.GetTextExtent(text)
183 assert w<=widthavailable
184 dc.DrawText(text, x, y)
185 return w,h
186
187 media_codec=phone_media_codec.codec_name
189 - def __init__(self, target, drag_over=False, enter_leave=False):
190 wx.FileDropTarget.__init__(self)
191 self.target=target
192 self.drag_over=drag_over
193 self.enter_leave=enter_leave
194
197
199 if self.drag_over:
200 return self.target.OnDragOver(x,y,d)
201 return wx.FileDropTarget.OnDragOver(self, x, y, d)
202
204 if self.enter_leave:
205 return self.target.OnEnter(x,y,d)
206 return wx.FileDropTarget.OnEnter(self, x, y, d)
207
209 if self.enter_leave:
210 return self.target.OnLeave()
211 return wx.FileDropTarget.OnLeave(self)
212
213 -class FileView(wx.Panel, widgets.BitPimWidget):
214
215
216
217 item_selection_brush=None
218 item_selection_pen=None
219 item_line_font=None
220 item_term="..."
221 item_guardspace=None
222
223 skiplist= ( 'desktop.ini', 'thumbs.db', 'zbthumbnail.info' )
224 database_key=""
225
226
227 NONE=0
228 SELECTED=1
229 ALL=2
230
231
232 maxlen=-1
233
234 filenamechars=None
235
236 helpid=helpids.ID_TAB_MEDIA
237
238 - def __init__(self, mainwindow, parent, media_root, watermark=None):
239 wx.Panel.__init__(self,parent,style=wx.CLIP_CHILDREN)
240
241 self._fixupdb(mainwindow.database)
242
243 if self.item_selection_brush is None:
244 self.item_selection_brush=wx.TheBrushList.FindOrCreateBrush("MEDIUMPURPLE2", wx.SOLID)
245 self.item_selection_pen=wx.ThePenList.FindOrCreatePen("MEDIUMPURPLE2", 1, wx.SOLID)
246 f1=wx.TheFontList.FindOrCreateFont(10, wx.SWISS, wx.NORMAL, wx.BOLD)
247 f2=wx.TheFontList.FindOrCreateFont(10, wx.SWISS, wx.NORMAL, wx.NORMAL)
248 self.item_line_font=[f1, f2, f2, f2]
249 dc=wx.MemoryDC()
250 dc.SelectObject(wx.EmptyBitmap(100,100))
251 self.item_guardspace=dc.GetTextExtent(self.item_term)[0]
252 del dc
253
254
255
256
257 self.parent=parent
258 self.mainwindow=mainwindow
259 self.thedir=None
260 self.wildcard="I forgot to set wildcard in derived class|*"
261 self.__dragging=False
262 self._in_context_menu=False
263 self.media_root=media_root
264 self.show_thumbnail=True
265 self.active_section=""
266
267 self.excluded_origins=()
268
269
270 self.aggdisp=aggregatedisplay.Display(self, self, watermark)
271 self.vbs=wx.BoxSizer(wx.VERTICAL)
272
273
274 self.tb=wx.ToolBar(self, -1, style=wx.TB_3DBUTTONS|wx.TB_HORIZONTAL)
275 self.tb.SetToolBitmapSize(wx.Size(18,18))
276 sz=self.tb.GetToolBitmapSize()
277
278
279 self.tb.AddRadioLabelTool(guihelper.ID_FILEVIEW_THUMBNAIL, "Thumbnail",
280 wx.ArtProvider.GetBitmap(guihelper.ART_MEDIA_THUMB_VIEW, wx.ART_TOOLBAR, sz),
281 wx.ArtProvider.GetBitmap(guihelper.ART_MEDIA_THUMB_VIEW, wx.ART_TOOLBAR, sz),
282 "Show Thumbnails", "Show items as thumbnails")
283 self.tb.AddRadioLabelTool(guihelper.ID_FILEVIEW_LIST, "List",
284 wx.ArtProvider.GetBitmap(guihelper.ART_MEDIA_LIST_VIEW, wx.ART_TOOLBAR, sz),
285 wx.ArtProvider.GetBitmap(guihelper.ART_MEDIA_LIST_VIEW, wx.ART_TOOLBAR, sz),
286 "Show List", "Show items in a list")
287 self.vbs.Add(self.tb, 0, wx.EXPAND|wx.ALL, 1)
288 self.aggr_sizer=self.vbs.Add(self.aggdisp, 1, wx.EXPAND|wx.ALL, 2)
289
290
291 column_info=self.GetColumnNames()
292 self.item_list=guiwidgets.BitPimListCtrl(self, column_info)
293 self.nodes={}
294 self.nodes_keys={}
295 self.item_list.ResetView(self.nodes, self.nodes_keys)
296 self.item_sizer=self.vbs.Add(self.item_list, 1, wx.EXPAND|wx.ALL, 2)
297 self.item_sizer.Show(False)
298 self.note=self.vbs.Add(wx.StaticText(self, -1, ' Note: Click column headings to sort data'), 0, wx.ALIGN_CENTRE|wx.BOTTOM, 10)
299 self.note.Show(False)
300 self.SetSizer(self.vbs)
301 timerid=wx.NewId()
302 self.thetimer=wx.Timer(self, timerid)
303 wx.EVT_TIMER(self, timerid, self.OnTooltipTimer)
304 self.motionpos=None
305 wx.EVT_MOUSE_EVENTS(self.aggdisp, self.OnMouseEvent)
306 self.tipwindow=None
307 if True:
308
309 wx.EVT_MOTION(self.aggdisp, self.OnStartDrag)
310
311
312
313 self.itemmenu=wx.Menu()
314 self.itemmenu.Append(guihelper.ID_FV_OPEN, "Open")
315 self.itemmenu.Append(guihelper.ID_FV_SAVE, "Save ...")
316 self.itemmenu.AppendSeparator()
317 if guihelper.IsMSWindows():
318 self.itemmenu.Append(guihelper.ID_FV_COPY, "Copy")
319 self.itemmenu.Append(guihelper.ID_FV_DELETE, "Delete")
320 self.itemmenu.Append(guihelper.ID_FV_RENAME, "Rename")
321 self.movemenu=wx.Menu()
322 self.itemmenu.AppendMenu(guihelper.ID_FV_MOVE, "Move to", self.movemenu)
323 self.itemmenu.AppendSeparator()
324 self.itemmenu.Append(guihelper.ID_FV_REPLACE, "Replace")
325
326 self.itemmenu.Append(guihelper.ID_FV_REFRESH, "Refresh")
327
328 self.bgmenu=wx.Menu()
329 self.bgmenu.Append(guihelper.ID_FV_ADD, "Add ...")
330 self.bgmenu.Append(guihelper.ID_FV_PASTE, "Paste")
331 self.bgmenu.Append(guihelper.ID_FV_REFRESH, "Refresh")
332
333 wx.EVT_MENU(self.tb, guihelper.ID_FILEVIEW_THUMBNAIL, self.OnThumbnailView)
334 wx.EVT_MENU(self.tb, guihelper.ID_FILEVIEW_LIST, self.OnListView)
335
336
337 wx.EVT_MENU(self.itemmenu, guihelper.ID_FV_OPEN, self.OnLaunch)
338 wx.EVT_MENU(self.itemmenu, guihelper.ID_FV_SAVE, self.OnSave)
339 if guihelper.IsMSWindows():
340 wx.EVT_MENU(self.itemmenu, guihelper.ID_FV_COPY, self.OnCopy)
341 wx.EVT_MENU(self.itemmenu, guihelper.ID_FV_DELETE, self.OnDelete)
342 wx.EVT_MENU(self.itemmenu, guihelper.ID_FV_RENAME, self.OnRename)
343 wx.EVT_MENU(self.itemmenu, guihelper.ID_FV_REPLACE, self.OnReplace)
344 wx.EVT_MENU(self.itemmenu, guihelper.ID_FV_REFRESH, lambda evt: self.OnRefresh())
345 wx.EVT_MENU(self.bgmenu, guihelper.ID_FV_ADD, self.OnAdd)
346 wx.EVT_MENU(self.bgmenu, guihelper.ID_FV_PASTE, self.OnPaste)
347 wx.EVT_MENU(self.bgmenu, guihelper.ID_FV_REFRESH, lambda evt: self.OnRefresh)
348
349 wx.EVT_RIGHT_UP(self.aggdisp, self.OnRightClick)
350 wx.EVT_LIST_ITEM_RIGHT_CLICK(self.item_list, self.item_list.GetId(), self.OnRightClick)
351 aggregatedisplay.EVT_ACTIVATE(self.aggdisp, self.aggdisp.GetId(), self.OnLaunch)
352 wx.EVT_LIST_ITEM_ACTIVATED(self.item_list, self.item_list.GetId(), self.OnLaunch)
353
354 self.droptarget=MyFileDropTarget(self)
355 self.SetDropTarget(self.droptarget)
356 wx.EVT_SIZE(self, self.OnSize)
357 wx.EVT_IDLE(self, self.OnIdle)
358 wx.EVT_KEY_DOWN(self.aggdisp, self.OnKeyDown)
359 wx.EVT_KEY_UP(self.aggdisp, self.OnKeyUp)
360 self.tb.Realize()
361 pubsub.subscribe(self.OnMediaInfo, pubsub.REQUEST_MEDIA_INFO)
362 pubsub.subscribe(self.OnMediaOpen, pubsub.REQUEST_MEDIA_OPEN)
363
365 "Save out changed data"
366 if self.modified:
367 self.modified=False
368 self._populatefs(self._data)
369 self.OnListRequest()
370
372 if guihelper.IsGtk():
373 if evt.GetKeyCode()==wx.WXK_SHIFT:
374 self._shift_down=True
375 else:
376 self._shift_down=evt.ShiftDown()
377 evt.Skip()
378
380 if guihelper.IsGtk():
381 if evt.GetKeyCode()==wx.WXK_SHIFT:
382 self._shift_down=False
383 else:
384 self._shift_down=evt.ShiftDown()
385 evt.Skip()
386
388 self.thetimer.Stop()
389 self.show_thumbnail=True
390 self.item_sizer.Show(False)
391 self.note.Show(False)
392 self.aggr_sizer.Show(True)
393 self.aggdisp.SetFocus()
394 self.vbs.Layout()
395
397 self.thetimer.Stop()
398 self.show_thumbnail=False
399 self.aggr_sizer.Show(False)
400
401 self.aggdisp.SetSize((1,1))
402 self.item_sizer.Show(True)
403 self.item_list.SetFocus()
404 self.note.Show(True)
405 self.vbs.Layout()
406
412
414
415
416
417 self.media_root.widget_to_save=self
418 self.media_root.origin_to_save=self.active_section
419 result=[]
420 result.append((widgets.BitPimWidget.MENU_NORMAL, guihelper.ID_EDITADDENTRY, "Add to %s" % self.active_section, "Add a new media items"))
421 result.append((widgets.BitPimWidget.MENU_NORMAL, guihelper.ID_EDITDELETEENTRY, "Delete Selected", "Delete Selected Items"))
422 result.append((widgets.BitPimWidget.MENU_NORMAL, guihelper.ID_EDITSELECTALL, "Select All", "Select All Items"))
423 if guihelper.IsMSWindows():
424 result.append((widgets.BitPimWidget.MENU_NORMAL, guihelper.ID_EDITCOPY, "Copy", "Copy Selected Items"))
425 result.append((widgets.BitPimWidget.MENU_SPACER, 0, "", ""))
426 result.append((widgets.BitPimWidget.MENU_NORMAL, guihelper.ID_EXPORT_MEDIA_TO_DIR, "Export %s to Folder ..." % self.active_section, "Export the media to a folder on your hard drive"))
427 result.append((widgets.BitPimWidget.MENU_NORMAL, guihelper.ID_EXPORT_MEDIA_TO_ZIP, "Export %s to Zip File ..." % self.active_section, "Export the media to a zip file"))
428 return result
429
434
436
437 menuItems = self.movemenu.GetMenuItems()
438 for i, menuItem in enumerate(menuItems):
439 self.Unbind(wx.EVT_MENU, id=menuItem.GetId())
440 self.movemenu.DeleteItem(menuItem)
441
442
443 origins=self.media_root.GetNodeList(self)
444 origins.remove(self.active_section)
445 if len(origins):
446 for origin in origins:
447 mid=wx.NewId()
448 self.movemenu.Append(mid, origin)
449 wx.EVT_MENU(self, mid, self.OnMoveItem)
450
452 columns=[]
453 columns.append(("Name", 120, False))
454 columns.append(("Size/bytes", 80, True))
455 columns.append(("Date Modified", 120, False))
456 columns.append(("File Details", 380, False))
457 return columns
458
460
461 if self.thetimer.IsRunning():
462 self.thetimer.Stop()
463 evt.Skip()
464
489
506
520
521 @guihelper.BusyWrapper
524
525 if True:
526
528 evt.Skip()
529 if not evt.LeftIsDown():
530 return
531 items=self.GetSelectedItems()
532 if not len(items):
533 return
534 drag_source=wx.DropSource(self)
535 file_names=wx.FileDataObject()
536 for item in items:
537 me=self._data[self.database_key][item.key]
538 fname=self._gettempfile(me)
539 if not os.path.isfile(fname):
540 continue
541 file_names.AddFile(fname)
542 drag_source.SetData(file_names)
543 self.__dragging=True
544 res=drag_source.DoDragDrop(wx.Drag_AllowMove)
545 self.__dragging=False
546
547
548 for item in items:
549 me=self._data[self.database_key][item.key]
550 fname=self._gettempfile(me)
551 if not os.path.isfile(fname):
552 item.RemoveFromIndex()
553
555 self.motionpos=evt.GetPosition()
556
557
558 self.abs_mouse_pos=wx.GetMousePosition()
559 evt.Skip()
560 self.thetimer.Stop()
561 if evt.AltDown() or evt.MetaDown() or evt.ControlDown() or \
562 evt.ShiftDown() or evt.Dragging() or evt.IsButton() or \
563 self._in_context_menu or not self.show_thumbnail:
564 return
565 self.thetimer.Start(1750, wx.TIMER_ONE_SHOT)
566
581
587
589
590 self.nodes={}
591 self.nodes_keys={}
592 index=0
593 for k,e in self.sections:
594 if self.active_section==None or k.label==self.active_section:
595 for item in e:
596
597 dlist=item.long.splitlines()
598 d=""
599 for l in dlist:
600 if len(d):
601 d+=" - "
602 d+=l
603 self.nodes[index]=(item.name, str(item.size), item.timestamp, d)
604 self.nodes_keys[index]=item
605 index+=1
606 self.item_list.ResetView(self.nodes, self.nodes_keys)
607
609 if self.show_thumbnail:
610 return [item for _,_,_,item in self.aggdisp.GetSelection()]
611 res=[]
612 sel=self.item_list.GetSelections()
613 for sel_idx in sel:
614 res.append(self.item_list.GetItemData(sel[sel_idx]))
615 return res
616
618 return [item for _,_,_,item in self.aggdisp.GetAllItems()]
619
621 return self.item_list.GetItemCount() > 0
622
626
628
629
630
631
632
633 items=self.GetSelectedItems()
634 if len(items)==1:
635 ext=getext(items[0].name)
636 if ext=="": ext="*"
637 else: ext="*."+ext
638 with guihelper.WXDialogWrapper(wx.FileDialog(self, "Save item", wildcard=ext, defaultFile=items[0].name, style=wx.SAVE|wx.OVERWRITE_PROMPT|wx.CHANGE_DIR),
639 True) as (dlg, retcode):
640 if retcode==wx.ID_OK:
641 file(dlg.GetPath(), "wb").write(self._data[items[0].datakey][items[0].key].mediadata)
642 if self._data[items[0].datakey][items[0].key].timestamp!=None:
643 os.utime(dlg.GetPath(), (self._data[items[0].datakey][items[0].key].timestamp,
644 self._data[items[0].datakey][items[0].key].timestamp))
645 else:
646 with guihelper.WXDialogWrapper(wx.DirDialog(self, "Save items to", style=wx.DD_DEFAULT_STYLE|wx.DD_NEW_DIR_BUTTON),
647 True) as (dlg, retcode):
648 if retcode==wx.ID_OK:
649 for item in items:
650 fname=item.name.encode(media_codec)
651 fname=os.path.join(dlg.GetPath(), basename(fname))
652 file(fname, 'wb').write(self._data[item.datakey][item.key].mediadata)
653 if self._data[item.datakey][item.key].timestamp!=None:
654 os.utime(fname, (self._data[item.datakey][item.key].timestamp,
655 self._data[item.datakey][item.key].timestamp))
656
657 if guihelper.IsMSWindows():
675
676 if guihelper.IsGtk():
677
679 if not wx.TheClipboard.Open():
680
681 return
682 if wx.TheClipboard.IsSupported(wx.DataFormat(wx.DF_UNICODETEXT)):
683 file_names=wx.TextDataObject()
684 has_data=wx.TheClipboard.GetData(file_names)
685 else:
686 has_data=False
687 wx.TheClipboard.Close()
688 if has_data:
689
690 _names=[x for x in file_names.GetText().split('\n') \
691 if os.path.isfile(x) ]
692 if _names:
693 self.OnAddFiles(_names)
695 """ Return True if can accept clipboard data, False otherwise
696 """
697 if not wx.TheClipboard.Open():
698 return False
699 r=wx.TheClipboard.IsSupported(wx.DataFormat(wx.DF_UNICODETEXT))
700 if r:
701 file_names=wx.TextDataObject()
702 r=wx.TheClipboard.GetData(file_names)
703 if r:
704 for _name in file_names.GetText().split('\n'):
705 if not os.path.isfile(_name):
706 r=False
707 break
708 wx.TheClipboard.Close()
709 return r
710 else:
712 if not wx.TheClipboard.Open():
713
714 return
715 if wx.TheClipboard.IsSupported(wx.DataFormat(wx.DF_FILENAME)):
716 file_names=wx.FileDataObject()
717 has_data=wx.TheClipboard.GetData(file_names)
718 else:
719 has_data=False
720 wx.TheClipboard.Close()
721 if has_data:
722 self.OnAddFiles(file_names.GetFilenames())
723
725 """ Return True if can accept clipboard data, False otherwise
726 """
727 if not wx.TheClipboard.Open():
728 return False
729 r=wx.TheClipboard.IsSupported(wx.DataFormat(wx.DF_FILENAME))
730 wx.TheClipboard.Close()
731 return r
732
737
743
744 - def AddToIndex(self, file, origin, data, dict, timestamp=None, index=-1):
773
775
776 adjustflg=False
777 for _,_name,_type in db.getcolumns(self.database_key):
778 if _name=='mediadata' and _type!='indirectBLOB':
779
780 adjustflg=True
781 break
782
783 if adjustflg:
784 db._altertable(self.database_key, [('mediadata', 'indirectBLOB')],
785 ['mediadata'], 1)
786
794
796
797 if hasattr(item, 'origin'):
798 _origin=item.origin
799 _name=item.name
800 else:
801 _origin=item.get('origin', '')
802 _name=item.get('name', '')
803 relative_name=os.path.join(_origin,
804 _name.encode(media_codec))
805 return os.path.join(self.mainwindow.blob_path, relative_name)
806
816
837
862
879
896
901
905
932
948
950 dict={}
951 index_found=False
952 if os.path.isdir(self.thedir):
953 for file in os.listdir(self.thedir):
954 if file=='index.idx':
955 d={}
956 d['result']={}
957 common.readversionedindexfile(os.path.join(self.thedir, file), d, self.versionupgrade, currentversion)
958 result.update(d['result'])
959 index_found=True
960 elif file.lower() in self.skiplist:
961
962 continue
963 elif key is not None:
964 dict[file.decode(media_codec)]=open(os.path.join(self.thedir, file), "rb").read()
965 if index_found:
966 if key is not None:
967 result[key]=dict
968 if indexkey not in result:
969 result[indexkey]={}
970 return result
971
975
990
993
994 - def OnAdd(self, _=None):
995 with guihelper.WXDialogWrapper(wx.FileDialog(self, "Choose files", style=wx.OPEN|wx.MULTIPLE, wildcard=self.wildcard),
996 True) as (dlg, retcode):
997 if retcode==wx.ID_OK:
998 self.OnAddFiles(dlg.GetPaths())
999
1002
1003 media_notification_type=None
1022
1024 raise NotImplementedError
1025
1037
1059
1101
1103 s1=a.name.lower()
1104 s2=b.name.lower()
1105 if s1<s2:
1106 return -1
1107 if s1==s2:
1108 return 0
1109 return 1
1110
1111 - def log(self, log_str):
1112 self.mainwindow.log(log_str)
1113
1116
1134
1136
1137 datakey="Someone forgot to set me"
1138 PADDING=3
1139
1141 self.view=view
1142 self.key=key
1143 self.thumbsize=10,10
1144 self.setvals()
1145 self.lastw=None
1146
1176
1177 - def Draw(self, dc, width, height, selected):
1178 if self.thumb==None:
1179 try:
1180 if self.size:
1181 me=self.view._data[self.datakey][self.key]
1182 self.thumb=self.view.GetItemThumbnail(me.mediadata, self.thumbnailsize[0], self.thumbnailsize[1], self.fileinfo)
1183 else:
1184 self.thumb=self.view.GetItemThumbnail(None, self.thumbnailsize[0], self.thumbnailsize[1])
1185 except:
1186 self.thumb=self.view.GetItemThumbnail(None, self.thumbnailsize[0], self.thumbnailsize[1])
1187 redrawbbox=False
1188 if selected:
1189 if self.lastw!=width or self.selbbox is None:
1190 redrawbbox=True
1191 else:
1192 oldb=dc.GetBrush()
1193 oldp=dc.GetPen()
1194 dc.SetBrush(self.view.item_selection_brush)
1195 dc.SetPen(self.view.item_selection_pen)
1196 dc.DrawRectangle(*self.selbbox)
1197 dc.SetBrush(oldb)
1198 dc.SetPen(oldp)
1199 dc.DrawBitmap(self.thumb, self.PADDING+self.thumbnailsize[0]/2-self.thumb.GetWidth()/2, self.PADDING, True)
1200 xoff=self.PADDING+self.thumbnailsize[0]+self.PADDING
1201 yoff=self.PADDING*2
1202 widthavailable=width-xoff-self.PADDING
1203 maxw=0
1204 old=dc.GetFont()
1205 for i,line in enumerate(self.lines):
1206 dc.SetFont(self.view.item_line_font[i])
1207 w,h=DrawTextWithLimit(dc, xoff, yoff, line, widthavailable, self.view.item_guardspace, self.view.item_term)
1208 maxw=max(maxw,w)
1209 yoff+=h
1210 dc.SetFont(old)
1211 self.lastw=width
1212 self.selbbox=(0,0,xoff+maxw+self.PADDING,max(yoff+self.PADDING,self.thumb.GetHeight()+self.PADDING*2))
1213 if redrawbbox:
1214 return self.Draw(dc, width, height, selected)
1215 return self.selbbox
1216
1223
1225 del self.view._data[self.datakey][self.key]
1226 self.view.modified=True
1227 self.view.OnRefresh()
1228
1230 self.view._data[self.datakey][self.key].name=new_name
1231 self.view.modified=True
1232 self.view.OnRefresh()
1233
1235 self.view._data[self.datakey][self.key].origin=new_origin
1236 self.view._data[self.datakey][self.key].index=-1
1237 self.view.modified=True
1238 self.view.OnRefresh()
1239
1244