changeset 180:fdb961f27ae9

Primitivus: file sending and progress management - added "send file" in one2one chat's menu - new progress widget which is linked to the notification bar - the notification bar show the average progress of all the current progress bars, and is used to show progress details - if present, pudb is used for debugging (can continue without breaking terminal's setting)
author Goffi <goffi@goffi.org>
date Mon, 16 Aug 2010 21:16:43 +0800
parents d6c0c5dca9b9
children a566f654929e
files frontends/primitivus/chat.py frontends/primitivus/primitivus frontends/primitivus/progress.py frontends/wix/main_window.py
diffstat 4 files changed, 136 insertions(+), 13 deletions(-) [+]
line wrap: on
line diff
--- a/frontends/primitivus/chat.py	Mon Aug 16 21:11:00 2010 +0800
+++ b/frontends/primitivus/chat.py	Mon Aug 16 21:16:43 2010 +0800
@@ -255,6 +255,12 @@
             self.host.bridge.tarotGameCreate(self.id, list(self.occupants), self.host.profile)
     
     def onSendFileRequest(self, menu):
-        dialog = FileDialog()
+        dialog = FileDialog(ok_cb=self.onFileSelected, cancel_cb=self.host.removePopUp)
         self.host.showPopUp(dialog, 80, 80)
 
+    #MISC EVENTS#
+    def onFileSelected(self, filepath):
+        self.host.removePopUp()
+        full_jid = self.host.CM.get_full(self.target)
+        id = self.host.bridge.sendFile(full_jid, filepath)
+        self.host.addProgress(id,filepath) 
--- a/frontends/primitivus/primitivus	Mon Aug 16 21:11:00 2010 +0800
+++ b/frontends/primitivus/primitivus	Mon Aug 16 21:16:43 2010 +0800
@@ -30,12 +30,12 @@
 from chat import Chat
 from gateways import GatewaysManager
 import custom_widgets
-import pdb
 import logging
 from logging import debug, info, error
 import sys, os
 from tools.jid  import JID
 from xmlui import XMLUI
+from progress import Progress
 
 
 ### logging configuration FIXME: put this elsewhere ###
@@ -59,6 +59,7 @@
                  ('menuitem', 'light gray,bold', 'dark red'),
                  ('menuitem_focus', 'light gray,bold', 'dark green'),
                  ('notifs', 'black,bold', 'yellow'),
+                 ('notifs_focus', 'dark red', 'yellow'),
                  ('card_neutral', 'dark gray', 'white', 'standout,underline'),
                  ('card_neutral_selected', 'dark gray', 'dark green', 'standout,underline'),
                  ('card_special', 'brown', 'white', 'standout,underline'),
@@ -67,6 +68,12 @@
                  ('card_red_selected', 'dark red', 'dark green', 'standout,underline'),
                  ('card_black', 'black', 'white', 'standout,underline'),
                  ('card_black_selected', 'black', 'dark green', 'standout,underline'),
+                 ('directory', 'dark cyan, bold', 'default'),
+                 ('directory_focus', 'dark cyan, bold', 'dark green'),
+                 ('separator', 'brown', 'default'),
+                 ('warning', 'light red', 'default'),
+                 ('progress_normal', 'default', 'black'),
+                 ('progress_complete', 'default', 'light red'),
                  ]
             
 class ChatList(QuickChatList):
@@ -92,16 +99,22 @@
         self.chat_wins=ChatList(self)
         self.notBar = custom_widgets.NotificationBar()
         urwid.connect_signal(self.notBar,'change',self.onNotification)
+        self.progress_wid = Progress(self)
+        urwid.connect_signal(self.notBar.progress,'click',lambda x:self.addWindow(self.progress_wid))
         self.__saved_overlay = None
     
     def debug(self):
-        """convenient method to reset screen and launch pdb"""
-        import os
-        os.system('reset')
-        print 'Entered debug mode'
-        pdb.set_trace()
+        """convenient method to reset screen and launch p(u)db"""
+        try:
+            import pudb
+            pudb.set_trace()
+        except:
+            import os,pdb
+            os.system('reset')
+            print 'Entered debug mode'
+            pdb.set_trace()
 
-    def write_log(self, log, file_name='/tmp/primitivus_log'):
+    def writeLog(self, log, file_name='/tmp/primitivus_log'):
         """method to write log in a temporary file, useful for debugging"""
         with open(file_name, 'a') as f:
             f.write(log+"\n")
@@ -261,7 +274,17 @@
         self.center_part.widget_list[wid_idx] = urwid.Filler(urwid.Text(''))
         self.center_part.set_focus(0)
         self.redraw()
