root/conseil.py

Revision 80, 13.2 kB (checked in by ploum@…, 4 weeks ago)

gros commit tout pourri

Line 
1#!/usr/bin/env python
2# -*- coding: utf-8 -*-
3import sys, time, os
4import string, threading
5#subfolders are added to the path
6sys.path[1:1]=["storage", "protocols"]
7
8try:
9        import pygtk
10        pygtk.require("2.0")
11except:
12        pass
13try:
14        import gtk
15        import gtk.glade
16        import gobject
17except:
18        sys.exit(1)
19
20
21## Translation stuff ##
22## Adapted from http://www.learningpython.com/2006/12/03/translating-your-pythonpygtk-application/
23
24import locale
25import gettext
26
27APP_NAME="conseil"
28#Get the local directory since we are not installing anything
29local_path = os.path.realpath(os.path.dirname(sys.argv[0]))
30locale_path = os.path.join(local_path, "locale")
31# Init the list of languages to support
32langs = []
33#Check the default locale
34lc, encoding = locale.getdefaultlocale()
35if (lc):
36        #If we have a default, it's the first in the list
37        langs = [lc]
38# Now lets get all of the supported languages on the system
39language = os.environ.get('LANGUAGE', None)
40if (language):
41        """langage comes back something like en_CA:en_US:en_GB:en
42        on linuxy systems, so we need to split it up into a list"""
43        langs += language.split(":")
44else:
45    language = os.environ.get('LANG', None)
46if (language):
47    langs += language.split(":")
48"""Now add on to the back of the list the translations that we
49know that we have, our defaults"""
50langs += ["en_US"]
51
52"""Now langs is a list of all of the languages that we are going
53to try to use.  First we check the default, then what the system
54told us, and finally the 'known' list"""
55
56gettext.bindtextdomain(APP_NAME, locale_path)
57gettext.textdomain(APP_NAME)
58gtk.glade.bindtextdomain(APP_NAME, locale_path)
59gtk.glade.textdomain(APP_NAME)
60# Get the language to use
61lang = gettext.translation(APP_NAME,local_path
62        , languages=langs, fallback = True)
63"""Install the language, map _() (which we marked our
64strings to translate with) to lang.gettext() which will
65translate them."""
66_ = lang.gettext
67
68## End of translation stuff ##
69
70from protocol_launchpadstaging_web import protocol
71from bug import bug
72from bookmarks_store import *
73from definitions import *
74from management import *
75from retriever import *
76
77class MainWindow :
78       
79        #Initialization of the main window
80        def __init__(self):     
81                #Set the Glade file
82                self.full_glade         = gtk.glade.XML("conseil.glade")
83                self.main_window        = self.full_glade.get_widget("main_window")
84                self.bugs_tabs          = self.full_glade.get_widget("bugs_notebook")
85                self.statusbar          = self.full_glade.get_widget("statusbar")
86                self.sidebar            = self.full_glade.get_widget("sidebar")
87                self.accounts    = manage_accounts(self.full_glade)
88                #self.display_sidebar_menu = self.full_glade.get_widget("sidebar_display")
89                #hpane = self.full_glade.get_widget("hpaned1")
90                #hpane.set_property("min-position", 100)
91                #We remove directly the first page
92                # we might want to keep it and remove it at the first action
93                self.bugs_tabs.remove_page(0)
94                #Create our dictionay and connect it
95                dic = { "on_simple_search_button_clicked" : self.simpleSearch_clicked,
96                        "on_main_window_destroy" : gtk.main_quit,
97                        "on_bookmarks_row_activated": self.bookmarkClicked,
98                        "on_add_bookmark_button_clicked" : self.addBookmark_clicked,
99                        "on_remove_bookmark_button_clicked" : self.removeBookmark_clicked,
100                        "on_bookmarks_button_press_event" : self.bookmarks_button_press,
101                        "on_quit_activate": gtk.main_quit,
102                        "on_import_activate" : self.import_bookmarks,   
103                        "on_open_activate" : self.open_bookmarks,
104                        "on_account_activate" : self.accounts.show,
105                        "on_close_accountsconfig_button_clicked" : self.accounts.hide,
106                        "on_accounts_friendlyname_changed" : self.accounts.friendlyname_change,
107                        "on_accounts_protocol_changed" : self.accounts.protocol_change,
108                        "on_accounts_url_changed" : self.accounts.url_change,
109                        "on_accounts_login_changed" : self.accounts.login_change,
110                        "on_accounts_password_changed" : self.accounts.password_change,
111                        "on_accounts_add" : self.add_account,
112                        "on_accounts_remove" : self.remove_account,
113                        "on_a_propos_activate" : self.about_dialog,
114                        "on_aboutdialog_response" : lambda x, y: x.hide(),
115                        "on_bugs_notebook_switch_page" : self.switch_page,
116                        "on_sidebar_display_activate" : self.show_sidebar,
117                        "on_sidebar_close_button_clicked" : lambda close : self.set_sidebar(0),
118                        "on_aboutdialog_delete_event" : self.close_dialog,
119                        "on_accounts_dialog_delete_event" : self.close_dialog
120                        }
121                self.full_glade.signal_autoconnect(dic)
122                #self.sidebar_bm.connect("button_press_event", self.bookmarks_button_press)
123                #Wich BTS are we using ?
124                #self.auth = user()
125                #bookmarks init
126                #construction of the bookmarks widget
127                self.bookmarksStorage = gtk.TreeStore(gobject.TYPE_STRING, gobject.TYPE_STRING, gobject.TYPE_STRING) # title, bts name, xml
128                self.bookmarksTreeV = self.full_glade.get_widget("bookmarks_list")
129                self.bookmarksTreeV.set_model(self.bookmarksStorage)
130                self.renderer = gtk.CellRendererText()
131                self.renderer.set_property('editable', False)
132                self.renderer.connect('edited', self.__edited_callback)
133                column = gtk.TreeViewColumn("title", self.renderer, text=0)
134                self.bookmarksTreeV.append_column(column)
135                #~ self.bookmarksTreeV.append_column(gtk.TreeViewColumn("bts", gtk.CellRendererText(), text=1))
136                #~ self.bookmarksTreeV.append_column(gtk.TreeViewColumn("bug_id", gtk.CellRendererText(), text=2))
137                self.bookmarksTreeV.show()
138                #construction of the advanced search widget
139                #with scrollbars
140                #adv_main = self.full_glade.get_widget("adv_search_scrolled")
141                #or without
142                adv_main = self.full_glade.get_widget("adv_search_box")
143                adv_parent = self.full_glade.get_widget("adv_search_side_box")
144                to_remove = self.full_glade.get_widget("omega13")
145
146                statusbox = self.full_glade.get_widget("adv_search_status_box")
147                for e in self.accounts[0].bts().availableStatus(): # fixme !
148                        checkbox = gtk.CheckButton(label=e)
149                        checkbox.show()
150                        statusbox.pack_start(checkbox,expand=0,padding=1)
151                importancebox = self.full_glade.get_widget("adv_search_importance_box")
152                for e in self.accounts[0].bts().availableImportance(): # fixme !
153                        checkbox = gtk.CheckButton(label=e)
154                        checkbox.show()
155                        importancebox.pack_start(checkbox,expand=0,padding=1)   
156               
157                viewport = self.full_glade.get_widget("adv_search_viewport")
158                viewport.remove(adv_main)
159               
160                adv_parent.remove(to_remove)
161                adv_parent.add(adv_main)
162               
163                self.bookmarks = {}
164                for account in self.accounts:
165                        bts = account.bts().btsName()
166                        if not bts in self.bookmarks:
167                                self.bookmarks[bts] = bookmarks_store(bts, self.bookmarksStorage)
168               
169                self.btslist = btslist = self.full_glade.get_widget('bts_list1')
170                cell = gtk.CellRendererText()
171                model = gtk.ListStore(gobject.TYPE_STRING)
172                btslist.set_model(model)
173                btslist.pack_start(cell)
174                btslist.set_attributes(cell, text=0)
175                for bts in self.bookmarks:
176                        btslist.append_text(bts)
177                btslist.set_active(0)
178       
179        def add_account(self, x):
180                bts = self.accounts.add_account().bts().btsName()
181                if not bts in self.bookmarks:
182                        self.bookmarks[bts] = bookmarks_store(bts, self.bookmarksStorage)
183       
184        def remove_account(self, x):
185                acc = self.accounts.selected_account()
186                if acc:
187                        bts = acc.bts().btsName()
188                        self.accounts.remove_account()
189                        if len(self.get_accounts_for_bts(bts)) == 1:
190                                del self.booksmarks[bts]
191       
192        def __isint(self,x):
193                try:
194                        x = int(x)
195                        return 1
196                except:
197                        return 0
198
199        def show_sidebar(self,check) :
200                self.set_sidebar(check.get_active())
201
202        def set_sidebar(self,boolean) :
203                menu = self.full_glade.get_widget("sidebar_display")
204                if boolean :
205                        self.sidebar.show()
206                        menu.set_active(1)
207                else:
208                        self.sidebar.hide()
209                        menu.set_active(0)
210
211        def switch_page(self,notebook,pointer,position) :
212                widget = notebook.get_nth_page(position)
213                descr = tab_descr(widget)
214                title = read_title(descr)
215                zetype = read_type(descr)
216                if zetype == 2 or zetype == 3 :
217                        try :
218                                ztree = widget.get_children()[0].get_children()[0].get_children()[0]
219                                model= ztree.get_model()
220                                total = str(model.iter_n_children(None))
221                                title = "search for %s  - (%s results)" %(title,total)
222                        #eek.. this is ugly, isn't it ?
223                        except :
224                                title = _("search for %s") %title
225                self.statusbar.pop(0)
226                self.statusbar.push(0,title)
227
228        #bookmark is edited
229        def __edited_callback(self, cellrenderertext, path, new_text) :
230                self.bookmarks.rename(path,new_text)
231                self.renderer.set_property('editable', False)
232       
233        def import_bookmarks(self,a) :
234                def callback(dial,zeid,bmarks):
235                        if zeid == -5 :
236                                if bmarks.import_file(dial.get_filename()) == 0 :
237                                        print _("Not valid Conseil XML file")
238                                dial.destroy()
239                        else :
240                                dial.destroy()
241                dialog = gtk.FileChooserDialog()
242                cancel_button = dialog.add_button(gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL)
243                ok_button = dialog.add_button(gtk.STOCK_OK, gtk.RESPONSE_OK)
244                ok_button.grab_default()
245                dialog.connect("response", callback, self.bookmarks)
246                dialog.show()
247
248        def open_bookmarks(self,a):
249                def callback(dial,zeid,bmarks):
250                        if zeid == -5 :
251                                for i in bmarks.open_file(dial.get_filename())  :
252                                        self.open_page(bookmark(None,i))
253                                dial.destroy()
254                        else :
255                                dial.destroy()
256                dialog = gtk.FileChooserDialog()
257                cancel_button = dialog.add_button(gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL)
258                ok_button = dialog.add_button(gtk.STOCK_OK, gtk.RESPONSE_OK)
259                ok_button.grab_default()
260                dialog.connect("response", callback, self.bookmarks)
261                dialog.show()
262
263
264       
265
266        def bookmarks_button_press(self,widget, event) :
267                #middle click, we open the bug
268                if event.button == 2 :
269                        zetuple = widget.get_selection().get_selected()
270                        #Fixme : what if the user didn't click on the tree first ?
271                        if zetuple[1] != None :
272                                clicked = bookmark(widget,None,zetuple[2])
273                                self.open_page(clicked)
274                       
275                #right click menu
276                elif event.button == 3 :
277                        # callback for delete right click menu
278                        def del_callback(menuitem) :
279                                zetuple = widget.get_selection().get_selected()
280                                self.bookmarks.delete(zetuple[1])
281                        #callback for rename TODO
282                        def ren_callback(menuitem) :
283                                self.renderer.set_property('editable', True)
284                                zetuple = widget.get_selection().get_selected()
285                                store = zetuple[0]
286                                path = store.get_string_from_iter(zetuple[1])
287                                column = widget.get_column(0)
288                                widget.set_cursor(path,column,True)
289                        #définition du right click menu
290                        # TODO : use a widget as the MenuItem
291                        delete = gtk.MenuItem("delete")
292                        delete.connect("activate", del_callback)
293                        delete.show()
294                        rename = gtk.MenuItem("rename")
295                        rename.connect("activate", ren_callback)
296                        rename.show()
297                        menu = gtk.Menu()
298                        menu.append(delete)
299                        menu.append(rename)
300                        menu.popup(None, None, None, event.button, event.time)
301
302       
303        def bookmarkClicked(self, widget, path, view_column):
304                clicked = bookmark(widget,None,self.bookmarksStorage[path][2])
305                self.open_page(clicked)
306
307        #open a page in the given widget using clicked, which is a bookmark object
308        def open_page(self,clicked) :
309                accs = self.get_accounts_for_bts(clicked.bts)
310                retriever = accs[0].retriever(self.bugs_tabs, self.full_glade)
311               
312                method = clicked.get_method()
313                dic = makedict()
314                if method == 1:
315                        # besoin de programmation défensive ici FIXME
316                        dic["method"] = 1
317                        bug_nbr = clicked.get_bug()
318                        dic["bug"] = bug_nbr
319                        retriever.display(dic)
320                elif method == 2:
321                        dic["method"] = 2
322                        searchString = clicked.get_search()
323                        dic["search"] = searchString
324                        retriever.display(dic)
325                elif method == 3:
326                        dic["method"] = 3
327                        product = clicked.get_product()
328                        dic["product"] = product
329                        search = clicked.get_search()
330                        dic["search"] = search
331                        retriever.display(dic)
332
333        #when the "add bookmark button is clicked
334        def addBookmark_clicked(self, widget):
335                tab = self.bugs_tabs.get_nth_page(self.bugs_tabs.get_current_page())
336                if tab != None :
337                        #tab_descr function is part of page
338                        descr = tab_descr(tab)
339                        self.bookmarks[read_bts(descr)].add(descr)
340       
341        #the "remove bookmark" button is clicked
342        def removeBookmark_clicked(self, widget):
343                to_delete = self.bookmarksTreeV.get_selection().get_selected()[1]       
344                bts = self.bookmarksStorage.get_value(to_delete, 2)
345                self.bookmarks[bts].delete(to_delete)
346       
347        #main search button pressed
348        def simpleSearch_clicked(self, widget):
349                acc = self.get_accounts_for_bts(self.btslist.get_active_text())[0]
350                bts = acc.bts()
351                retriever = acc.retriever(self.bugs_tabs, self.full_glade)
352               
353                searchString = self.full_glade.get_widget("simple_search_entry").get_text().strip()
354                if searchString.startswith("#") :
355                        tmp = searchString.lstrip("#")
356                        if self.__isint(tmp) :
357                                searchString = tmp
358                if searchString != '' :
359                        dic = makedict()
360                        dic["bts"] = bts.btsName()
361                        # Have we a single bug number ?
362                        if self.__isint(searchString) :
363                                dic["method"] = 1
364                                dic["bug"] = searchString
365                                retriever.display(dic)
366                        # no, we have a search.
367                        else :
368                                array = string.split(searchString,' ',1)
369                                if bts.packageExist(array[0]) :
370                                        dic["method"]= 3
371                                        dic["product"] = array[0]
372                                        if len(array) < 2 :
373                                                dic["search"] = None
374                                        else :
375                                                dic["search"] = array[1]       
376                                        retriever.display(dic)
377                                else :
378                                        dic["method"]= 2
379                                        dic["search"] = searchString
380                                        retriever.display(dic)
381       
382        def about_dialog(self,widget):
383                about_widget = self.full_glade.get_widget("aboutdialog")
384                about_widget.show()
385               
386        def close_dialog(self,widget,event) :
387                widget.hide()
388                return True
389
390        def get_accounts_for_bts(self, bts):
391                accounts = []
392                for account in self.accounts:
393                        if account.bts().btsName() == bts:
394                                accounts.append(account)
395                return accounts
396
397if __name__ == "__main__":
398        gobject.threads_init()
399        #gtk.gdk.threads_init()
400        hwg = MainWindow()
401        #gtk.threads_enter()
402        gtk.main()
403        #gtk.threads_leave()
Note: See TracBrowser for help on using the browser.