Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorroot <root@ghunt-desktop.(none)>2010-06-12 10:12:16 (GMT)
committer root <root@ghunt-desktop.(none)>2010-06-12 10:12:16 (GMT)
commit2415239957382b99e8fde4aa6b0f1d5684f962bb (patch)
tree8435f1d906e7007b9652f795913877f2be04ffc4
parentc66d824660bdd9709bde659daf97c0a4017acfcc (diff)
improvements to add album, partial thumbnail scroll, snapshot for reflash
-rw-r--r--activity/permissions.info2
-rw-r--r--data_cache.sqlitebin0 -> 1231872 bytes
-rw-r--r--data_cache.sqlite.templatebin0 -> 2048 bytes
-rw-r--r--dbphoto.py80
-rw-r--r--display.py601
-rw-r--r--photo_toolbar.py15
-rw-r--r--sources.py28
-rw-r--r--sugargame/canvas.py19
-rw-r--r--xophoto.sqlite.templatebin12288 -> 12288 bytes
-rw-r--r--xophotoactivity.py91
10 files changed, 506 insertions, 330 deletions
diff --git a/activity/permissions.info b/activity/permissions.info
new file mode 100644
index 0000000..431deab
--- /dev/null
+++ b/activity/permissions.info
@@ -0,0 +1,2 @@
+constant-uid
+
diff --git a/data_cache.sqlite b/data_cache.sqlite
new file mode 100644
index 0000000..57b8e38
--- /dev/null
+++ b/data_cache.sqlite
Binary files differ
diff --git a/data_cache.sqlite.template b/data_cache.sqlite.template
new file mode 100644
index 0000000..b76b868
--- /dev/null
+++ b/data_cache.sqlite.template
Binary files differ
diff --git a/dbphoto.py b/dbphoto.py
index 5221c33..295b2cb 100644
--- a/dbphoto.py
+++ b/dbphoto.py
@@ -29,6 +29,7 @@ import hashlib
#pick up activity globals
from xophotoactivity import *
+import display
#define globals related to sqlite
sqlite_file_path = None
@@ -56,15 +57,34 @@ class DbAccess():
_logger.debug('trying to open database cwd:%s filename %s'%(os.getcwd(),dbfilename,))
dbfilename = os.path.join(os.getcwd(),dbfilename)
self.con = sqlite3.connect(dbfilename)
+ self.dbfilename = dbfilename
self.con.row_factory = sqlite3.Row
self.con.text_factory = str
#rows generated thusly will have columns that are addressable as dict of fieldnames
self.cur = self.con.cursor()
+ path = os.path.dirname(dbfilename)
+ data_db = os.path.join(path,'data_cache.sqlite')
+ sql = "attach '%s' as data_cache"%data_db
+ _logger.debug('attaching using sql %s'%sql)
+ self.cur.execute(sql)
except IOError,e:
_logger.debug('open database failed. exception :%s '%(e,))
return None
return self.cur
+ def connection(self):
+ #test to see if the database is open
+ if self.con:
+ try:
+ cursor = self.con.cursor()
+ cursor.execute('select * from config')
+ not_open = False
+ except:
+ not_open = True
+ if not self.con or not_open:
+ self.opendb(self.dbfilename)
+ return self.con
+
def is_open(self):
if self.con: return True
return False
@@ -91,13 +111,17 @@ class DbAccess():
return rows[0]['mime_type']
return None
- def get_album_list(self):
- sql = 'select max duplicate from picture group by album'
- album_list,cur = self.dbdo(sql)
- if len(album_list) == 0:
- _logger.debug('failed to retrieve albums')
- return None
- return album_list
+ def get_albums(self):
+ cursor = self.connection().cursor()
+ cursor.execute('select * from groups where category = ?',('albums',))
+ return cursor.fetchall()
+
+ def get_album_thumbnails(self,album_id):
+ sql = """select pict.*, grp.* from picture as pict, groups as grp \
+ where grp.category = ? and grp.jobject_id = pict.jobject_id order by create_date desc"""
+ cursor = self.connection().cursor()
+ cursor.execute(sql,(str(album_id),))
+ return cursor.fetchall()
def create_picture_record(self,object_id, fn):
"""create a record in picture pointing to unique pictures in the journal.
@@ -127,14 +151,14 @@ class DbAccess():
(in_ds, mount_point, orig_size, create_date,jobject_id, md5_sum, duplicate) \
values (%s,'%s',%s,'%s','%s','%s',%s)""" % \
(1, fn, info.st_size, info.st_ctime, object_id, md5_hash,len(rows_md5),)
- cursor = self.con.cursor()
+ cursor = self.connection().cursor()
cursor.execute(sql)
self.con.commit()
return 1
elif len(rows) == 1:
sql = """update picture set in_ds = ?, mount_point = ?, orig_size = ?, \
create_date = ?, md5_sum = ?, duplicate = ?"""
- cursor = self.con.cursor()
+ cursor = self.connection().cursor()
cursor.execute(sql,(1, fn, info.st_size, info.st_ctime, md5_hash,len(rows_md5)))
self.con.commit()
return 0
@@ -145,15 +169,15 @@ class DbAccess():
#_logger.debug('rowcount %s object_id %s'%(len(rows),object_id))
#the object_id is supposed to be unique, so add only new object_id's
if len(rows) == 0:
- cursor = self.con.cursor()
+ cursor = self.connection().cursor()
cursor.execute('insert into picture (jobject_id) values (?)',(str(jobject_id),))
self.con.commit()
def clear_in_ds(self):
- self.con.execute('update picture set in_ds = 0')
+ self.connection().execute('update picture set in_ds = 0')
def delete_not_in_ds(self):
- self.con.execute('delete from picture where in_ds = 0')
+ self.connection().execute('delete from picture where in_ds = 0')
def check_in_ds(self,fullpath,size):
sql = "select * from picture where mount_point = '%s' and orig_size = %s"%(fullpath,size,)
@@ -163,7 +187,7 @@ class DbAccess():
return False
def get_last_album(self):
- cursor = self.con.cursor()
+ cursor = self.connection().cursor()
cursor.execute("select * from config where name = 'last_album'")
rows = cursor.fetchmany()
_logger.debug('found %s last albums'%len(rows))
@@ -176,7 +200,7 @@ class DbAccess():
return None,0
def set_last_album(self,album_id):
- cursor = self.con.cursor()
+ cursor = self.connection().cursor()
value,id = self.get_last_album()
if id > 0:
cursor.execute("update config set value = ? where id = ?",(album_id,id))
@@ -185,7 +209,7 @@ class DbAccess():
self.con.commit()
def set_album_count(self,album_id,count):
- cursor = self.con.cursor()
+ cursor = self.connection().cursor()
cursor.execute("select * from groups where category = 'albums' and subcategory = ?",(str(album_id),))
rows = cursor.fetchmany()
if len(rows) == 1:
@@ -196,7 +220,7 @@ class DbAccess():
_logger.debug('set album count error:%s'%e)
def get_album_count(self,album_id):
- cursor = self.con.cursor()
+ cursor = self.connection().cursor()
try:
cursor.execute("select * from groups where category = 'albums' and subcategory = ?",(str(album_id,)))
rows = cursor.fetchmany()
@@ -207,13 +231,14 @@ class DbAccess():
return 0
def create_update_album(self,album_id,name):
- cursor = self.con.cursor()
+ cursor = self.connection().cursor()
cursor.execute('select * from groups where category = ? and subcategory = ?',\
('albums',str(album_id,)))
rows = cursor.fetchmany()
+ _logger.debug('create-update found %s records. album:%s. id:%s'%(len(rows),album_id,name,))
if len(rows)>0 : #pick up the name
id = rows[0]['id']
- cursor.execute("update groups set category = ?, subcategory = ?, jobject_id = ? where id = ?",\
+ cursor.execute("update groups set subcategory = ?, jobject_id = ? where id = ?",\
(str(album_id),name,id))
else:
cursor.execute("insert into groups (category,subcategory,jobject_id,seq) values (?,?,?,?)",\
@@ -221,20 +246,27 @@ class DbAccess():
self.con.commit()
def add_image_to_album(self, album_id, jobject_id):
- cursor = self.con.cursor()
+ cursor = self.connection().cursor()
+ cursor.execute('select max(seq) as max_seq from groups where category = ? group by category',(album_id,))
+ rows = cursor.fetchall()
+ if len(rows)>0:
+ old_seq = rows[0]['max_seq']
+ else:
+ old_seq = 0
+ _logger.debug('failed to get max of seq for album %s'%album_id)
#we will try to add the same picture only once
cursor.execute("select * from groups where category = ? and jobject_id = ?",\
(str(album_id), str(jobject_id,)))
rows = cursor.fetchmany()
if len(rows)>0: return None
cursor.execute("insert into groups (category,subcategory,jobject_id,seq) values (?,?,?,?)",\
- (str(album_id),'',str(jobject_id),0))
+ (str(album_id),'',str(jobject_id),old_seq + 20))
self.con.commit()
def table_exists(self,table):
try:
sql = 'select * from %s'%table
- self.con.execute(sql)
+ self.connection().execute(sql)
return True
except:
return False
@@ -259,7 +291,7 @@ class DbAccess():
def fieldlist(self,table):
list=[] #accumulator for model
- cur = self.con.cursor()
+ cur = self.connection().cursor()
cur.execute('select * from %s'%table)
if cur:
for field in cur.description:
@@ -282,14 +314,14 @@ class DbAccess():
def dbdo(self,sql):
""" execute a sql statement or definition, return rows and cursor """
try:
- cur = self.con.cursor()
+ cur = self.connection().cursor()
cur.execute(sql)
return cur.fetchall(), cur
#self.con.commit()
except sqlite.Error, e:
_logger.debug( 'An sqlite error:%s; sql:%s'%(e,sql,))
self.error = str(e)
- raise PhotoException(self.error)
+ raise display.PhotoException(self.error)
def dbtry(self,sql):
""" execute a sql statement return true if no error"""
diff --git a/display.py b/display.py
index 758e79d..8bd0528 100644
--- a/display.py
+++ b/display.py
@@ -57,21 +57,31 @@ from ezscroll.ezscroll import ScrollBar
from xophotoactivity import *
#Display Module globals
-background_color = (210,210,210)
-album_background_color = (170,170,170)
-album_selected_color = (210,210,210)
-selected_color = (0,230,0)
mouse_timer = time.time()
in_click_delay = False
in_db_wait = False
in_drag = False
screen_h = 0
screen_w = 0
+
#thickness of scroll bar
-thick = 20
+thick = 15
sb_padding = 6
-album_display_start = 0
+background_color = (210,210,210)
+album_background_color = (170,170,170)
+album_selected_color = (210,210,210)
+selected_color = (0,230,0)
+text_color = (0,0,200)
+album_font_size = 30
album_column_width = 200
+album_height = 190
+album_size = (180,165)
+album_location = (25,25)
+album_aperature = (150,125)
+
+journal_id = '20100521T10:42'
+trash_id = '20100521T11:40'
+
import logging
_logger = logging.getLogger('xophoto.display')
@@ -88,7 +98,7 @@ class PhotoException(Exception):
def __str__():
return repr(self.value)
-class DisplayOne():
+class OneThumbnail():
def __init__(self,rows,db,target,index=0,save_to_db=True):
self.rows = rows
self.db = db
@@ -103,8 +113,9 @@ class DisplayOne():
self.surf = None
self.background = (200,200,200)
self.scaled = None
+ self.from_database = False
- def paint(self):
+ def paint_thumbnail(self):
"""
Put an image on pygame screen.
Inputs: 1. cursor pointing to picture records of xophoto.sqlite
@@ -112,7 +123,7 @@ class DisplayOne():
"""
if not self.scaled:
i = self.db.row_index('jobject_id','picture')
- id = self.rows[self.row_index][i]
+ id = self.rows[self.row_index]['jobject_id']
self.surface = pygame.Surface((self.size_x,self.size_y,))
self.surface.fill(background_color)
self.scaled = self.scale_image(id,self.size_x,self.size_y)
@@ -132,8 +143,9 @@ class DisplayOne():
First check to see if this thumbnail is already in the database, if so, return it
If not, generate the thumbnail, write it to the database, and return it
"""
+ #_logger.debug('scale_image id:%s.x:%s. y:%s'%(id,x_size,y_size,))
max_dim = max(x_size,y_size) - 2*self.border
- sql = 'select * from transforms where jobject_id = "%s"'%id
+ sql = 'select * from data_cache.transforms where jobject_id = "%s"'%id
rows, cur = self.db.dbdo(sql)
for row in rows:
w = row['scaled_x']
@@ -147,6 +159,7 @@ class DisplayOne():
blob =row['thumb']
surf = pygame.image.frombuffer(blob,(w,h),'RGB')
#_logger.debug('retrieved thumbnail from database')
+ self.from_database = True
return surf
try:
ds_obj = datastore.get(id)
@@ -185,12 +198,13 @@ class DisplayOne():
cursor = conn.cursor()
thumb_binary = sqlite3.Binary(thumbstr)
try:
- cursor.execute("insert into transforms (jobject_id,original_x,original_y,scaled_x,scaled_y,thumb) values (?,?,?,?,?,?)",\
+ cursor.execute("insert into data_cache.transforms (jobject_id,original_x,original_y,scaled_x,scaled_y,thumb) values (?,?,?,?,?,?)",\
(id,w,h,self.x_thumb,self.y_thumb,thumb_binary,))
except sqlite3.Error,e:
_logger.debug('write thumbnail error %s'%e)
return None
self.db.commit()
+ self.from_database = False
return ret
def position(self,x,y):
@@ -217,131 +231,222 @@ class DisplayOne():
return self
-class DisplayMany():
+class OneAlbum():
"""
Receives an open database object refering to
database:'xophoto.sqlite' which is stored in the journal
+ Displays one album and the associated thumbnails
"""
- def __init__(self,dbaccess,index=0):
- global background_color
+ def __init__(self,dbaccess,album_id):
self.db = dbaccess
+ self.album_id = album_id
self.pict_dict = {}
self.large_displayed = False
- self.screen_width = screen_w - album_column_width
+ self.screen_width = screen_w - album_column_width - thick
self.screen_height = screen_h
- self.picture_surface = pygame.Surface((self.screen_width,self.screen_height))
- self.picture_surface.fill(background_color)
self.screen_origin_x = 000
self.screen_origin_y = 000
self.pict_per_row = 5
self.num_rows = 4
- self.display_start_index = index
self.origin_row = 0
+ self.display_end_index = 0
+ self.jobject_id = None
+ self.thumbnail_world = None
+ self.thumbnail_surface = pygame.Surface((screen_w-album_column_width-thick,screen_h)).convert()
+ self.thumbnail_surface.fill(background_color)
+
+ #variable for remembering the state of the thumbnail display
+ self.display_start_index = 0
+ self.thumb_index = 0
self.last_selected = None
- def paint(self,rows,index=0):
+ #figure out what size to paint, assuming square aspect ratio
+ screen_max = max(self.screen_height,self.screen_width)
+ self.xy_size = screen_max // self.pict_per_row
+
+
+ def paint(self):
"""
Put multiple images on pygame screen.
- Inputs: 1. cursor pointing to picture records of xophoto.sqlite
- 2. Index into cursor
"""
- self.rows = rows
- if index < 0:
- self.display_start_index = 0
- self.origin_row = 0
- elif index >= len(rows):
- self.display_start_index = len(rows) - self.pict_per_row
- self.origin_row = index // self.pict_per_row
- self.selected_index = index
+ #make sure we have the most recent list
+ self.rows = self.db.get_album_thumbnails(self.album_id)
+
+ #as we fetch the thumbnails record the number for the left column display
+ self.db.set_album_count(self.album_id,len(self.rows))
+
#protect from an empty database
if len(self.rows) == 0: return
- #figure out what size to paint, assuming square aspect ratio
- if self.pict_per_row > 0:
- #x_size = math.floor(self.screen_width/self.pict_per_row)
- x_size = self.screen_width // self.pict_per_row
- else:
- raise PhotoException('pict_per_row was zero or negative')
- if x_size > self.screen_width:
- x_size = self.screen_width
- if x_size > self.screen_height:
- x_size = self.screen_height
- y_size = x_size
- self.xy_size = x_size
+ num_rows = int(len(self.rows) // self.pict_per_row) + 1
+ self.thumbnail_world = pygame.Surface((screen_w-album_column_width-thick,self.xy_size*num_rows))
+ self.thumbnail_world.fill(background_color)
+ y_size = self.xy_size
+ x_size = self.xy_size
+
num_pict = len(self.rows)
- if num_pict > self.num_rows * self.pict_per_row:
- num_pict = self.num_rows * self.pict_per_row
- self.display_start_index = self.origin_row * self.pict_per_row
- #check for upper bound on rows
- if num_pict + self.display_start_index > len(self.rows):
- num_pict = len(self.rows)-self.display_start_index
- if self.last_selected:
- self.last_selected.unselect()
- self.last_selected = None
- screen.fill((255,255,255))
- _logger.debug('displaymany in range %s,%s'%(self.display_start_index, num_pict + self.display_start_index,))
- self.display_end_index = num_pict + self.display_start_index
- for i in range(self.display_start_index, self.display_end_index):
+ _logger.debug('display many thumbnails in range %s,%s'%(self.display_start_index, num_pict + self.display_start_index,))
+ for i in range(num_pict):
if not self.pict_dict.has_key(i):
- self.pict_dict[i] = DisplayOne(self.rows,self.db,self.picture_surface,i)
+ self.pict_dict[i] = OneThumbnail(self.rows,self.db,self.thumbnail_world,i)
row = i // self.pict_per_row
pos_x = (i % self.pict_per_row) * x_size
pos_y = (row - self.origin_row) * y_size
self.pict_dict[i].position(pos_x,pos_y)
#_logger.debug('calling paint with size(%s,%s) and position(%s,%s)'%(x_size,y_size,pos_x,pos_y,))
self.pict_dict[i].size(x_size,y_size)
- self.pict_dict[i].paint()
- screen.blit(self.picture_surface,(album_column_width,0))
- self.select_pict(self.selected_index)
-
+ self.pict_dict[i].paint_thumbnail()
+ if not self.pict_dict[i].from_database:
+ surf = self.thumbnail_panel(self.thumbnail_world)
+ screen.blit(surf,(album_column_width,0))
+ pygame.display.flip()
+ surf = self.thumbnail_panel(self.thumbnail_world)
+ screen.blit(surf,(album_column_width,0))
+ screen.blit(self.thumbnail_world,(album_column_width,0))
+ self.select_pict(self.thumb_index)
+
+ def thumbnail_panel(self,world):
+ #modeled after ezscrollbar example
+ scrollRect = pygame.Rect(screen_w - album_column_width - thick, 0, screen_w-album_column_width-sb_padding, screen_h)
+ excludes = ((0, 0), (screen_w-album_column_width-thick,screen_h)) # rect where sb update is a pass
+ group = pygame.sprite.RenderPlain()
+ self.sb = ScrollBar(
+ group,
+ world.get_height(),
+ scrollRect,
+ self.thumbnail_surface,
+ 1,
+ excludes,
+ 4,
+ False,
+ thick,
+ #(170,220,180),
+ (255,255,255),
+ (200,210,225),
+ (240,240,250),
+ (0,55,100))
+ self.sb.draw(self.thumbnail_surface)
+ self.thumbnail_surface.blit(world, (album_column_width,0),(self.sb.get_scrolled(),(screen_w-album_column_width-thick,screen_h)))
+ return self.thumbnail_surface
+
def clear(self):
- #self.picture_surface = pygame.Surface((self.screen_width,self.screen_height))
+ #self.thumbnail_world = pygame.Surface((self.screen_width,self.screen_height))
self.pict_dict = {}
- self.picture_surface.fill(background_color)
- screen.blit(self.picture_surface,(album_column_width,0))
+ if not self.thumbnail_world: return
+ self.thumbnail_world.fill(background_color)
+ screen.blit(self.thumbnail_world,(album_column_width,0))
+
+ def one_album_image(self,rows,index,selected=False,image_id=None):
+ """album name is title stored in groups.jobject_id where category='albums'
+ This should be called after display thumbnails because the thumbnail routine
+ counts the number of images which this routine displays to the user
+ """
+ surf = pygame.Surface((album_column_width,album_height))
+
+ if image_id:
+ self.jobject_id = image_id
+ if selected:
+ surf.fill(album_selected_color)
+ else:
+ surf.fill(album_background_color)
+ album_id = rows[index]['subcategory']
+ count = rows[index]['seq']
+ album = rows[index]['jobject_id']
+
+ if album_id == trash_id:
+ if count > 0:
+ fn = os.path.join('assets','trash_full.png')
+ else:
+ fn = os.path.join('assets','trash_empty.png')
+ else:
+ fn = os.path.join('assets','stack_background.png')
+ stack = pygame.image.load(fn)
+ frame = pygame.transform.scale(stack,album_size)
+ stack_image = self.put_image_on_stack(album_id)
+ if stack_image:
+ frame.blit(stack_image,album_location)
+ surf.blit(frame,(0,0))
+ font = pygame.font.Font(None,album_font_size)
+ text = font.render('%s %s'%(album,count),0,text_color)
+ text_rect = text.get_rect()
+ text_rect.midbottom = surf.get_rect().midbottom
+ surf.blit(text,text_rect)
+ _logger.debug('one album %s'%album)
+ return surf
+
+ def put_image_on_stack(self,album_id):
+ if album_id == journal_id:
+ sql = "select * from groups where category = '%s' order by seq asc"%(album_id)
+ else:
+ sql = "select * from groups where category = '%s' order by seq desc"%(album_id)
+ (rows,cur) = self.db.dbdo(sql)
+ if len(rows)>0:
+ jobject_id = str(rows[0]['jobject_id'])
+ else:
+ jobject_id = None
+ _logger.debug('failed to get jobject_id:%s for display on album side (stack).sql:%s'%(jobject_id,sql,))
+ return None
+ conn = self.db.get_connection()
+ cursor = conn.cursor()
+ cursor.execute('select * from data_cache.transforms where jobject_id = ?',(jobject_id,))
+ rows = cursor.fetchall()
+ if len(rows) > 0:
+ row = rows[0]
+ w = row['scaled_x']
+ h = row['scaled_y']
+ blob =row['thumb']
+ surf = pygame.image.frombuffer(blob,(w,h),'RGB')
+ transform_max = max(w,h)
+ #_logger.debug('transform rec max: %s request max: %s'%(transform_max,max_dim,))
+ ret = pygame.transform.scale(surf,album_aperature)
+ return ret
+
+ def set_top_image(self,jobject_id):
+ self.jobject_id = jobject_id
+
def click(self,x,y):
#first determine if the x,y pair are within the displayed thumbnails
thumb_index = int((y // self.xy_size) * self.pict_per_row + \
(x - album_column_width) // self.xy_size) + self.display_start_index
if thumb_index <= self.display_end_index:
- self.selected_index = thumb_index
- self.select_pict(self.selected_index)
+ self.thumb_index = thumb_index
+ self.select_pict(self.thumb_index)
def get_jobject_id_at_xy(self,x,y):
#first determine if the x,y pair are within the displayed thumbnails
thumb_index = int((y // self.xy_size) * self.pict_per_row + (x - album_column_width) // self.xy_size)
if thumb_index <= self.display_end_index:
return self.rows[thumb_index]['jobject_id']
- return None
-
+ return
+
def toggle(self,x,y):
if not self.large_displayed:
self.large_displayed = True
#restore the number of rows
self.num_rows_save = self.num_rows
self.num_rows = 1
- self.origin_row = self.selected_index // self.pict_per_row
- self.picture_surface.fill(background_color)
+ self.origin_row = self.thumb_index // self.pict_per_row
+ self.thumbnail_world.fill(background_color)
self.one_large()
else:
self.large_displayed = False
self.num_rows = self.num_rows_save
- self.picture_surface.fill(background_color)
+ self.thumbnail_world.fill(background_color)
#following call paints the thumnails
- self.paint(self.rows)
+ self.paint()
def one_large(self):
#clear the pictures
- #self.picture_surface.fill(background_color)
+ #self.thumbnail_world.fill(background_color)
#figure out what size to paint
y_size = screen_h - self.xy_size
x_pos = (screen_w - album_column_width - y_size) / 2
- disp_one = DisplayOne(self.rows,self.db,self.picture_surface,self.selected_index)
+ disp_one = OneThumbnail(self.rows,self.db,self.thumbnail_world,self.thumb_index)
disp_one.position(x_pos,self.xy_size)
disp_one.size(y_size,y_size)
- disp_one.paint()
+ disp_one.paint_thumbnail() #this one will be larger than a thumbnail
def screen_width(self,width):
self.screen_width = width
@@ -362,44 +467,44 @@ class DisplayMany():
self.last_selected = self.pict_dict[num].select()
if self.large_displayed:
self.one_large()
- screen.blit(self.picture_surface,(album_column_width,0))
+ screen.blit(self.thumbnail_world,(album_column_width,0))
def next(self):
- if self.selected_index < len(self.rows)-1:
- self.selected_index += 1
- #self.display_start_index = self.selected_index
- if self.selected_index >= (self.origin_row + self.num_rows) * self.pict_per_row:
+ if self.thumb_index < len(self.rows)-1:
+ self.thumb_index += 1
+ #self.display_start_index = self.thumb_index
+ if self.thumb_index >= (self.origin_row + self.num_rows) * self.pict_per_row:
self.origin_row += 1
- self.paint(self.rows,self.selected_index)
- self.select_pict(self.selected_index)
+ self.paint()
+ self.select_pict(self.thumb_index)
def next_row(self):
- if self.selected_index // self.pict_per_row < len(self.rows) // self.pict_per_row:
- self.selected_index += self.pict_per_row
- if self.selected_index > len(self.rows)-1:
- self.selected_index = len(self.rows)-1
- if self.selected_index >= (self.origin_row + self.num_rows) * self.pict_per_row:
+ if self.thumb_index // self.pict_per_row < len(self.rows) // self.pict_per_row:
+ self.thumb_index += self.pict_per_row
+ if self.thumb_index > len(self.rows)-1:
+ self.thumb_index = len(self.rows)-1
+ if self.thumb_index >= (self.origin_row + self.num_rows) * self.pict_per_row:
self.origin_row += 1
- self.paint(self.rows,self.selected_index)
+ self.paint()
self.last_selected = None
- self.select_pict(self.selected_index)
+ self.select_pict(self.thumb_index)
def prev(self):
- if self.selected_index > 0:
- self.selected_index -= 1
- if self.selected_index < (self.origin_row) * self.pict_per_row:
+ if self.thumb_index > 0:
+ self.thumb_index -= 1
+ if self.thumb_index < (self.origin_row) * self.pict_per_row:
self.origin_row -= 1
- self.paint(self.rows, self.selected_index)
- self.select_pict(self.selected_index)
+ self.paint()
+ self.select_pict(self.thumb_index)
def prev_row(self):
- if self.selected_index // self.pict_per_row > 0:
- self.selected_index -= self.pict_per_row
- if self.selected_index // self.pict_per_row < self.origin_row:
+ if self.thumb_index // self.pict_per_row > 0:
+ self.thumb_index -= self.pict_per_row
+ if self.thumb_index // self.pict_per_row < self.origin_row:
self.origin_row -= 1
- self.paint(self.rows,self.selected_index)
- self.select_pict(self.selected_index)
+ self.paint()
+ self.select_pict(self.thumb_index)
class DisplayAlbums():
@@ -407,27 +512,33 @@ class DisplayAlbums():
journal_id = '20100521T10:42'
trash_id = '20100521T11:40'
predefined_albums = [(journal_id,_('Journal')),(trash_id,_('Trash')),] #_('Duplicates'),_('Last Year'),_('Last Month'),]
- journal_name = _('Journal')
def __init__(self,db,activity):
+ """
global album_column_width
global thick
global background_color
global album_background_color
global album_selected_color
+ """
+
+ #why both _rows and _objects?
+ # rows is returned from a select in seq order
+ # objects is storage for local context and paint yourself functionality
+ # objects dictionary is accessed via album_id datetime stamp
self.album_rows = []
+ self.album_objects = {}
self.album_column_width = album_column_width
self.db = db #pointer to the open database
self._activity = activity #pointer to the top level activity
self.accumulation_target,id = self.db.get_last_album()
- self.disp_many = DisplayMany(self.db)
+ #self.disp_many = DisplayMany(self.db)
+ self.default_name = _("Unnamed Photos")
self.num_of_last_rolls = 5
- self.text_color = (0,0,200)
self.selected_color = album_selected_color
self.background_color = album_background_color
- self.album_height = 190
- self.album_font_size = 30
- self.up_down_jump = 5
- self.selected_index = 0
+ self.album_height = album_height
+ self.album_index = 0
+ self.selected_album_id = journal_id
#figure out how many albums can be displayed
if screen_h == 0:
_logger.debug('screen height not initialized')
@@ -438,7 +549,6 @@ class DisplayAlbums():
self.album_surface.fill(background_color)
#if the albums table is empty, populate it from the journal, and initialize
- self.conn = self.db.get_connection()
sql = "select * from groups"
rows,cur = self.db.dbdo(sql)
i = 0
@@ -448,20 +558,8 @@ class DisplayAlbums():
sql = """insert into groups (category,subcategory,jobject_id,seq) \
values ('%s','%s','%s',%s)"""%('albums',album_tup[0],album_tup[1],i,)
self.db.dbtry(sql)
- i += 1
+ i += 20
self.db.commit()
- """
- #following block is just to debug the situation where there are more albums than fit in one column
- #this wont be necessary if I use scroll bar
- if len(rows) < 15: #it is not long enough
- conn = self.db.get_connection()
- cursor = conn.cursor()
- for j in range(15):
- album = 'Camera Roll %s'%j
- sql = "insert into groups (category,subcategory,jobject_id,seq) values ('%s','%s','%s',%s)"%('albums',album,'',i,)
- cursor.execute(sql)
- self.db.commit()
- """
#then put the journal picutres into the journal album
rows, cur = self.db.dbdo('select * from picture')
i = 0
@@ -472,25 +570,28 @@ class DisplayAlbums():
sql = """insert into groups (category,subcategory,jobject_id,seq) \
values ('%s','%s','%s',%s)"""% (self.predefined_albums[0][0],self.predefined_albums[0][1],row['jobject_id'],i,)
cursor.execute(sql)
- i += 1
+ i += 20
conn.commit()
+ #initialize the list of album objects from the database
+ album_rows = self.db.get_albums()
+ _logger.debug('initializing albums. %s found'%len(album_rows))
+ for row in album_rows:
+ id = str(row['subcategory'])
+ self.album_objects[id] = OneAlbum(self.db,id)
#the initial screen will show the contents of the journal
self.display_journal()
- def display_thumbnails(self,album):
+ def display_thumbnails(self,album_id):
"""uses the album (a datetime str) as value for category in table groups
to display thumbnails on the right side of screen"""
- sql = """select pict.*, grp.* from picture as pict, groups as grp \
- where grp.category = ? and grp.jobject_id = pict.jobject_id order by create_date desc"""
- cursor = self.conn.cursor()
- cursor.execute(sql,(str(album),))
- rows = cursor.fetchall()
- _logger.debug('album to display: %s. Number of pictures found: %s'%(album,len(rows),))
- self.db.set_album_count(album,len(rows))
- self.disp_many.clear()
- self.disp_many.last_selected = None
- self.disp_many.paint(rows)
+ self.album_objects[self.selected_album_id].clear()
+ self.album_objects[self.selected_album_id].last_selected = None
+ alb_object = self.album_objects.get(self.selected_album_id)
+ if alb_object:
+ alb_object.paint()
+ else:
+ _logger.debug('display_thumbnails did not find %s'%album_id)
def display_journal(self):
self.display_thumbnails(self.journal_id)
@@ -499,48 +600,10 @@ class DisplayAlbums():
global album_background_color
self.album_surface.fill(album_background_color)
- def can_go_up(self):
- if album_display_start > 0:
- return True
- return False
-
- def can_go_down(self):
- if album_display_start < self.number_of_albums - self.up_down_jump:
- return True
- return False
- def one_album(self,rows,index,selected=False):
- """album is title stored in config.jobject_id where category='albums'"""
- surf = pygame.Surface((self.album_column_width,self.album_height))
-
- if selected:
- surf.fill(self.selected_color)
- else:
- surf.fill(self.background_color)
- album_id = rows[index]['subcategory']
- count = rows[index]['seq']
- album = rows[index]['jobject_id']
-
- if album_id == self.trash_id:
- if count > 0:
- fn = os.path.join('assets','trash_full.png')
- else:
- fn = os.path.join('assets','trash_empty.png')
- else:
- fn = os.path.join('assets','stack_background.png')
- stack = pygame.image.load(fn)
- frame = pygame.transform.scale(stack,(180,155))
- surf.blit(frame,(0,0))
- font = pygame.font.Font(None,self.album_font_size)
- text = font.render('%s %s'%(album,count),0,self.text_color)
- text_rect = text.get_rect()
- text_rect.midbottom = surf.get_rect().midbottom
- surf.blit(text,text_rect)
- _logger.debug('one album %s'%album)
- return surf
-
def album_panel(self,world):
+ """modeled after ezscrollbar example"""
global album_column_width
global screen_h
global background_color
@@ -548,7 +611,7 @@ class DisplayAlbums():
global album_selected_color
global thick
global sb_padding
- thick = 15
+ #thick = 15
scrollRect = pygame.Rect(album_column_width - thick, 0, album_column_width-sb_padding, screen_h)
excludes = ((0, 0), (album_column_width-thick,screen_h)) # rect where sb update is a pass
group = pygame.sprite.RenderPlain()
@@ -572,25 +635,26 @@ class DisplayAlbums():
return self.album_surface
def paint_albums(self):
- global album_display_start
global album_column_width
screen_row = 0
- if not self.album_rows:
- self.refresh_album_rows()
+ self.refresh_album_rows()
if len(self.album_rows) > 0:
self.clear_albums()
self.world = pygame.Surface((album_column_width, 8 * self.album_height)) #len(self.album_rows) * self.album_height))
self.world.fill(album_background_color)
- #the logic for albums is very similar to the paint many thumbnails above
num_albums = len(self.album_rows)
for row_index in range(num_albums ):
- selected = (row_index == self.selected_index)
- self.world.blit(self.one_album(self.album_rows, row_index, selected),(0,screen_row * self.album_height))
+ selected = (row_index == self.album_index)
+ album_id = self.album_rows[row_index]['subcategory']
+ album_object = self.album_objects[album_id]
+ album_image = album_object.one_album_image(self.album_rows, row_index, selected)
+ self.world.blit(album_image,(0,screen_row * self.album_height))
screen_row += 1
surf = self.album_panel(self.world)
- screen.blit(surf, (0,0))
-
+ screen.blit(surf, (0,0))
+ pygame.display.flip()
+
def refresh_album_rows(self):
sql = "select * from groups where category = 'albums' order by id"
rows,cur = self.db.dbdo(sql)
@@ -600,17 +664,24 @@ class DisplayAlbums():
def click(self,x,y):
"""select the pointed to item"""
- global album_display_start
#get the y index
- y_index = y // self.album_height
- self.selected_index = y_index + album_display_start
+ sb_x,sb_y = self.sb.get_scrolled()
+ y_index = (y + sb_y) // self.album_height
+ self.album_index = int(y_index)
+ self.accumulation_target = self.album_index
+ self.refresh_album_rows()
+ if self.album_index >= len(self.album_rows) :
+ return None
+
#now change the thumbnail side of the screen
try:
- album_name = self.album_rows[int(self.selected_index)]['subcategory']
- album_title = self.album_rows[int(self.selected_index)]['jobject_id']
+ album_name = self.album_rows[int(self.album_index)]['subcategory']
+ album_title = self.album_rows[int(self.album_index)]['jobject_id']
except Exception,e:
album_name = journal_id #the journal
_logger.debug('exception fetching thumbnails %s'%e)
+ return
+ self.selected_album_id = album_name
_logger.debug('now display the thumbnails with the album identifier %s'%album_name)
self._activity.activity_toolbar.title.set_text(album_title)
self.display_thumbnails(album_name)
@@ -626,48 +697,75 @@ class DisplayAlbums():
--seq = modified as the order of the pictures is modified
(seq = count of albums when category='albums')
"""
- if not name: name = _("Unnamed Photos")
+ if not name: name = self.default_name
self.accumulation_target,id = self.db.get_last_album()
+ if not self.album_objects.has_key(self.accumulation_target):
+ self.accumulation_target = None
_logger.debug('last album id was %s and id was %s'%(self.accumulation_target,id))
if not self.accumulation_target:
- self.create_new_album()
+ self.create_new_album(name)
else: #see if this is a request to change name
if jobject_id == '':
- jobject_id = self.accumulation_target
+ jobject_id = self.accumulation_target
self.db.add_image_to_album(self.accumulation_target, jobject_id)
+ self.album_objects[self.accumulation_target].set_top_image(self.accumulation_target)
#self.display_thumbnails(self.accumulation_target)
- self.refresh_album_rows()
self.paint_albums()
- def create_new_album(self):
- self.accumulation_target = str(datetime.datetime.today())
- _logger.debug('new album is:%s'%self.accumulation_target)
- self.db.create_update_album(self.accumulation_target,name)
+ def set_name(self,name):
+ self.db.create_update_album(self.album_rows[self.album_index]['subcategory'],name)
+ self.paint_albums()
+ pygame.display.flip()
+
+
+ def create_new_album(self,name):
+ if not name: name = self.default_name
+ self.accumulation_target = str(datetime.datetime.today())
+ _logger.debug('new album is:%s'%self.accumulation_target)
+ self.db.create_update_album(self.accumulation_target,name)
+ self.album_objects[self.accumulation_target] = (OneAlbum(self.db,self.accumulation_target))
+ #save off the unique id(timestamp)as a continuing target
+ self.db.set_last_album(self.accumulation_target)
+ self.paint_albums()
- #save off the unique id(timestamp)as a continuing target
- self.db.set_last_album(self.accumulation_target)
+ def delete_album(self,album_id):
+ _logger.debug('delete album action routine. deleting id(timestamp):%s'%album_id)
+ """ need to delete the album pointer, the album records, and album object"""
+ if self.album_objects.has_key(album_id):
+ del self.album_objects[album_id]
+ conn = self.db.get_connection()
+ cursor = conn.cursor()
+ cursor.execute('delete from groups where subcategory = ?',(str(album_id),))
+ cursor.execute('delete from groups where category = ?',(str(album_id),))
+ conn.commit()
+ self.album_index = 0
+ self.selected_album_id = self.journal_id
+ self.display_thumbnails(self.selected_album_id)
+ self.paint_albums()
+
def change_name_of_current_album(self,name):
"""create a 'current' album (if necessary) and name it"""
self.add_to_current_album('',name)
def get_current_album_identifier(self):
- return self.album_rows[self.selected_index]['subcategory']
+ return str(self.album_rows[self.album_index]['subcategory'])
def get_current_album_name(self):
- return self.album_rows[self.selected_index]['jobject_id']
+ return str(self.album_rows[self.album_index]['jobject_id'])
def get_album_index_at_xy(self,x,y):
if x > album_column_width - thick: return None
index = y // self.album_height
- if index > len(self.album_rows): return None
return int(index)
def add_to_album_at_xy(self,x,y):
- jobject_id = self.disp_many.get_jobject_id_at_xy(x,y)
+ jobject_id = self.album_objects[self.selected_album_id].get_jobject_id_at_xy(x,y)
if jobject_id:
self.add_to_current_album(jobject_id)
+ else:
+ _logger.debug('could not find jobject_id in add_to_aqlbum_at_xy')
def start_grab(self,x,y):
self.start_grab_x = x
@@ -678,15 +776,38 @@ class DisplayAlbums():
def drop_image(self, img_x,img_y,album_x, album_y):
self._activity.window.set_cursor(None)
index = self.get_album_index_at_xy(album_x, album_y)
- jobject_id = self.disp_many.get_jobject_id_at_xy(img_x,img_y)
+ jobject_id = self.album_objects[self.selected_album_id].get_jobject_id_at_xy(img_x,img_y)
if not index or not jobject_id: return
#if index is larger than max, we want a new album
- if index > len(self.album_rows):
- self.create_new_album()
+ _logger.debug('index:%s length of rows:%s jobject_id %s'%(index,len(self.album_rows),jobject_id,))
+ if index > len(self.album_rows)-1:
+ self.create_new_album(self.default_name)
+ self.album_objects[self.accumulation_target].set_top_image(jobject_id)
else:
self.db.add_image_to_album(self.album_rows[index]['subcategory'], jobject_id)
+ #self.display_thumbnails(self.accumulation_target)
+ self.refresh_album_rows()
+ self.paint_albums()
+
+ def toggle(self,x,y):
+ """change the number of albums displayed"""
+ pass
+
+
+ def roll_over(self,x,y, in_drag=False):
+ """indicate willingness to be selected"""
+ pass
+
+ def do_drag_up(self,x,y):
+ """add the dragged item to the selected album"""
+ pass
+
+
##################### ALERT ROUTINES ##################################
+class Utilities():
+ def __init__(self,activity):
+ self._activity = activity
def alert(self,msg,title=None):
alert = NotifyAlert(0)
@@ -699,7 +820,8 @@ class DisplayAlbums():
def no_file_cb(self,alert,response_id):
self._activity.remove_alert(alert)
-
+ pygame.display.flip
+
from sugar.graphics.alert import ConfirmationAlert
def confirmation_alert(self,msg,title=None,confirmation_cb = None):
@@ -708,7 +830,7 @@ class DisplayAlbums():
alert.props.msg = msg
alert.callback_function = confirmation_cb
alert.connect('response', self._alert_response_cb)
- self.add_alert(alert)
+ self._activity.add_alert(alert)
return alert
#### Method: _alert_response_cb, called when an alert object throws a
@@ -717,30 +839,12 @@ class DisplayAlbums():
#remove the alert from the screen, since either a response button
#was clicked or there was a timeout
this_alert = alert #keep a reference to it
- self.remove_alert(alert)
+ self._activity.remove_alert(alert)
+ pygame.display.flip()
#Do any work that is specific to the type of button clicked.
if response_id is gtk.RESPONSE_OK and this_alert.callback_function != None:
this_alert.callback_function (this_alert, response_id)
- def toggle(self,x,y):
- """change the number of albums displayed"""
- pass
-
-
- def roll_over(self,x,y, in_drag=False):
- """indicate willingness to be selected"""
- pass
-
- def do_drag_up(self,x,y):
- """add the dragged item to the selected album"""
- pass
-
- def add_new_album(self,name):
- pass
-
- def delete_album(self,x,y):
- pass
-
class Application():
#how far does a drag need to be not to be ignored?
@@ -761,8 +865,15 @@ class Application():
self.file_tree.copy_tree_to_ds(source)
number_of_pictures = self.ds_sql.scan_images()
if number_of_pictures < 10:
- _logger.debug('failed to initalize the datastore with at least 10 pictures')
-
+ _logger.debug('failed to initalize the datastore with at least 10 pictures')
+
+ def change_album_name(self,name):
+ if self.album_collection:
+ self.album_collection.set_name(name)
+
+ def pygame_display(self):
+ pygame.display.flip()
+
def run(self):
global screen
global in_click_delay
@@ -773,7 +884,7 @@ class Application():
if True:
#moved the database functionality here because of sync problems with journal
if not self._activity.DbAccess_object: #we need to wait for the read-file to finish
- Timer(25.0, self.end_db_delay, ()).start()
+ Timer(5.0, self.end_db_delay, ()).start()
in_db_wait = True
while not self._activity.DbAccess_object and in_db_wait:
gtk.main_iteration()
@@ -818,14 +929,15 @@ class Application():
screen.fill((255,255,255)) #255 for white
x = 0
pygame.display.flip()
-
+ self.util = Utilities(self._activity)
+ #self.util.alert("this is a test")
#if the picture table is empty, populate it from the journal, and initialize
if ds_count < 10:
self.first_run_setup()
- self.albums = DisplayAlbums(self.db, self._activity)
- self.albums.paint_albums()
+ self.album_collection = DisplayAlbums(self.db, self._activity)
+ self.album_collection.paint_albums()
# Flip Display
pygame.display.flip()
@@ -849,16 +961,16 @@ class Application():
running = False
pygame.quit()
elif event.key == K_LEFT:
- self.albums.disp_many.prev()
+ self.album_collection.album_objects[self.album_collection.selected_album_id].prev()
pygame.display.flip()
elif event.key == K_RIGHT:
- self.albums.disp_many.next()
+ self.album_collection.album_objects[self.album_collection.selected_album_id].next()
pygame.display.flip()
elif event.key == K_UP:
- self.albums.disp_many.prev_row()
+ self.album_collection.album_objects[self.album_collection.selected_album_id].prev_row()
pygame.display.flip()
elif event.key == K_DOWN:
- self.albums.disp_many.next_row()
+ self.album_collection.album_objects[self.album_collection.selected_album_id].next_row()
pygame.display.flip()
#mouse events
@@ -881,12 +993,12 @@ class Application():
pygame.display.set_mode(event.size, pygame.RESIZABLE)
if x < album_column_width:
- self.albums.sb.update(event)
- changes = self.albums.sb.draw(self.albums.album_surface)
+ self.album_collection.sb.update(event)
+ changes = self.album_collection.sb.draw(self.album_collection.album_surface)
if len(changes) > 0:
- changes.append(self.albums.album_surface.blit(self.albums.world, (0,0),
- (self.albums.sb.get_scrolled(),(album_column_width-thick,screen_h))))
- screen.blit(self.albums.album_surface,(0,0))
+ changes.append(self.album_collection.album_surface.blit(self.album_collection.world, (0,0),
+ (self.album_collection.sb.get_scrolled(),(album_column_width-thick,screen_h))))
+ screen.blit(self.album_collection.album_surface,(0,0))
pygame.display.update(changes)
@@ -915,7 +1027,7 @@ class Application():
return
print('drop at %s,%s'%(x,y,))
if in_drag and self.last_l:
- self.albums.drop_image(self.drag_start_x,self.drag_start_y,x,y)
+ self.album_collection.drop_image(self.drag_start_x,self.drag_start_y,x,y)
pygame.display.flip()
def process_mouse_click(self,event):
@@ -923,21 +1035,24 @@ class Application():
l,m,r = pygame.mouse.get_pressed()
print('mouse single click')
if x < album_column_width -thick:
- scroll_x,scroll_y = self.albums.sb.get_scrolled()
- self.albums.click(x,y + scroll_y)
+ scroll_x,scroll_y = self.album_collection.sb.get_scrolled()
+ rtn_val = self.album_collection.click(x,y + scroll_y)
+ if not rtn_val:
+ #create a new album
+ pass
elif x > album_column_width:
if l:
- self.albums.disp_many.click(x,y)
+ self.album_collection.album_objects[self.album_collection.selected_album_id].click(x,y)
elif r:
self.in_grab = True
- self.albums.start_grab(x,y)
+ self.album_collection.start_grab(x,y)
pygame.display.flip()
def process_mouse_double_click(self,event):
x,y = event.pos
print('double click')
if x > album_column_width:
- self.albums.add_to_album_at_xy(x,y)
+ self.album_collection.add_to_album_at_xy(x,y)
pygame.display.flip()
def mouse_timer_running(self):
diff --git a/photo_toolbar.py b/photo_toolbar.py
index 16fec38..3903c3d 100644
--- a/photo_toolbar.py
+++ b/photo_toolbar.py
@@ -47,7 +47,7 @@ class ActivityToolbar(gtk.Toolbar):
"""
#if activity.metadata:
if True:
- label = gtk.Label(_('New Album Name:'))
+ label = gtk.Label(_('New Album Name: '))
label.show()
self._add_widget(label)
@@ -56,7 +56,8 @@ class ActivityToolbar(gtk.Toolbar):
if activity.metadata:
self.title.set_text(activity.metadata['title'])
#activity.metadata.connect('updated', self.__jobject_updated_cb)
- #self.title.connect('changed', self.__title_changed_cb)
+ self.title.connect('changed', self.__title_changed_cb)
+ self.title.connect('activate', self.__update_title_cb)
self._add_widget(self.title)
self.add_album = ToolButton('list-add')
@@ -168,18 +169,20 @@ class ActivityToolbar(gtk.Toolbar):
self._update_title_sid = gobject.timeout_add_seconds(
1, self.__update_title_cb)
- def __update_title_cb(self):
+ def __update_title_cb(self, entry=None):
title = self.title.get_text()
self._activity.metadata['title'] = title
self._activity.metadata['title_set_by_user'] = '1'
- self._activity.save()
-
+ self._activity.game.change_album_name(title)
+ #self._activity.save()
+ """
shared_activity = self._activity.get_shared_activity()
if shared_activity:
shared_activity.props.name = title
-
+ """
self._update_title_sid = None
+
return False
def _add_widget(self, widget, expand=False):
diff --git a/sources.py b/sources.py
index 674e088..606d2cc 100644
--- a/sources.py
+++ b/sources.py
@@ -78,24 +78,28 @@ class Datastore_SQLite():
return rtn
def check_for_recent_images(self):
- """scans the journal for pictures that are not in database, records object_id if found"""
- find_spec = {'mime_type':['image/png','image/jpg','image/tif','image/bmp','image/gif']}
- (results,count) = datastore.find(find_spec)
- _logger.debug('directed image datastore found:%s'%count)
+ """scans the journal for pictures that are not in database, records object_id if found.
+ stops checking when the first image is found that is already in the database.
+ """
+ mime_list = self.db.get_mime_list()
+ (results,count) = datastore.find({})
+ _logger.debug('Journal/datastore entries found:%s'%count)
added = 0
a_row_found = False
cursor = self.db.get_connection().cursor()
for ds in results:
#at least for now assume that the newest images are returned first
if not a_row_found:
- cursor.execute('select * from picture where jobject_id = ?',(str(ds.object_id),))
- rows = cursor.fetchall()
- if len(rows) == 0:
- #may need to add date entered into ds (create date could be confusing)
- self.db.put_ds_into_picture(ds.object_id)
- added += 1
- else: #assume that pictures are returned in last in first out order
- a_row_found = True
+ dict = ds.get_metadata().get_dictionary()
+ if dict["mime_type"] in mime_list:
+ cursor.execute('select * from picture where jobject_id = ?',(str(ds.object_id),))
+ rows = cursor.fetchall()
+ if len(rows) == 0:
+ #may need to add date entered into ds (create date could be confusing)
+ self.db.put_ds_into_picture(ds.object_id)
+ added += 1
+ else: #assume that pictures are returned in last in first out order
+ a_row_found = True
ds.destroy()
_logger.debug('added %s datastore object ids from datastore to picture'%added)
return (count,added,)
diff --git a/sugargame/canvas.py b/sugargame/canvas.py
index abaa0eb..e38508d 100644
--- a/sugargame/canvas.py
+++ b/sugargame/canvas.py
@@ -46,25 +46,14 @@ class PygameCanvas(gtk.EventBox):
translator.hook_pygame()
# Restore the default cursor.
- from threading import Timer
- self.window_timer = False
- Timer(10.0, self.end_window_delay, ()).start()
- while not self.window_timer:
- gtk.main_iteration()
- if hasattr(self._socket,'get_window'): # or hasattr(self._socket.get_window(),'realized'):
- break
- if self.window_timer:
- _logger.debug('gtk window not visible through socket')
- exit()
- self._socket.get_window().set_cursor(None)
-
+ #self._socket.get_window().set_cursor(None)
+ window = self._socket.get_parent_window()
+ window.set_cursor(None)
+
# Run the Pygame main loop.
main_fn()
return False
- def end_window_delay(self):
- self.window_timer = True
-
def get_pygame_widget(self):
return self._socket
diff --git a/xophoto.sqlite.template b/xophoto.sqlite.template
index b66fb47..11c5721 100644
--- a/xophoto.sqlite.template
+++ b/xophoto.sqlite.template
Binary files differ
diff --git a/xophotoactivity.py b/xophotoactivity.py
index f117e0d..0f74397 100644
--- a/xophotoactivity.py
+++ b/xophotoactivity.py
@@ -46,6 +46,7 @@ from threading import Timer
from subprocess import Popen, PIPE
import display
+from display import *
import photo_toolbar
from sources import *
from sinks import *
@@ -76,6 +77,8 @@ class XoPhotoActivity(activity.Activity):
self.window_realized = False
self.game = None
self.kept_once = False
+ self.util = Utilities(self)
+
if handle and handle.object_id and handle.object_id != '' and not self.use_db_template:
_logger.debug('At activity startup, handle.object_id is %s'%handle.object_id)
@@ -172,19 +175,23 @@ class XoPhotoActivity(activity.Activity):
def activity_toolbar_add_album_cb(self,album_name):
- self.game.albums.change_name_of_current_album(album_name )
+ self.game.album_collection.create_new_album(None)
def activity_toolbar_delete_album_cb(self):
- album = self.game.albums.get_current_album_name()
- self.game.albums.alert('Are you sure you want to delete %s?'%album)
+ album = self.game.album_collection.get_current_album_name()
+ album_id = self.game.album_collection.get_current_album_identifier()
+ if album_id in [journal_id,trash_id]:
+ self.util.alert(_('Drag pictures to the Trash, and then empty the trash'),\
+ _('Warning! Journal and Trash cannot be deleted'))
+ return
+ self.util.confirmation_alert(_('Are you sure you want to delete %s?')%album,\
+ _('Caution'),self.confirm_delete_album_cb)
- def confirm_delete_album_cb(self,response):
- album = self.game.albums.get_current_album_identifier()
-
- if not response in (gtk.RESPONSE_OK):return
- sql = 'delete from groups where subcategory = ?'
- cursor = self.game.db.conn.cursor()
- cursor.execute(sql,())
+ def confirm_delete_album_cb(self,alert,response):
+ album_id = self.game.album_collection.get_current_album_identifier()
+ _logger.debug('about to delete album with identifier:%s'%album_id)
+ if not response == gtk.RESPONSE_OK:return
+ self.game.album_collection.delete_album(album_id)
def command_line(self,cmd, alert_error=False):
_logger.debug('command_line cmd:%s'%cmd)
@@ -192,7 +199,7 @@ class XoPhotoActivity(activity.Activity):
output = p1.communicate()
if p1.returncode != 0 :
_logger.debug('error returned from shell command: %s was %s'%(cmd,output[0]))
- if alert_error: self.alert(_('%s Command returned non zero\n'%cmd+output[0]))
+ if alert_error: self.util.alert(_('%s Command returned non zero\n'%cmd+output[0]))
return output[0],p1.returncode
@@ -201,6 +208,12 @@ class XoPhotoActivity(activity.Activity):
dict = self.get_metadata()
#set a flag to copy the template
self.interactive_close = True
+
+ #compact the database
+ conn = self.DbAccess_object.get_connection()
+ cursor = conn.cursor()
+ cursor.execute('vacuum')
+
self.save()
db_path = os.path.join(os.environ['SUGAR_ACTIVITY_ROOT'],'data','xophoto.sqlite')
@@ -211,33 +224,40 @@ class XoPhotoActivity(activity.Activity):
exit()
source = db_path
ds = datastore.create()
- ds.metadata['title'] = _('Empty Photo Stack')
+ ds.metadata['title'] = _('New Photo Stack')
ds.metadata['activity_id'] = dict.get('activity_id')
ds.metadata['activity'] = 'org.laptop.XoPhoto'
ds.metadata['mime_type'] = 'application/binary'
dest = os.path.join(os.environ['SUGAR_ACTIVITY_ROOT'],'instance','xophoto.sqlite')
+
+ #albums are stored in the groups table, so start fresh
+ conn = self.DbAccess_object.get_connection()
+ cursor = conn.cursor()
+ cursor.execute("delete from groups")
+ conn.commit()
+
shutil.copyfile(source,dest)
ds.set_file_path(dest)
datastore.write(ds,transfer_ownership=True)
ds.destroy()
- if dict.get('dbcorrupted','False') == 'False' and not self.kept_once:
- #try to save all the time/computation involved in making thumbnails
- backup_db = os.path.join(os.environ['SUGAR_ACTIVITY_ROOT'],'data','xophoto_back.sqlite')
- if os.path.isfile(backup_db):
- try:
- conn = self.DbAccess_object.get_connection()
- cursor = conn.cursor()
- cursor.execute("attach '%s' as thumbs"%backup_db)
- sql = 'insert into picture select * from thumbs.picture'
- cursor.execute(sql)
- sql = 'insert into transforms select * from thumbs.transforms'
- cursor.execute(sql)
- conn.commit()
- except Exception,e:
- _logger.debug('database exception %s'%e)
- raise e
- self.kept_once = True
- self.game.albums.alert(_('Click KEEP again for a completely new Database.'),_('New Database initialized from the Current Database.'))
+
+ #check the thumbnails
+ cursor.execute('pragma data_cache.quick_check')
+ rows = cursor.fetchall()
+ if len(rows) == 1 and str(rows[0]) == 'ok':
+ #thumbnails database is ok
+ _logger.debug('thumbnail database passes quick_check')
+ else:
+ #need to start over with a new template and regenerate the thumbnails
+ _logger.debug('swapping in template for transforms (thumbnail) database')
+
+ try:
+ source = os.path.join(os.getcwd(),'data_cache.sqlite.template')
+ local_path = os.path.join(os.environ['SUGAR_ACTIVITY_ROOT'],'data','data_cache.sqlite')
+ shutil.copy(source,local_path)
+ except Exception,e:
+ _logger.debug('data_cache template failed to copy error:%s'%e)
+ exit()
def edit_toolbar_doimport_cb(self, view_toolbar):
if not self.file_tree:
@@ -284,6 +304,7 @@ class XoPhotoActivity(activity.Activity):
_logger.debug('started read_file %s. make_file flag %s'%(file_path,self.make_jobject))
if self.make_jobject: #make jobject is flag signifying that we are not resuming activity
_logger.debug(' copied template rather than resuming')
+
#This is a new invocation, copy the sqlite database to the data directory
source = os.path.join(os.getcwd(),'xophoto.sqlite.template')
dest = os.path.join(os.environ['SUGAR_ACTIVITY_ROOT'],'data','xophoto.sqlite')
@@ -292,6 +313,16 @@ class XoPhotoActivity(activity.Activity):
except Exception,e:
_logger.debug('database template failed to copy error:%s'%e)
exit()
+
+ #now do the same for the thumbnails if they don't already exist
+ source = os.path.join(os.getcwd(),'data_cache.sqlite.template')
+ dest = os.path.join(os.environ['SUGAR_ACTIVITY_ROOT'],'data','data_cache.sqlite')
+ if not os.path.isfile(dest):
+ try:
+ shutil.copy(source,dest)
+ except Exception,e:
+ _logger.debug('thumbnail database template failed to copy error:%s'%e)
+ exit()
else:
if self.DbAccess_object: #if the database is open don't overwrite and confuse it
_logger.debug('in read-file, db was already open')