-    
+        
+    def addProgress (self, id, message):
+        """Follow a SàT progress bar
+        @param id: SàT id of the progression
+        @param message: message to show to identify the progression"""
+        self.progress_wid.addProgress(id, message)
+
+    def setProgress(self, percentage):
+        """Set the progression shown in notification bar"""
+        self.notBar.setProgress(percentage)
+
     def contactSelected(self, contact_list):
         contact = contact_list.get_contact()
         if contact:
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/frontends/primitivus/progress.py	Mon Aug 16 21:16:43 2010 +0800
@@ -0,0 +1,96 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+
+"""
+Primitivus: a SAT frontend
+Copyright (C) 2009, 2010  Jérôme Poisson (goffi@goffi.org)
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program.  If not, see <http://www.gnu.org/licenses/>.
+"""
+
+import urwid
+import custom_widgets
+from tools.jid import JID
+
+
+class Progress(urwid.WidgetWrap):
+
+    def __init__(self, host):
+        self.host = host
+        self.progress_list = urwid.SimpleListWalker([])
+        self.progress_dict = {}
+        listbox = urwid.ListBox(self.progress_list)
+        buttons = []
+        buttons.append(custom_widgets.CustomButton(_('Clear progress list'), self.__onClear))
+        max_len = max([button.getSize() for button in buttons])
+        buttons_wid = urwid.GridFlow(buttons,max_len,1,0,'center')
+        main_wid = custom_widgets.FocusFrame(listbox, footer=buttons_wid)
+        urwid.WidgetWrap.__init__(self, main_wid)
+
+    def addProgress(self, id, message):
+        mess_wid = urwid.Text(message)
+        progr_wid = urwid.ProgressBar('progress_normal', 'progress_complete')
+        column = urwid.Columns([mess_wid, progr_wid])
+        self.progress_dict[id] = {'full':column,'progress':progr_wid,'state':'init'}
+        self.progress_list.append(column)
+        self.progressCB(self.host.loop, (id, message))
+
+    def progressCB(self, loop, data):
+        id, message = data
+        data = self.host.bridge.getProgress(id)
+        pbar = self.progress_dict[id]['progress']
+        if data:
+            if self.progress_dict[id]['state'] == 'init':
+                #first answer, we must construct the bar
+                self.progress_dict[id]['state'] = 'progress'
+                pbar.done = float(data['size'])
+                
+            pbar.set_completion(float(data['position']))
+            self.updateNotBar()
+        else:
+            if self.progress_dict[id]['state'] == 'progress':
+                self.progress_dict[id]['state'] = 'done'
+                pbar.set_completion(pbar.done)
+                self.updateNotBar()
+                return
+
+        loop.set_alarm_in(1,self.progressCB, (id, message))
+
+    def __removeBar(self, id):
+        wid = self.progress_dict[id]['full']
+        self.progress_list.remove(wid)
+        del(self.progress_dict[id])
+
+    def __onClear(self, button):
+       to_remove = []
+       for id in self.progress_dict:
+           if self.progress_dict[id]['state'] == 'done':
+               to_remove.append(id)
+       for id in to_remove:
+           self.__removeBar(id)
+       self.updateNotBar()
+
+    def updateNotBar(self):
+        if not self.progress_dict:
+            self.host.setProgress(None)
+            return
+        progress = 0
+        nb_bars = 0
+        for id in self.progress_dict:
+            pbar = self.progress_dict[id]['progress']
+            progress += pbar.current/pbar.done*100
+            nb_bars+=1
+        av_progress = progress/float(nb_bars)
+        self.host.setProgress(av_progress)
+    
--- a/frontends/wix/main_window.py	Mon Aug 16 21:11:00 2010 +0800
+++ b/frontends/wix/main_window.py	Mon Aug 16 21:16:43 2010 +0800
@@ -324,13 +324,11 @@
     def progressCB(self, id, title, message):
         data = self.bridge.getProgress(id)
         if data:
-            if not data['position']:
-                data['position'] = '0'
             if not self.pbar:
                 #first answer, we must construct the bar
-                self.pbar = wx.ProgressDialog(title, message, int(data['size']), None,
+                self.pbar = wx.ProgressDialog(title, message, float(data['size']), None,
                     wx.PD_SMOOTH | wx.PD_ELAPSED_TIME | wx.PD_ESTIMATED_TIME | wx.PD_REMAINING_TIME) 
-                self.pbar.finish_value = int(data['size'])
+                self.pbar.finish_value = float(data['size'])
                 
             self.pbar.Update(int(data['position']))
         elif self.pbar: