import os
import sys,time
try:
import subprocess
except ImportError:
print "jbrout need python2.4 or +"
sys.exit()
try:
os.chdir(os.path.split(sys.argv[0])[0])
except:
pass
import pygtk
pygtk.require('2.0')
import gtk
import locale
from libs.gladeapp import GladeApp
from libs.i18n import createGetText
GladeApp.bindtextdomain("jbrout",os.path.join(os.path.dirname(__file__), 'po'))
__builtins__.__dict__["_"] = createGetText("jbrout",os.path.join(os.path.dirname(__file__), 'po'))
import gobject
try:
__version__ = open("version.txt").read().strip()
except:
__version__ = "svn"
from common import cd2rd,cd2d,format_file_size_for_display,runWith,openURL from commongtk import AlbumCommenter,InputBox,MessageBox,InputQuestion,Img,WinKeyTag
from db import JBrout,Buffer
from winsearch import Winsearch
from winshow import WinShow
from listview2 import ThumbnailsView
from externaltools import ExternalTools
import tempfile,shutil
import urllib,time,datetime,sys
import traceback, string, optparse
def myExceptHook(type, value, tb):
sys.__excepthook__(type, value, tb)
lines = traceback.format_exception(type, value, tb)
MessageBox(None,string.join(lines),title=_("Jbrout Error"))
def beep(m):
print >>sys.stdout,m
def colorToString(color):
"""
Converts a gtk.gdk color to a string
(fix for windows not having the to_string member function)"""
return "#%x%x%x" %(color.red, color.blue, color.green)
class JStyle:
""" static class to handle jbrout colors """
w = gtk.Window() w.realize() style=w.get_style() del(w)
TEXT= colorToString(style.text[gtk.STATE_NORMAL])
TEXT_LOLIGHT = colorToString(style.fg[gtk.STATE_INSENSITIVE])
TEXT_HILIGHT = "#FF0000"
BACKGROUND = colorToString(style.base[gtk.STATE_NORMAL])
class JPlugin:
class PlugConf:
def __init__(self,myConf,myName):
self.__conf = myConf
self.__name = myName
def __setitem__(self,n,v):
self.__conf[self.__name+"."+n] = v
def __getitem__(self,n):
return self.__conf[self.__name+"."+n]
def __init__(self,id,path):
self.id=id
self.path=path
self.conf = JPlugin.PlugConf(JBrout.conf,id)
def MessageBox(self,m,title=None):
MessageBox(JPlugin.parent.main_widget,m,title)
def InputBox(self,t,m,title=None):
return InputBox(JPlugin.parent.main_widget,t,m,title)
def InputQuestion(self,m,title=None):
return InputQuestion(JPlugin.parent.main_widget,m,title)
def openURL(self,url):
return openURL(url)
def showProgress(self,c=None,m=None,msg=None):
JPlugin.parent.showProgress(c,m,msg)
def getGeneralConfItem(self,n):
"""Permit to read General JBrout configuration parameter 'n' """
return self.__conf[n]
class ListView(ThumbnailsView):
choix = [_("Tags"),_("Comment"),_("Album"),_("Date"),_("Name")]
def __init__(self, pere,allow_dragndrop):
ThumbnailsView.__init__(self)
self.parentWin = pere
self.connect('key-press-event', self.on_key_press_for_tag)
if allow_dragndrop:
self.drag_source_set(gtk.gdk.BUTTON1_MASK | gtk.gdk.BUTTON2_MASK,
[('to_albums', 0, 111),], gtk.gdk.ACTION_COPY | gtk.gdk.ACTION_MOVE)
self.drag_dest_set(gtk.DEST_DEFAULT_ALL, [('from_tags', 0, 111),('from_ftags', 0, 112),],
gtk.gdk.ACTION_COPY | gtk.gdk.ACTION_MOVE)
self.connect("drag_data_received",self.on_drag_data_received_data)
def on_key_press_for_tag(self,widget,event):
if JBrout.modify:
nbSelected = len(self.selection)
if nbSelected>0:
if event.keyval<255 and event.string.strip()!="":
wk=WinKeyTag(_("Apply to %d photo(s)")%nbSelected,event.string,JBrout.tags.getAllTags())
ret=wk.loop()
if ret:
tag = ret[0]
self.parentWin.setTagsOnSelected(self,[tag,])
self.grab_focus()
def on_drag_data_received_data(self, widget, object,x,y,sdata,code,time):
""" event drop notified """
y+=self.get_vadjustment().get_value()
cell_num = self.cell_at_position(x,y,False)
if cell_num >=0:
if cell_num not in self.selection:
self.selection.set([cell_num])
self.parentWin.on_selecteur_drop(self)
def notify_selection_change(self,old):
""" event selection changed """
ThumbnailsView.notify_selection_change(self,old)
nbSelected = len(self.selection)
focusedItem = self.focus_cell
if nbSelected==1:
try:
photo_node = self.items[focusedItem]
info_text = "%d/%d" % (focusedItem+1,len(self.items) )+" - "+photo_node.name+" - "+photo_node.resolution+" - "+cd2d(photo_node.date).strftime('%d %B %Y %H:%M')+ " - " + ", ".join(photo_node.tags)
except:
info_text=""
elif nbSelected>0:
info_text = _("%d/%d selected") % (nbSelected,len(self.items) )
else:
info_text = ""
try:
self.parentWin.label_image_infos.set_text(info_text)
except:
pass
def getSelected(self):
return [self.items[i] for i in self.selection.real_selection if i<len(self.items)]
def setSelected(self,ln):
if ln:
lf=[i.file for i in self.items] ls = [lf.index(i.file) for i in ln] lold=self.selection.real_selection self.selection.set(ls)
self.focus_cell=ls[0]
self.scroll_to(self.focus_cell)
self.notify_selection_change(lold)
self.refresh()
def reSelectFocus(self):
if self.focus_cell < len(self.items) and self.items:
self.setSelected( [self.items[self.focus_cell],] )
def init(self,l,orderAscending=0):
sclwin=self.get_parent()
ss=sclwin.get_vscrollbar()
ss.set_value(0)
if orderAscending:
l.sort( cmp=lambda x,y: cmp(x.date,y.date))
else:
l.sort( cmp=lambda x,y: -cmp(x.date,y.date))
self.set_photos(l)
def remove(self,n):
idx=self.items.index(n)
if idx in self.selection.real_selection:
self.selection.remove(idx)
self.items.remove(n)
if self.focus_cell>=len(self.items):
self.focus_cell=max(0,len(self.items) -1)
self.scroll_to(self.focus_cell)
self.refresh()
def refresh(self):
""" refresh the layout """
self.notify_selection_change(self.selection.real_selection)
self.invalidate_view()
def get_text(self, idx): node = self.items[idx]
a= [
", ".join(node.tags),
node.comment,
node.folderName,
cd2rd(node.date),
node.name
] [self.select]
return a
def is_thumb(self,idx):
node = self.items[idx]
return node.file in Buffer.images
def get_thumb(self,idx):
node = self.items[idx]
if not self.is_thumb(idx):
Buffer.images[node.file]=node.getThumb()
pb=Buffer.images[node.file]
if node.isInBasket:
pb2 = pb.copy()
Buffer.pbBasket2.copy_area(0, 0, 15, 13, pb2, 7, 7)
pb=pb2
if node.isReadOnly:
pb2 = pb.copy()
wx= pb.get_width()
Buffer.pbReadOnly.copy_area(0, 0, 15, 13, pb2, wx-22,7)
pb=pb2
return pb
class DateDB(gtk.TreeStore):
def __init__(self):
gtk.TreeStore.__init__(self, str,gtk.gdk.Pixbuf,str)
def init(self,offset=0,today=False,selectDate=None):
self.clear()
if offset!=0:
y=self.selectedDate.year
m=self.selectedDate.month
d=self.selectedDate.day
if abs(offset)==1:
m+=offset
if m>12:
m=1
y+=1
if m<1:
m=12
y-=1
elif abs(offset)==12:
y+=(offset/12)
self.selectedDate = datetime.datetime(y,m,d)
if today:
t=datetime.datetime.now()
self.selectedDate = datetime.datetime(t.year,t.month,1)
if selectDate:
t=selectDate
self.selectedDate = datetime.datetime(t.year,t.month,1)
ym = self.selectedDate.strftime("%Y%m")
ln = JBrout.db.select("""//photo[substring(@date,1,6)="%s"]""" % ym)
jour={}
for node in ln:
jour[ node.date[:8] ] = node
jours = [i for i in jour.keys()]
jours.sort()
for i in jours:
node = jour[i]
d= datetime.datetime(int(i[:4]),int(i[4:6]),int(i[6:8]))
date = unicode(d.strftime("%A %d"),locale.getpreferredencoding ())
ymd = d.strftime("%Y%m%d")
self.append(None,[date,node.getThumb().scale_simple(80,80,gtk.gdk.INTERP_NEAREST),ymd])
return self.selectedDate
def whichPos(self,d):
ymd=d.strftime("%Y%m%d")
cpt=0
for nom,pb,yymmdd in self:
if ymd==yymmdd:
return cpt
cpt+=1
return None
class TreeDB(gtk.TreeStore):
def __init__(self,filter=None):
gtk.TreeStore.__init__(self, str,str,object,str)
self.__filter=filter
if filter==None or filter: self.init()
def init(self):
""" Init the tree and the basket (which will be refreshed) """
self.clear()
self.zapfill( JBrout.db.getRootFolder() ,None)
self.__iterBasket = None
self.activeBasket()
def zapfill(self,node,attach):
""" same as fill, but zap the beginning of the useless tree, and branch to fill """
if node != None:
folders = node.getFolders()
photos = node.getPhotos()
if len(folders)==1 and len(photos)==0: return self.zapfill(folders[0],attach)
else:
return self.fill(node,attach)
def fill(self,node,attach):
""" rebuild treestore from the nodefolder 'node' to the iter 'attach' """
if node != None:
folders = node.getFolders()
new = self.add(attach,node )
def isInFilter(f):
for i in self.__filter:
if f==i[:len(ufile)]:
if i==f:
return True
else:
if i[len(ufile)] in "\\/":
return True
return False
for i in folders:
if self.__filter!=None:
ufile = i.file
if isInFilter( ufile ):
self.fill(i,new)
else:
self.fill(i,new)
return new
def find(self,node):
""" return the 'iter' of the node in the model or None """
a = self.get_iter_root()
while a:
r=self.ffind(a,node)
if r: return r
a = self.iter_next(a)
def ffind(self,it,node):
nnode = self.get(it)
if nnode and nnode.file == node.file:
return it
else:
ic=self.iter_children(it)
while ic:
f=self.ffind(ic,node)
if f:
return f
else:
ic = self.iter_next(ic)
def expander(self,tree):
""" do the expand/collapse from the model(node) to the treeview 'tree' """
def _expander(model, path, iter0, tree):
node = model.get(iter0)
if node and node.expand:
tree.expand_row(path,False)
self.foreach( _expander, tree )
def get(self,it):
""" get the 'node' of the iter 'it' """
node = self.get_value(it,2)
return node
def set(self,it,node):
""" set the 'node' of the iter 'it' """
self.set_value(it,0,node.name)
self.set_value(it,1,len(node.getPhotos()))
self.set_value(it,2,node)
color = len(node.getPhotos())>0 and JStyle.TEXT or JStyle.TEXT_LOLIGHT
self.set_value(it,3,color)
def add(self,it,node):
""" append the 'node' to the iter """
color = len(node.getPhotos())>0 and JStyle.TEXT or JStyle.TEXT_LOLIGHT
return self.append(it,[node.name,len(node.getPhotos()),node,color])
def activeBasket(self):
if JBrout.db.isBasket():
if self.__iterBasket:
self.remove(self.__iterBasket)
nb = len(JBrout.db.getBasket())
self.__iterBasket = self.prepend(None,[_("Basket"),nb,None,JStyle.TEXT_HILIGHT])
else:
if self.__iterBasket:
self.remove(self.__iterBasket)
self.__iterBasket = None
class TreeTags(gtk.TreeStore):
def __init__(self,filter=None):
gtk.TreeStore.__init__(self, str,object,str, int,str)
self.__filter=filter self.init()
def init(self):
self.clear()
self.fill( JBrout.tags.getRootTag() ,None)
def fill(self,node,attach):
""" rebuild treestore from the catgnode 'node' to the iter 'attach' """
catgs = node.getCatgs()
tags = node.getTags()
new = self.add(attach,node)
for i in catgs:
self.fill(i,new)
for i in tags:
if self.__filter!=None:
if i.name in self.__filter:
self.add(new,i)
else:
self.add(new,i)
if self.__filter!=None:
if self.iter_children(new) == None:
self.remove(new)
def find(self,name):
""" return the 'iter' of the node 'name" in the model or None """
def _lookInside(model, path, iter0, rechNode):
node = model.get(iter0)
if node and node.name==rechNode:
_lookInside.ite = iter0
return True
_lookInside.ite=None
self.foreach( _lookInside, name )
return _lookInside.ite
def expander(self,tree):
""" do the expand/collapse from the model(node) to the treeview 'tree' """
def _expander(model, path, iter0, tree):
node = model.get(iter0)
if node.__class__.__name__ == "CatgNode" and node.expand:
tree.expand_row(path,False)
self.foreach( _expander, tree )
def get(self,it):
""" get the 'node' of the iter 'it' """
node = self.get_value(it,1)
return node
def cleanSelections(self):
""" clean selections in the tree """
def _clean(model, path, iter0):
model.set_value(iter0,3,0)
self.foreach( _clean )
def switch_inc(self,it):
if self.get_value(it,3)!=1:
self.set_value(it,3,1)
dis=True
else:
self.set_value(it,3,0)
dis=False
self.__switchChilds(it,dis)
def switch_exc(self,it):
if self.get_value(it,3)!=2:
self.set_value(it,3,2)
dis=True
else:
self.set_value(it,3,0)
dis=False
self.__switchChilds(it,dis)
def __switchChilds(self,it,dis):
node = self.get_value(it,1)
if node.__class__.__name__ == "CatgNode":
ii=self.iter_children(it)
while ii:
if dis:
self.set_value(ii,3,3)
self.__switchChilds(ii,dis)
else:
self.set_value(ii,3,0)
self.__switchChilds(ii,dis)
ii = self.iter_next(ii)
def getSelected(self):
""" return a list of tuple (type_of_check,name,sons_or_self)
- type_of_check : include or exclude
- name : name of the branch (tag or catg)
- sons_or_self : if it's a tag, it is its name, else (a catg), it's a list of tags descendant
"""
ii=self.get_iter_root()
ii=self.iter_children(ii)
def getAllLeaves(ii):
l=[]
while ii:
node = self.get_value(ii,1)
if node.__class__.__name__ == "CatgNode":
l+=getAllLeaves(self.iter_children(ii))
else:
l.append( node.name )
ii = self.iter_next(ii)
return l
def par(ii):
l=[]
while ii:
node = self.get_value(ii,1)
tcheck = self.get_value(ii,3)
if node.__class__.__name__ == "CatgNode":
if tcheck in (1,2):
l.append( (tcheck,node.name,getAllLeaves(self.iter_children(ii))) )
else:
l+=par(self.iter_children(ii))
else:
if tcheck in (1,2):
l.append( (tcheck,node.name,node.name) )
ii = self.iter_next(ii)
return l
return par(ii)
def setSelected(self,ltags):
""" set included for all TAGS in 'ltags'
(used by winshow)
"""
def _set(model, path, iter0):
node=model.get_value(iter0,1)
if node.__class__.__name__ == "TagNode" and node.name in ltags:
model.set_value(iter0,3,1)
else:
model.set_value(iter0,3,0)
self.foreach( _set )
def __displayKey(self,node):
return node.key and "(%s)"%node.key or ""
def add(self,it,node):
""" append the 'node' to the iter """
if node.__class__.__name__ == "TagNode":
return self.append(it,[node.name,node,JStyle.TEXT,0,self.__displayKey(node)])
else:
return self.append(it,["[%s]" % node.name,node,JStyle.TEXT_LOLIGHT,0,""])
class Window(GladeApp):
glade=os.path.join(os.path.dirname(__file__), 'jbrout.glade')
window="window"
def init(self):
if JBrout.conf["normalizeName"] == None:
ret=InputQuestion(self.main_widget,
_('Do you want JBrout to rename your imported photos according to their create timestamp (Recommended) ?'),
buttons=(gtk.STOCK_NO, gtk.RESPONSE_CANCEL, gtk.STOCK_YES, gtk.RESPONSE_OK)
)
if ret:
JBrout.conf["normalizeName"] = 1
else:
JBrout.conf["normalizeName"] = 0
if JBrout.conf["normalizeNameFormat"] == None: JBrout.conf["normalizeNameFormat"] = "p%Y%m%d_%H%M%S"
if JBrout.conf["autorotAtImport"] == None: JBrout.conf["autorotAtImport"] = 0
JBrout.db.setNormalizeName( JBrout.conf["normalizeName"]==1 )
JBrout.db.setNormalizeNameFormat( JBrout.conf["normalizeNameFormat"] )
JBrout.db.setAutorotAtImport( JBrout.conf["autorotAtImport"]==1 )
self.tagsInSelection=[]
self.foldersInSelection=[]
table = ListView(self,JBrout.modify)
table.connect('button-press-event', self.on_selecteur_mouseClick)
Buffer.clear()
self.tooltips = gtk.Tooltips()
canModify = JBrout.modify
for ord,text,alter,callback,img in JBrout.plugins.menuEntries():
if img:
if canModify:
enableMenu = True
else:
enableMenu = not alter
if enableMenu:
image=gtk.Image()
image.set_from_file(img)
image.show()
bb = gtk.ToolButton(image)
bb.set_tooltip(self.tooltips, text)
bb.connect("clicked", self.on_selecteur_menu_select_plugin,table,callback)
self.toolbar.insert(bb, 3)
bb.show()
frame_default = self.statusbar.get_children()[0]
self.label_image_infos= frame_default.get_children()[0]
self.label_image_infos.set_text("welcome")
progress_info_frame = gtk.Frame()
progress_info_frame.set_shadow_type(gtk.SHADOW_IN)
self.label_progress_infos = gtk.Label()
self.progress_bar = gtk.ProgressBar()
self.statusbar.pack_start(progress_info_frame, False, False, 0)
hbox = gtk.HBox()
hbox.pack_start(self.label_progress_infos, False, False, 5)
hbox.pack_start(self.progress_bar, False, False, 0)
progress_info_frame.add(hbox)
hbox.show_all()
self.statusbar.show_all()
self.progress_bar.hide()
self.main_widget.set_redraw_on_allocate(False)
self.comment=AlbumCommenter(JBrout.modify)
b=gtk.VBox()
b.show()
b.pack_start(self.comment,False,True,2)
sclwin = gtk.ScrolledWindow()
sclwin.set_policy(gtk.POLICY_NEVER, gtk.POLICY_ALWAYS)
sclwin.add(table)
sclwin.show()
b.pack_start(sclwin)
self.hpanedView.remove(self.frameFilter) self.hpanedView.pack1(b,True) self.hpanedView.pack2(self.frameFilter,False)
table.show()
table.grab_focus()
self.tbl = table
sclwin.set_shadow_type(1)
self.hpaned1.set_focus_chain((self.tbl,))
TARGET_STRING = 0
TARGET_ROOTWIN = 1
self.main_widget.set_title("JBrout "+__version__)
if JBrout.modify:
TARGETS = [
('MY_TREE_MODEL_ROW', gtk.TARGET_SAME_WIDGET, 0),
('TEXT', 0, 2),
('STRING', 0, 3),
]
self.treeviewdb.enable_model_drag_source( gtk.gdk.BUTTON1_MASK,
[TARGETS[0]],
gtk.gdk.ACTION_DEFAULT|
gtk.gdk.ACTION_COPY)
self.treeviewdb.enable_model_drag_dest([TARGETS[0]]+[("to_albums",0,0)], gtk.gdk.ACTION_DEFAULT)
self.btn_addFolder.drag_dest_set(gtk.DEST_DEFAULT_ALL, [( 'text/uri-list', 0, 1 ),('text/plain', 0, 1)], gtk.gdk.ACTION_COPY | gtk.gdk.ACTION_MOVE)
self.treeviewtags.enable_model_drag_source( gtk.gdk.BUTTON1_MASK|gtk.gdk.BUTTON2_MASK,
[TARGETS[0]]+[("from_tags",0,0)], gtk.gdk.ACTION_DEFAULT|
gtk.gdk.ACTION_COPY)
self.tvFilteredTags.enable_model_drag_source( gtk.gdk.BUTTON1_MASK|gtk.gdk.BUTTON2_MASK,
[("from_ftags",0,0)], gtk.gdk.ACTION_DEFAULT|
gtk.gdk.ACTION_COPY)
self.treeviewtags.enable_model_drag_dest([TARGETS[0]], gtk.gdk.ACTION_DEFAULT)
self.treeviewtags.get_selection().set_mode(gtk.SELECTION_MULTIPLE)
self.tvFilteredTags.get_selection().set_mode(gtk.SELECTION_MULTIPLE)
self.btn_addFolder.show()
else:
self.btn_addFolder.hide()
def filename(column, cell, model, iter):
v=model.get_value(iter, 1)
if int(v)>0:
nb= " (%s)" %v
else:
nb=""
cell.set_property('text', model.get_value(iter, 0)+nb)
cell.set_property('foreground', model.get_value(iter, 3))
cell.set_property('xalign', 0)
def pixbuf(column, cell, model, iter):
if model.get_value(iter, 2)==None:
cell.set_property('pixbuf', Buffer.pbBasket)
else:
cell.set_property('pixbuf', Buffer.pbFolder)
cell.set_property('width', 16)
cell.set_property('xalign', 0)
cellpb = gtk.CellRendererPixbuf()
cell = gtk.CellRendererText()
column = gtk.TreeViewColumn()
column.pack_start(cellpb, False)
column.pack_start(cell, False)
column.set_cell_data_func(cell, filename)
column.set_cell_data_func(cellpb, pixbuf)
self.treeviewdb.append_column(column)
cellpb = gtk.CellRendererPixbuf()
cell = gtk.CellRendererText()
column = gtk.TreeViewColumn()
column.pack_start(cellpb, False)
column.pack_start(cell, False)
column.set_cell_data_func(cell, filename)
column.set_cell_data_func(cellpb, pixbuf)
self.tvFilteredAlbums.append_column(column)
store = TreeDB()
self.treeviewdb.set_model( store )
store.expander(self.treeviewdb)
cell_renderer = gtk.CellRendererText()
column = gtk.TreeViewColumn("Tags", cell_renderer,text=0,foreground=2)
self.treeviewtags.append_column(column)
cell_renderer = gtk.CellRendererText()
column = gtk.TreeViewColumn("Tags", cell_renderer,text=0,foreground=2)
self.tvFilteredTags.append_column(column)
store = TreeTags()
self.treeviewtags.set_model( store )
store.expander(self.treeviewtags)
cell_renderer = gtk.CellRendererText()
column = gtk.TreeViewColumn("Dates", cell_renderer,text=0)
self.selectDate.append_column(column)
cellpb = gtk.CellRendererPixbuf()
column = gtk.TreeViewColumn("View", cellpb,pixbuf=1)
self.selectDate.append_column(column)
cell = gtk.CellRendererText()
self.comboboxyear.pack_start(cell, True)
self.comboboxyear.add_attribute(cell, 'text',0)
self.fillComboYear()
m = DateDB()
m.init(today=True)
self.selectDate.set_model(m)
menuDisplay=self.menuitem3.get_submenu()
gitem=None
for i in reversed(ListView.choix):
item = gtk.RadioMenuItem(gitem,i)
if not gitem: gitem = item
idx = self.tbl.choix.index(i) + 1
item.connect("activate",self.on_affichage_select,idx )
if idx == (JBrout.conf["viewSelection"] or 5):
self.tbl.select=idx
item.set_active(True)
item.show()
menuDisplay.prepend(item)
self.menuAscending.set_active( JBrout.conf["orderAscending"]==1 )
self.tvFilteredTags.connect("row_activated",self.on_treeviewtags_row_activated)
self.tvFilteredAlbums.connect("row_activated",self.on_treeviewdb_row_activated)
w,h=JBrout.conf["width"] or 800,JBrout.conf["height"] or 600
self.main_widget.set_default_size(w,h)
self.main_widget.reshow_with_initial_size()
self.hpaned1.set_position( JBrout.conf["hpaned"] or 160 )
self.frameFilter.hide()
self.hpanedView.set_position( -1 )
self.hs_size.set_value( int(JBrout.conf["thumbsize"] or 160) )
Window.MODEBASKET="basket"
Window.MODEFOLDER="folder"
Window.MODETIME="time"
Window.MODETAG="tag"
self.mode = Window.MODEFOLDER
self.storeMultipleSelectedPathsOfTags=[]
def fillComboYear(self):
""" fill the comboyear in tab "time" """
drange=JBrout.db.getMinMaxDates()
if drange:
min,max=drange
m=gtk.ListStore( str)
m.clear()
if min and max :
for i in range(min.year,max.year+1):
m.append( [str(i),] )
self.comboboxyear.set_model(m)
def on_order_changed(self,*args):
JBrout.conf["orderAscending"] = self.menuAscending.get_active() and 1 or 0
self.tbl.init(self.tbl.items,JBrout.conf["orderAscending"])
def on_affichage_select(self,widget,idx):
self.tbl.select=idx - 1
self.tbl.refresh()
label = self.menuitem3.get_children()[0]
label.set_text(_("Display (%s)") % self.tbl.choix[idx-1])
JBrout.conf["viewSelection"]=idx
return True
def showProgress(self,cur=None,max=None,msg=None):
"""
to show a current process is pending ... 3 types of call:
- showProgress(True) : block principal window (no msg, no win)
- showProgress(cur,max,msg) : block principal window, and show a progress bar cur/max + msg
- showProgress() : release principal window
"""
def off():
self.progress_bar.hide()
self.main_widget.window.set_cursor(None)
self.label_progress_infos.set_text('')
self.toolbar.set_sensitive(True)
self.menubar.set_sensitive(True)
self.notebook1.set_sensitive(True)
self.tbl.set_sensitive(True)
self.label_image_infos.set_sensitive(True)
self.comment.set_sensitive(True)
def on():
cursor = gtk.gdk.Cursor(gtk.gdk.WATCH)
self.main_widget.window.set_cursor(cursor)
self.progress_bar.show()
self.toolbar.set_sensitive(False)
self.menubar.set_sensitive(False)
self.notebook1.set_sensitive(False)
self.tbl.set_sensitive(False)
self.label_image_infos.set_sensitive(False)
self.comment.set_sensitive(False)
if cur is None and max is None:
self.tbl.start() off()
else:
if max is None:
self.tbl.start() off()
else:
self.tbl.stop() on()
if cur <= 0:
cur = 0.01
elif cur >= max:
cur = max
percent = float(cur)/max
self.progress_bar.set_fraction(percent)
self.label_progress_infos.set_text(msg)
while gtk.events_pending(): gtk.main_iteration(False)
def SetSelection(self,title,ln,mode,withFilter=True):
self.mode = mode
self.main_widget.set_title(_("%s (%d photo(s))") % (title,len(ln)))
self.tbl.init(ln,JBrout.conf["orderAscending"])
if mode != Window.MODEFOLDER:
self.comment.hide()
if withFilter:
self.refreshFilltered()
self.tbl.grab_focus()
def refreshFilltered(self):
ln=self.tbl.items
t=set()
f=set()
for i in ln:
t=t.union(i.tags)
f=f.union([i.folder,])
self.tagsInSelection = list(t)
self.foldersInSelection = list(f)
if self.cbxFilter.get_active():
store = TreeTags( self.tagsInSelection)
self.tvFilteredTags.set_model( store )
store.expander(self.tvFilteredTags)
store = TreeDB( self.foldersInSelection )
self.tvFilteredAlbums.set_model( store )
store.expander(self.tvFilteredAlbums)
def selectAlbum(self,model,iter0,all=True,fromFilteredTree=False):
if iter0:
self.showProgress(True)
try:
path = model.get_path(iter0)
node = model.get(iter0)
if node:
if all:
ln = node.getAllPhotos()
else:
ln = node.getPhotos()
name = node.name
mode = Window.MODEFOLDER
self.comment.set(node)
else:
ln = JBrout.db.getBasket()
name = _("Basket")
mode = Window.MODEBASKET
if not fromFilteredTree:
self.treeviewdb.expand_to_path( path )
self.treeviewdb.set_cursor( path )
self.SetSelection(name,ln,mode,not fromFilteredTree)
finally:
self.showProgress()
pass
def on_menu_rename(self,e):
treeselection = self.treeviewdb.get_selection()
model, iter0 = treeselection.get_selected()
node = model.get(iter0)
self.showProgress(True)
ret = InputBox(self.main_widget,_("Rename folder"),node.name)
self.showProgress()
if ret and ret != node.name:
if node.rename(ret):
model.set(iter0,node)
model.activeBasket()
self.selectAlbum(model,iter0)
def on_menu_new_folder(self,e):
treeselection = self.treeviewdb.get_selection()
model, iter0 = treeselection.get_selected()
node = model.get(iter0)
self.showProgress(True)
ret = InputBox(self.main_widget,_("New folder"),"")
self.showProgress()
if ret:
newNode = node.createNewFolder(ret)
if newNode:
iter1=model.add(iter0,newNode)
self.selectAlbum(model,iter1)
def on_menu_refresh(self,e):
Buffer.clear()
treeselection = self.treeviewdb.get_selection()
model, iter0 = treeselection.get_selected()
node = model.get(iter0)
parentIter = model.iter_parent(iter0)
path = node.file.decode("utf_8")
self.on_drop_folders_from_os(model,[path])
def on_menu_delete_from_db(self,e):
treeselection = self.treeviewdb.get_selection()
model, iter0 = treeselection.get_selected()
node = model.get(iter0)
parentIter = model.iter_parent(iter0)
node.remove()
model.remove(iter0)
model.activeBasket()
self.selectAlbum(model,parentIter)
def on_menu_delete_from_disk(self,e):
treeselection = self.treeviewdb.get_selection()
model, iter0 = treeselection.get_selected()
node = model.get(iter0)
nbsubfiles = len(os.listdir(node.file))
parentIter = model.iter_parent(iter0)
self.showProgress(True)
if nbsubfiles==0:
question = _("Are you sure to delete this folder ?")
else:
question = _("Are you sure to delete this folder ?\n(This folder contains %d file(s))") % nbsubfiles
ret = InputQuestion(self.main_widget,question)
self.showProgress()
if ret:
if node.delete():
model.remove(iter0)
model.activeBasket()
self.selectAlbum(model,parentIter)
def on_menu_remove_basket(self,e):
JBrout.db.clearBasket()
model = self.treeviewdb.get_model()
model.activeBasket()
self.tbl.refresh()
def on_menu_select_only(self,e):
treeselection = self.treeviewdb.get_selection()
model, iter0 = treeselection.get_selected()
self.selectAlbum(model,iter0,False)
def on_drop_photos(self,model,iter0):
node = model.get(iter0)
self.tbl.hide()
if node:
for i in self.tbl.getSelected():
nodeFolderParent = i.getParent()
if nodeFolderParent.file != node.file: if i.moveToFolder(node):
self.tbl.remove(i)
iterFolderParent = model.find( nodeFolderParent)
model.set(iterFolderParent,nodeFolderParent)
model.set(iter0,node)
else:
for node in self.tbl.getSelected():
node.addToBasket()
self.tbl.refresh()
self.tbl.show()
model.activeBasket()
self.tbl.reSelectFocus()
def on_drop_folders_from_os(self,model,files):
self.showProgress(0,1,"import") try:
newNodeFolder=None
importedTags={}
for folder in files:
if os.path.isdir(folder):
iterator = JBrout.db.add( folder,importedTags )
total = iterator.next()
for nb in iterator:
if type(nb)==int and nb>=0:
self.showProgress(nb,total,_("Importing %d/%d")%(nb,total))
if nb:
newNodeFolder = nb
if newNodeFolder: tags = importedTags.keys()
if tags:
nbNewTags = JBrout.tags.updateImportedTags( tags )
if nbNewTags: tmodel = self.treeviewtags.get_model()
tmodel.init()
tmodel.expander(self.treeviewtags)
MessageBox(self.main_widget,_("%d tag(s) were added !") % nbNewTags)
model.init( ) model.expander(self.treeviewdb)
newIterFolder = model.find( newNodeFolder )
self.selectAlbum(model,newIterFolder)
finally:
self.showProgress()
def on_move_folder(self,model,ifrom,ito):
nfrom = model.get(ifrom)
nto = model.get(ito)
if nto!=None:
if nfrom !=None:
if InputQuestion(self.main_widget,_("Are you sure to move this folder here ?")):
new = nfrom.moveToFolder(nto)
if new:
model.remove(ifrom)
iter0=model.fill(new,ito)
self.selectAlbum(model,iter0)
model.activeBasket()
else:
MessageBox(self.main_widget,_("Can't drag the basket to a folder"))
else:
if nfrom !=None:
for node in nfrom.getAllPhotos():
node.addToBasket()
model.activeBasket()
self.tbl.refresh()
def on_selecteur_mouseClick(self,widget,event): if event.button==3 and event.type == gtk.gdk.BUTTON_PRESS:
def makeItem(nom,callback,selecteur):
item = gtk.ImageMenuItem(nom)
item.connect("activate",callback,selecteur)
item.show()
return item
ln = widget.getSelected()
canBasketRemove=False
canBasketAdd=False
isThereAReadOnlyFile = False
for node in ln:
if node.isInBasket:
canBasketRemove = True
else:
canBasketAdd = True
if node.isReadOnly:
isThereAReadOnlyFile = True
canModify = JBrout.modify and (not isThereAReadOnlyFile)
menu = gtk.Menu()
if canBasketAdd: menu.append( makeItem(_("Add to Basket"), self.on_selecteur_menu_add_to_basket,widget) )
if canBasketRemove: menu.append( makeItem(_("Remove From Basket"), self.on_selecteur_menu_remove_from_basket,widget) )
if len(ln)==1: menu.append( makeItem(_("Select this folder"), self.on_selecteur_menu_select_folder,widget ))
menu.append( makeItem(_("Select this time"), self.on_selecteur_menu_select_time,widget ))
menu2 = gtk.Menu()
isEntries = False
for ord,text,alter,callback,img in JBrout.plugins.menuEntries(ln):
if canModify:
enableMenu = True
else:
enableMenu = not alter
if enableMenu:
item = gtk.ImageMenuItem( text )
if img:
ii=gtk.Image()
ii.set_from_file(img)
ii.show()
item.set_image(ii)
menu2.append(item)
item.connect("activate",self.on_selecteur_menu_select_plugin,widget,callback)
isEntries = True
if isEntries:
smenu2=gtk.ImageMenuItem(_("Operations"))
smenu2.set_submenu(menu2)
smenu2.show_all()
menu.append(smenu2)
menuET = gtk.Menu()
isEntries=False
listET = ExternalTools(JBrout.toolsFile)
for et in listET:
if canModify:
enableItem=True
else:
enableItem=not et.canModify
if enableItem:
item = gtk.ImageMenuItem( et.label )
menuET.append(item)
item.connect("activate",self.on_selecteur_menu_select_external_tool,widget,et)
isEntries=True
if isEntries:
smenuET=gtk.ImageMenuItem(_("External Tools"))
smenuET.set_submenu(menuET)
smenuET.show_all()
menu.append(smenuET)
if canModify:
d=[]
for pnode in ln:
for t in pnode.tags:
if t not in d:
d.append(t)
if d:
d.sort()
menu3 = gtk.Menu()
for tag in d:
item = gtk.ImageMenuItem( tag )
item.connect("activate",self.on_selecteur_menu_delete_tag,widget,tag)
menu3.append(item)
item = gtk.ImageMenuItem( _("** ALL **") )
item.connect("activate",self.on_selecteur_menu_delete_tag,widget,"*")
menu3.append(item)
smenu3=gtk.ImageMenuItem(_("Delete tag"))
smenu3.set_submenu(menu3)
smenu3.show_all()
menu.append(smenu3)
menu.append( makeItem(_("Delete"), self.on_selecteur_menu_delete,widget ))
menu.popup(None,None,None,event.button,event.time)
return 1
elif event.button==1 and event.type == gtk.gdk._2BUTTON_PRESS:
l,i = widget.items,widget.focus_cell
isInfo = JBrout.conf["showInfo"]==1 and True or False
isModify = JBrout.modify
w=WinShow(TreeTags(),l,i,isInfo,isModify)
w.hpShow.set_position( int(JBrout.conf["viewertreewidth"] or 160) )
w.loop()
JBrout.conf["viewertreewidth"] = int(w.hpShow.get_position())
JBrout.conf["showInfo"]=w.needInfo and 1 or 0
if w.removed:
sel = self.tbl.setSelected(w.removed)
self.on_selecteur_menu_delete(None,self.tbl)
if w.selected: sel = self.tbl.setSelected(w.selected)
if w.isBasketUpdate: model=self.treeviewdb.get_model()
model.activeBasket()
return 1
def on_selecteur_menu_delete_tag(self,b,sel,tag):
ln=sel.getSelected()
try:
for i in ln:
self.showProgress(ln.index(i),len(ln),_("Deleting tags"))
if tag=="*":
i.clearTags()
else:
i.delTag(tag)
finally:
self.showProgress()
sel.refresh()
def on_selecteur_menu_add_to_basket(self,b,sel):
ln = sel.getSelected()
for node in ln:
node.addToBasket()
model=self.treeviewdb.get_model()
model.activeBasket()
sel.refresh()
def on_selecteur_menu_remove_from_basket(self,b,sel):
ln = sel.getSelected()
for node in ln:
node.removeFromBasket()
if self.mode == Window.MODEBASKET:
sel.remove(node)
model=self.treeviewdb.get_model()
model.activeBasket()
sel.refresh()
def on_selecteur_menu_select_folder(self,b,sel):
ln = sel.getSelected()
assert len(ln)==1
node = ln[0]
self.notebook1.set_current_page(0)
folderNode = node.getParent()
model = self.treeviewdb.get_model()
iterFolder = model.find( folderNode)
self.selectAlbum(model,iterFolder)
sel.setSelected([node])
def on_selecteur_menu_select_time(self,b,sel):
ln = sel.getSelected()
assert len(ln)==1
node = ln[0]
d=cd2d(node.date)
self.notebook1.set_current_page(1)
model=self.selectDate.get_model()
self.date_display_update(model.init(selectDate=d))
pos=model.whichPos(d)
if pos:
treeselection = self.selectDate.get_selection()
treeselection.select_path( pos )
self.on_selectDate_row_activated(self.selectDate,None)
self.selectDate.set_cursor( pos )
sel.setSelected([node])
def on_selecteur_menu_delete(self,b,sel):
l = sel.getSelected()
ret = InputQuestion(None,_("Delete %d photo(s) are you sure ?") % len(l))
if ret:
sel.hide()
model = self.treeviewdb.get_model()
for i in l:
file = i.file
folderNode = i.getParent()
if i.delete():
Buffer.remove(file)
sel.remove(i)
iterFolderParent = model.find( folderNode)
model.set(iterFolderParent,folderNode)
model.activeBasket()
sel.show()
sel.refresh()
sel.reSelectFocus()
def on_selecteur_menu_select_plugin(self,ib,listview,callback):
l = listview.getSelected()
if l:
self.showProgress(True)
try:
ret=callback(l)
finally:
self.showProgress()
if ret:
for i in l:
Buffer.remove(i.file)
self.treeviewdb.get_model().activeBasket()
listview.refresh()
listview.refresh()
def on_selecteur_menu_select_external_tool(self,ib,listview,et):
l = listview.getSelected()
self.showProgress(True)
destination=unicode(tempfile.mkdtemp(".tmp","jbrout"))
for pnode in l:
pnode.copyTo(destination)
try:
g=et.g_run(l)
c=1
while 1:
self.showProgress( c, len(l) , et.label )
c+=1
if not g.next(): break
finally:
self.showProgress()
for pnode in l:
tmpfile = os.path.join(destination,pnode.name)
try:
pnode.getInfoFrom( tmpfile )
except IOError:
shutil.move(tmpfile,pnode.file)
try:
shutil.rmtree(destination)
except:
pass
for i in l:
Buffer.remove(i.file)
self.treeviewdb.get_model().activeBasket()
listview.refresh()
listview.refresh()
def on_selecteur_drop(self,sel):
self.setTagsOnSelected(sel,self.dragTags)
def setTagsOnSelected(self,sel,l):
if l:
ln = sel.getSelected()
try:
for i in ln:
self.showProgress(ln.index(i),len(ln),_("Adding tags"))
if i.isReadOnly:
beep(_("can't add tag to a readonly picture"))
else:
i.addTags(l)
finally:
self.showProgress()
sel.refresh()
def on_cbxFilter_toggled(self,widg,*args):
if widg.get_active():
self.frameFilter.show()
self.refreshFilltered()
else:
self.frameFilter.hide()
def on_menu_add_tag(self,e):
treeselection = self.treeviewtags.get_selection()
model,paths = treeselection.get_selected_rows()
if len(paths)==1:
iter0 = model.get_iter(paths[0])
node = model.get(iter0)
self.showProgress(True)
ret = InputBox(self.main_widget,_("New tag"),"")
self.showProgress()
if ret:
newt = node.addTag(ret.strip())
if newt:
newiter=model.add(iter0,newt)
path=model.get_path(newiter)
self.treeviewtags.expand_to_path( path )
self.treeviewtags.set_cursor( path )
else:
MessageBox(self.main_widget,_("Tag already exists"))
def on_menu_add_catg(self,e):
treeselection = self.treeviewtags.get_selection()
model,paths = treeselection.get_selected_rows()
if len(paths)==1:
iter0 = model.get_iter(paths[0])
node = model.get(iter0)
self.showProgress(True)
ret = InputBox(self.main_widget,_("New category"),"")
self.showProgress()
if ret:
newt = node.addCatg(ret.strip())
if newt:
newiter=model.add(iter0,newt)
path=model.get_path(newiter)
self.treeviewtags.expand_to_path( path )
self.treeviewtags.set_cursor( path )
else:
MessageBox(self.main_widget,_("Category already exists"))
def on_menu_delete_tags(self,e):
treeselection = self.treeviewtags.get_selection()
model,paths = treeselection.get_selected_rows()
if len(paths)==1:
iter0 = model.get_iter(paths[0])
node = model.get(iter0)
if node.__class__.__name__ == "TagNode":
ln = JBrout.db.select("""//photo[t="%s"]""" % node.name)
if len(ln)>0:
MessageBox(self.main_widget,_("This tag is in use"))
else:
node.remove()
model.remove(iter0)
else:
ln = node.getTags() + node.getCatgs()
if len(ln)==0:
node.remove()
model.remove(iter0)
else:
MessageBox(self.main_widget,_("Category is not empty"))
def date_display_update(self, date):
act=0
m=self.comboboxyear.get_model()
if m:
for i in range(len(m)):
if date.year == int(m[i][0]):
act=i
self.comboboxyear.set_active(act)
self.comboboxmonth.set_active(date.month-1)
def on_window_delete_event(self, widget, *args):
JBrout.conf["hpaned"] = self.hpaned1.get_position()
JBrout.conf["width"],JBrout.conf["height"] = self.main_widget.get_size()
JBrout.db.save()
JBrout.tags.save()
JBrout.conf.save()
self.quit()
def on_window_size_allocate(self, widget, *args):
pass
def on_editTools_activate(self,*args):
if not os.path.isfile(JBrout.toolsFile):
ExternalTools.generate(JBrout.toolsFile)
runWith(["notepad.exe","leafpad","scite","gedit","kate"],unicode(JBrout.toolsFile))
def on_search_activate(self, widget, *args):
win_search = Winsearch( TreeTags(), self.main_widget )
win_search.loop()
if win_search.xpath:
libl,xpath = win_search.xpath
ln = JBrout.db.select(xpath)
self.SetSelection(libl,ln,Window.MODETAG)
def on_quitter_activate(self, widget, *args):
self.on_window_delete_event(widget,*args)
def on_help_activate(self,*args):
try:
import locale
lang=locale.getdefaultlocale()[0][:2].lower()
if lang!="fr":
lang="en"
except:
lang="en"
openURL(u"http://jbrout.free.fr/help/%s/" % lang)
def on_a_propos_activate(self, widget, *args):
about = gtk.AboutDialog()
about.set_name('jbrout')
about.set_version(__version__)
about.set_copyright('Copyright 2005 Marc Lentz')
about.set_license(open("gpl.txt").read())
about.set_authors(['Marc Lentz',"","thanks to:", '- Frederic Peters',"- Erik Charlesson (french online help)","- Pieter Edelman (flickr uploader)"])
about.set_website('http://jbrout.python-hosting.com/wiki')
about.show()
def on_btn_addFolder_clicked(self, widget, *args):
print "on_btn_addFolder_clicked called with self.%s" % widget.get_name()
def on_btn_addFolder_drag_data_received(self, widget, *args):
print "on_btn_addFolder_drag_data_received called with self.%s" % widget.get_name()
def on_hs_size_value_changed(self, widget, *args):
self.tbl.thumbnail_width = int(widget.get_value())
JBrout.conf["thumbsize"] = int(widget.get_value())
def on_notebook1_switch_page(self, widget, *args):
gpoint,page= args
if page==1: self.fillComboYear()
date = self.selectDate.get_model().init()
self.date_display_update(date)
def on_treeviewdb_drag_data_received(self, widget, *args):
context, x, y, selection, info, time = args
dragFrom =context.get_source_widget().__class__.__name__
if dragFrom == "TreeView":
model = widget.get_model()
if self.dragFolder:
drop_info = widget.get_dest_row_at_pos(x, y)
if drop_info:
path, position = drop_info
iterTo = model.get_iter(path)
_cur = iterTo
parents=[model.get_path(_cur)]
while 1:
_cur = model.iter_parent(_cur)
if _cur:
parents.append(model.get_path(_cur))
else:
break
if model.get_path(self.dragFolder) not in parents:
self.on_move_folder(model,self.dragFolder,iterTo)
self.dragFolder=None
context.finish(True, False, time)
else:
beep(_("Don't drop parents to a child"))
else:
beep(_("Drop in space"))
else:
beep(_("Nothing was dragged"))
elif dragFrom == "ListView": drop_info = widget.get_dest_row_at_pos(x, y)
model=widget.get_model()
if drop_info:
path, position = drop_info
if position in [gtk.TREE_VIEW_DROP_INTO_OR_BEFORE,gtk.TREE_VIEW_DROP_INTO_OR_AFTER]:
iterTo = model.get_iter(path)
self.on_drop_photos(model,iterTo)
else:
beep(_("Drop from nowhere"))
context.finish(True,False, time)
def on_treeviewdb_row_expanded(self, widget, *args):
iter0,path = args
model = widget.get_model()
node = model.get(iter0)
node.setExpand(True)
def on_treeviewdb_row_collapsed(self, widget, *args):
iter0,path = args
model = widget.get_model()
node = model.get(iter0)
node.setExpand(False)
def on_treeviewdb_row_activated(self, widget, *args):
treeselection = widget.get_selection()
model, iter0 = treeselection.get_selected()
fromFilteredTree = (widget == self.tvFilteredAlbums)
self.selectAlbum( model, iter0, fromFilteredTree = fromFilteredTree )
def on_treeviewdb_drag_data_get(self, widget, *args):
treeselection = widget.get_selection()
model, iter0 = treeselection.get_selected()
self.dragFolder = iter0
def on_treeviewdb_button_press_event(self, widget, event):
def makeItem(nom,callback):
item = gtk.ImageMenuItem(nom)
item.connect("activate",callback)
item.show()
return item
treeselection = widget.get_selection()
model, iter0 = treeselection.get_selected()
if iter0 and event.type == gtk.gdk.BUTTON_PRESS:
node = model.get(iter0)
if node!=None:
if event.button==3:
menu = gtk.Menu()
menu.append( makeItem(_("Select only"),self.on_menu_select_only) )
if JBrout.modify:
menu.append( makeItem(_("Rename"),self.on_menu_rename) )
menu.append( makeItem(_("New folder"),self.on_menu_new_folder) )
menu.append( makeItem(_("Refresh"),self.on_menu_refresh) )
menu.append( makeItem(_("Remove from db"),self.on_menu_delete_from_db) )
menu.append( makeItem(_("Delete from disk"),self.on_menu_delete_from_disk) )
menu2 = gtk.Menu()
isEntries = False
for ord,text,alter,callback in JBrout.plugins.albumEntries(node):
if JBrout.modify:
enableMenu = True
else:
enableMenu = not alter
if enableMenu:
item = gtk.ImageMenuItem( text )
item.connect("activate",self.on_album_menu_select_plugin,widget,callback)
menu2.append(item)
isEntries = True
if isEntries:
smenu2=gtk.ImageMenuItem(_("Operations"))
smenu2.set_submenu(menu2)
smenu2.show_all()
menu.append(smenu2)
menu.popup(None,None,None,event.button,event.time)
return 1
elif event.button==2:
self.selectAlbum(model,iter0,False)
return 1
else:
if event.button==3:
menu = gtk.Menu()
menu.append( makeItem(_("Remove"),self.on_menu_remove_basket) )
menu.popup(None,None,None,event.button,event.time)
return 1
elif event.button==2:
self.selectAlbum(model,iter0)
return 1
def on_album_menu_select_plugin(self,ib,widget,callback):
treeselection = widget.get_selection()
model, iter0 = treeselection.get_selected()
if iter0:
node = model.get(iter0)
self.showProgress(True)
try:
ret=callback(node)
finally:
self.showProgress()
if ret:
self.on_menu_refresh(None)
model.activeBasket()
def on_btn_addFolder_clicked(self, widget, *args):
dialog = gtk.FileChooserDialog (_("Add Folder"),
None, gtk.FILE_CHOOSER_ACTION_SELECT_FOLDER,
(gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL, gtk.STOCK_OPEN,
gtk.RESPONSE_OK))
dialog.set_default_response (gtk.RESPONSE_OK)
dialog.set_transient_for (self.main_widget)
if sys.platform[:3].lower()=="win":
default="c:\\"
else:
default=""
dialog.select_filename (JBrout.conf["addFolderDefaultPath"] or default)
response = dialog.run ()
if response == gtk.RESPONSE_OK:
folder = dialog.get_filename().decode( "utf_8" ) JBrout.conf["addFolderDefaultPath"] = folder
else: