Commits

elbaschid committed bbbf211

initial working prototype of indicator

Comments (0)

Files changed (1)

revelation_indicator.py

+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+#
+# 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 os
+import sys
+import argparse
+
+import logging
+logging.basicConfig(level=logging.INFO)
+logger = logging.getLogger(__file__)
+
+import gtk
+import appindicator
+
+import gettext
+_ = gettext.gettext
+
+from revelation import config, data, datahandler, dialog, entry, io, ui, util
+
+#from gi.repository import Gtk, GObject, Gio
+#from gi.repository import AppIndicator3
+ 
+#try:
+#    from gi.repository import Notify
+#except:
+#    #print _("Please install")+" pynotify"
+#    print "Please install pynotify"
+
+
+class RevelationIndicator(object):
+
+    def __init__(self, options=None):
+        filename = ''
+        if 'file' in options:
+            filename = options.file
+            logger.debug('using provided file: %s', filename)
+            
+        self.ind = appindicator.Indicator(
+            "revelation-indicator-locked",
+            "revelation-indicator",
+            appindicator.CATEGORY_APPLICATION_STATUS
+        )
+
+        self.ind.set_status(appindicator.STATUS_ACTIVE)
+
+        #self.ind.set_status(AppIndicator3.STATUS_ACTIVE)
+        #self.ind.set_attention_icon("new-messages-red")
+
+        import sys
+        sys.excepthook	= self.__cb_exception
+
+        gettext.bindtextdomain(config.PACKAGE, config.DIR_LOCALE)
+        gettext.bind_textdomain_codeset(config.PACKAGE, "UTF-8")
+        gettext.textdomain(config.PACKAGE)
+        
+        try:
+            self.__init_config(filename)
+            self.__init_facilities()
+            self.__init_ui()
+            #self.__init_states()
+
+        except config.ConfigError:
+            dialog.Error(
+                None, 
+                _('Missing configuration data'), 
+                _('The applet could not find its configuration data, please'
+                  'reinstall Revelation.')
+            ).run()
+            sys.exit(1)
+
+    def __init_config(self, filename=''):
+        self.config = config.Config("/schemas/apps/revelation-applet/prefs")
+        
+        # set up defaults
+        # TODO this shouldn't really be necessary, the schema should
+        # be used for defaults - is this even possible with the current
+        # applet api?
+        defaults = {
+            "autolock": True,
+            "autolock_timeout": 10,
+            "chain_username": False,
+            "file": '',
+            "menuaction": "show",
+            "show_passwords": True,
+            "show_searchentry": True
+        }
+
+        for key, value in defaults.items():
+            try:
+                if self.config.get(key) is None:
+                    self.config.set_force(key, value)
+
+            except config.ConfigError:
+                self.config.set_force(key, value)
+
+        if filename:
+            self.config.set_force('file', filename)
+
+        ##TODO: debug only
+        for key, value in defaults.items():
+            print key, self.config.get(key)
+
+        # make sure the launchers have been set up, otherwise
+        # install the Revelation schema
+        def check_launchers():
+            try:
+                for entrytype in [ et() for et in entry.ENTRYLIST if et != entry.FolderEntry ]:
+                    self.config.get("/apps/revelation/launcher/%s" % entrytype.id)
+
+            except config.ConfigError:
+                return False
+
+            else:
+                return True
+
+
+        if check_launchers() == False:
+            if config.install_schema("%s/revelation.schemas" % config.DIR_GCONFSCHEMAS) == False:
+                raise config.ConfigError
+
+            if check_launchers() == False:
+                raise config.ConfigError
+
+    def __init_facilities(self):
+        "Sets up facilities"
+
+        self.clipboard		= data.Clipboard()
+        self.datafile		= io.DataFile(datahandler.Revelation)
+        self.entrystore		= data.EntryStore()
+        self.entrysearch	= data.EntrySearch(self.entrystore)
+        #self.items		= ui.ItemFactory(self.applet)
+        self.locktimer		= data.Timer()
+
+        self.config.monitor("autolock_timeout", lambda k,v,d: self.locktimer.start(v * 60))
+        self.config.monitor("file", self.__cb_config_file)
+
+        self.datafile.connect("changed", self.__cb_file_changed)
+        self.datafile.connect("content-changed", self.__cb_file_content_changed)
+        self.locktimer.connect("ring", self.__cb_file_autolock)
+
+        self.entrysearch.folders = False
+    
+    def __init_ui(self):
+        self.menu = gtk.Menu()
+
+        self.unlock_item = gtk.MenuItem(_('Unlock File'))
+        self.unlock_item.show()
+        self.unlock_item.connect(
+            'activate', 
+            lambda w,d=None: self.file_open(self.config.get("file"))
+        )
+
+        self.lock_item = gtk.MenuItem(_('Lock File'))
+        self.lock_item.show()
+        #( "file-lock",		lambda w,d=None: self.file_close() ),
+
+        self.reload_item = gtk.MenuItem(_('Reload File'))
+        self.reload_item.show()
+        #( "file-reload",	lambda w,d=None: self.file_reload() ),
+
+        self.start_revel_item = gtk.MenuItem(_('Start Revelation'))
+        self.start_revel_item.show()
+        #( "revelation",		lambda w,d=None: util.execute_child("@bindir@/revelation") ),
+
+        self.prefs_item = gtk.MenuItem(_('Preferences'))
+        self.prefs_item.show()
+        self.prefs_item.connect('activate', lambda w,d=None: self.prefs())
+
+        self.about_item = gtk.MenuItem(_('About'))
+        self.about_item.show()
+        self.about_item.connect('activate', self.__cb_about)
+
+        self.menu.append(self.unlock_item)
+        self.menu.append(self.lock_item)
+        self.menu.append(self.reload_item)
+        self.menu.append(self.start_revel_item)
+        self.menu.append(self.prefs_item)
+        self.menu.append(self.about_item)
+
+        self.ind.set_menu(self.menu)
+        self.menu.show_all()
+
+        gtk.about_dialog_set_url_hook(
+            lambda d,l: gtk.show_uri(None, l, gtk.get_current_event_time())
+        )
+
+	gtk.about_dialog_set_email_hook(
+            lambda d,l: gtk.show_uri(None, "mailto:" + l, gtk.get_current_event_time())
+        )
+
+#	# set up window icons
+#	pixbufs = [ self.items.get_pixbuf("revelation", size) for size in ( 48, 32, 24, 16) ]
+#	pixbufs = [ pixbuf for pixbuf in pixbufs if pixbuf != None ]
+#
+#	if len(pixbufs) > 0:
+#	    gtk.window_set_default_icon_list(*pixbufs)
+#
+        # set up popup menu
+        #self.applet.setup_menu("""
+		#	<popup name="button3">
+		#		<menuitem name="file-unlock"	verb="file-unlock"	label=\"""" + _('Unlock File') + """\"		pixtype="stock" pixname="revelation-unlock" />
+		#		<menuitem name="file-lock"	verb="file-lock"	label=\"""" + _('Lock File') + """\"		pixtype="stock" pixname="revelation-lock" />
+		#		<menuitem name="file-reload"	verb="file-reload"	label=\"""" + _('Reload File') + """\"		pixtype="stock" pixname="revelation-reload" />
+		#		<separator />
+		#		<menuitem name="revelation"	verb="revelation"	label=\"""" + _('Start Revelation') + """\"	pixtype="stock" pixname="revelation-revelation" />
+		#		<menuitem name="prefs"		verb="prefs"		label=\"""" + _('Preferences') + """\"		pixtype="stock"	pixname="gtk-properties" />
+		#		<menuitem name="about"		verb="about"		label=\"""" + _('About') + """\"		pixtype="stock"	pixname="gnome-stock-about" />
+		#	</popup>
+		#""", (
+		#	( "about",		lambda w,d=None: self.about() ),
+		#	( "file-lock",		lambda w,d=None: self.file_close() ),
+		#	( "file-reload",	lambda w,d=None: self.file_reload() ),
+		#	( "file-unlock",	lambda w,d=None: self.file_open(self.config.get("file")) ),
+		#	( "prefs",		lambda w,d=None: self.prefs() ),
+		#	( "revelation",		lambda w,d=None: util.execute_child("@bindir@/revelation") ),
+		#), None)
+
+		## set up ui items
+		#self.entry = ui.Entry()
+		#self.entry.set_width_chars(14)
+		#self.entry.connect("activate", self.__cb_entry_activate)
+		#self.entry.connect("button_press_event", self.__cb_entry_buttonpress)
+		#self.entry.connect("key_press_event", lambda w,d=None: self.locktimer.reset())
+
+		#self.icon = ui.Image()
+		#self.eventbox = ui.EventBox(self.icon)
+		#self.eventbox.connect("button_press_event", self.__cb_icon_buttonpress)
+
+		#self.hbox = ui.HBox(self.eventbox, self.entry)
+		#self.applet.add(self.hbox)
+		#
+		## handle Gnome Panel background
+		#self.applet.connect("change-background",self.panel_bg)
+
+		#self.applet.show_all()
+
+		## set up various ui element holders
+		#self.popup_entryview	= None
+		#self.popup_entrylist	= None
+
+		#self.entrymenu		= None
+
+    def main(self):
+        gtk.main()
+
+    def quit(self, widget):
+        sys.exit(0)
+
+    
+    def file_close(self):
+        self.__close_popups()
+        self.locktimer.stop()
+
+        self.datafile.close()
+        self.entrystore.clear()
+        self.entrymenu = None
+
+
+    def file_open(self, file, password = None):
+        try:
+            return self.__file_load(file, password)
+
+        except dialog.CancelError:
+            pass
+
+        except datahandler.FormatError:
+            dialog.Error(None, _('Invalid file format'), _('The file \'%s\' contains invalid data.') % file).run()
+
+        except ( datahandler.DataError, entry.EntryTypeError, entry.EntryFieldError ):
+            dialog.Error(
+                None, 
+                _('Unknown data'), 
+                _(
+                    'The file \'%s\' contains unknown data. It may have been '
+                    'created by a more recent version of Revelation.'
+                ) % file
+            ).run()
+
+        except datahandler.PasswordError:
+                dialog.Error(
+                    None, 
+                    _('Incorrect password'), 
+                    _(
+                        'You entered an incorrect password for the file '
+                        '\'%s\', please try again.'
+                    ) % file
+                ).run()
+                self.file_open(file, None)
+
+        except datahandler.VersionError:
+                dialog.Error(
+                    None, 
+                    _('Unknown data version'), 
+                    _('The file \'%s\' has a future version number, please upgrade Revelation to open it.') % file
+                ).run()
+
+        except IOError:
+                dialog.Error(
+                    None, 
+                    _('Unable to open file'), 
+                    _('The file \'%s\' could not be opened. Make sure that the file exists, and that you have permissions to open it.') % file
+                ).run()
+
+        return False
+
+
+    def file_reload(self):
+        if self.datafile.get_file() == None:
+                return
+
+        self.file_open(self.datafile.get_file(), self.datafile.get_password())
+
+    def prefs(self):
+        dialog.run_unique(Preferences, None, self.config)
+
+
+    def __cb_config_file(self, key, value, data):
+            "Config callback for file key changes"
+
+            self.file_close()
+            ##TODO: fix this
+            #self.applet.get_popup_component().set_prop("/commands/file-unlock", "sensitive", self.config.get("file") != "" and "1" or "0")
+
+
+    def __cb_config_show_searchentry(self, key, value, data):
+            "Config callback for show searchentry setting"
+
+            if value == True:
+                            self.entry.show()
+
+            else:
+                            self.entry.hide()
+
+    def __cb_entry_activate(self, widget, data = None):
+            "Callback for entry activation (pressing enter etc)"
+
+            self.entry_search(self.entry.get_text(), True)
+
+
+    def __cb_entry_buttonpress(self, widget, data = None):
+            "Callback for entry button presses"
+
+            self.locktimer.reset()
+
+            if data.button == 1:
+                ##TODO: fix this
+                #self.applet.request_focus(data.time)
+                pass
+
+
+    def __cb_file_autolock(self, widget, data = None):
+            "Callback for autolocking the file"
+
+            if self.config.get("autolock") == True:
+                    self.file_close()
+
+
+    def __cb_file_content_changed(self, widget, data = None):
+            "Callback for changed file content"
+
+            try:
+                    self.__file_load(self.datafile.get_file(), self.datafile.get_password())
+
+            except dialog.CancelError:
+                    pass
+
+            except datahandler.PasswordError:
+                    self.file_close()
+
+            except datahandler.Error:
+                    pass
+
+
+    def __cb_file_changed(self, widget, data = None):
+            "Callback for changed data file"
+
+            pass
+
+            ##FIXME:
+            #popup = self.applet.get_popup_component()
+
+            #if self.datafile.get_file() == None:
+            #        self.entry.set_text("")
+
+            #        popup.set_prop("/commands/file-unlock", "sensitive", self.config.get("file") != "" and "1" or "0")
+            #        popup.set_prop("/commands/file-lock", "sensitive", "0")
+            #        popup.set_prop("/commands/file-reload", "sensitive", "0")
+
+            #        self.icon.set_from_stock(ui.STOCK_REVELATION_LOCKED, ui.ICON_SIZE_APPLET)
+
+            #else:
+            #        popup.set_prop("/commands/file-unlock", "sensitive", "0")
+            #        popup.set_prop("/commands/file-lock", "sensitive", "1")
+            #        popup.set_prop("/commands/file-reload", "sensitive", "1")
+
+            #        self.icon.set_from_stock(ui.STOCK_REVELATION, ui.ICON_SIZE_APPLET)
+
+
+    def __cb_icon_buttonpress(self, widget, data = None):
+            "Callback for buttonpress on button"
+
+            if data.button != 1:
+                    return False
+
+            self.entry_menu(data.time)
+
+            return True
+
+
+    def __cb_popup_activate(self, widget, data = None):
+        self.locktimer.reset()
+
+        action = self.config.get("menuaction")
+
+        if action == "show":
+                self.entry_show(data)
+
+        elif action == "copy":
+                self.entry_copychain(data)
+
+        elif self.__launcher_valid(data):
+                self.entry_goto(data)
+
+        else:
+                self.entry_show(data)
+
+    def entry_show(self, e, focusafter = False):
+        self.__close_popups()
+
+        self.popup_entryview = EntryViewPopup(e, self.config, self.clipboard)
+
+        if focusafter == True:
+                self.popup_entryview.connect("closed", lambda w: self.__focus_entry())
+
+        def cb_goto(widget):
+                if self.__launcher_valid(e):
+                        self.entry_goto(e)
+
+                self.popup_entryview.close()
+
+        self.popup_entryview.button_goto.connect("clicked", cb_goto)
+        self.popup_entryview.button_goto.set_sensitive(self.__launcher_valid(e))
+
+        self.popup_entryview.realize()
+        x, y = self.__get_popup_offset(self.popup_entryview)
+        self.popup_entryview.show(x, y)
+
+    def __close_popups(self):
+            "Closes any open popups"
+
+            self.locktimer.reset()
+
+            if hasattr(self, "popup_entryview") == True and self.popup_entryview != None:
+                    self.popup_entryview.destroy()
+
+            if hasattr(self, "popup_entrylist") == True and self.popup_entrylist != None:
+                    self.popup_entrylist.destroy()
+
+            if hasattr(self, "entrymenu") == True and self.entrymenu != None:
+                    self.entrymenu.hide()
+
+
+    def __file_load(self, filename, password = None):
+
+        if not filename:
+            logger.debug("no revelation database provided")
+            return False
+
+        if dialog.present_unique(dialog.PasswordOpen) == True:
+            logger.debug('password dialog already opened')
+            return False
+
+        entrystore = self.datafile.load(
+            filename, 
+            password, 
+            lambda: dialog.run_unique(
+                dialog.PasswordOpen, 
+                None, 
+                os.path.basename(filename)
+            )
+        )
+
+        self.entrystore.clear()
+        self.entrystore.import_entry(entrystore, None)
+
+        menu = self.__generate_entrymenu(self.entrystore)
+        entries_item = gtk.MenuItem('Entries')
+        entries_item.set_submenu(menu)
+
+        self.menu.append(entries_item)
+        self.menu.show_all()
+
+        self.locktimer.start(self.config.get("autolock_timeout") * 60)
+
+        self.__close_popups()
+
+        return True
+
+
+    def __flash_entry(self, color = "#ffbaba", duration = 500):
+            "Flashes the entry with a color"
+
+            color_normal	= ui.Entry().rc_get_style().base[gtk.STATE_NORMAL]
+            color_new	= gtk.gdk.color_parse(color)
+
+            self.entry.modify_base(gtk.STATE_NORMAL, color_new)
+            gobject.timeout_add(duration, lambda: self.entry.modify_base(gtk.STATE_NORMAL, color_normal))
+
+
+    def __focus_entry(self):
+            "Gives focus to the entry"
+
+            ##FIXME:
+            ##self.applet.request_focus(long(0))
+            pass
+
+
+    def __generate_entrymenu(self, entrystore, parent = None):
+            "Generates an entry menu tree"
+
+            menu = gtk.Menu()
+
+            for i in range(entrystore.iter_n_children(parent)):
+                iter = entrystore.iter_nth_child(parent, i)
+
+                e = entrystore.get_entry(iter)
+                item = ui.ImageMenuItem(type(e) == entry.FolderEntry and ui.STOCK_FOLDER or e.icon, e.name)
+                item.connect("select", lambda w,d=None: self.locktimer.reset())
+
+                if type(e) == entry.FolderEntry:
+                    item.set_submenu(self.__generate_entrymenu(entrystore, iter))
+                else:
+                    item.connect("activate", self.__cb_popup_activate, e)
+
+                menu.append(item)
+
+            return menu 
+
+
+    def __get_launcher(self, e):
+            "Returns a launcher command for an entry, if possible"
+
+            command = self.config.get("/apps/revelation/launcher/%s" % e.id)
+
+            if command in ( "", None ):
+                    return None
+
+            subst = {}
+            for field in e.fields:
+                    subst[field.symbol] = field.value
+
+            command = util.parse_subst(command, subst)
+
+            return command
+
+
+    def __get_popup_offset(self, popup):
+            "Returns a tuple of x and y offset coords for popups"
+
+            x = gtk.gdk.screen_width() / 2
+            y = 50 
+
+            return x, y
+
+
+    def __launcher_valid(self, e):
+            "Checks if a launcher is valid"
+
+            try:
+                    command = self.__get_launcher(e)
+
+                    return command != None
+
+            except ( util.SubstFormatError ):
+                    return True
+
+            except ( util.SubstValueError, config.ConfigError ):
+                    return False
+
+
+    def __require_file(self):
+            "Checks if a datafile is loaded, or alerts the user"
+
+            if self.datafile.get_file() != None:
+                    return True
+
+            if self.config.get("file") != "":
+                    return self.file_open(self.config.get("file"))
+
+            d = dialog.Info(
+                    None, _('File not selected'),
+                    _('You must select a Revelation data file to use - this can be done in the applet preferences.'),
+                    ( ( gtk.STOCK_PREFERENCES, gtk.RESPONSE_ACCEPT ), ( gtk.STOCK_OK, gtk.RESPONSE_OK ) )
+            )
+
+
+            if d.run() == gtk.RESPONSE_ACCEPT:
+                    self.prefs()
+
+            return False
+
+
+
+
+    def __cb_about(self, item):
+        dialog = gtk.AboutDialog()
+        dialog.set_name(_('Revelation Indicator'))
+        dialog.set_comments(_('An indicator applet to browse a Revelation database'))
+        dialog.set_version("0.1")
+        dialog.set_copyright("(c) Sebastian Vetter")
+        dialog.run()
+        dialog.destroy()
+
+    def __cb_exception(self, type, value, trace):
+
+        if type == KeyboardInterrupt:
+            sys.exit(1)
+
+        traceback = util.trace_exception(type, value, trace)
+        sys.stderr.write(traceback)
+
+        if dialog.Exception(None, traceback).run() == True:
+            gtk.main()
+        else:
+            sys.exit(1)
+
+
+class Preferences(dialog.Utility):
+
+    def __init__(self, parent, cfg):
+            dialog.Utility.__init__(self, parent, "Preferences")
+            self.config = cfg
+            self.set_modal(False)
+
+            self.notebook = ui.Notebook()
+            self.vbox.pack_start(self.notebook)
+
+            self.page_general = self.notebook.create_page(_('General'))
+            self.__init_section_file(self.page_general)
+            #self.__init_section_menuaction(self.page_general)
+            #self.__init_section_misc(self.page_general)
+
+            #self.page_goto = self.notebook.create_page(_('Goto Commands'))
+            #self.__init_section_gotocmd(self.page_goto)
+
+            self.connect("response", lambda w,d: self.destroy())
+
+
+    def __init_section_file(self, page):
+            self.section_file = page.add_section(_('File Handling'))
+
+            # entry for file
+            self.button_file = ui.FileButton(_('Select File to Use'))
+            ui.config_bind(self.config, "file", self.button_file)
+
+            eventbox = ui.EventBox(self.button_file)
+            eventbox.set_tooltip_text(_('The data file to search for accounts in'))
+            self.section_file.append_widget(_('File to use'), eventbox)
+
+            # check-button for autolock
+            self.check_autolock = ui.CheckButton(_('Lock file when inactive for'))
+            ui.config_bind(self.config, "autolock", self.check_autolock)
+            self.check_autolock.connect("toggled", lambda w: self.spin_autolock_timeout.set_sensitive(w.get_active()))
+            self.check_autolock.set_tooltip_text(_('Automatically lock the file after a period of inactivity'))
+
+            # spin-entry for autolock-timeout
+            self.spin_autolock_timeout = ui.SpinEntry()
+            self.spin_autolock_timeout.set_range(1, 120)
+            self.spin_autolock_timeout.set_sensitive(self.check_autolock.get_active())
+            ui.config_bind(self.config, "autolock_timeout", self.spin_autolock_timeout)
+            self.spin_autolock_timeout.set_tooltip_text(_('The period of inactivity before locking the file, in minutes'))
+
+            # container for autolock-widgets
+            hbox = ui.HBox()
+            hbox.set_spacing(3)
+            hbox.pack_start(self.check_autolock)
+            hbox.pack_start(self.spin_autolock_timeout)
+            hbox.pack_start(ui.Label(_('minutes')))
+            self.section_file.append_widget(None, hbox)
+
+
+    #def __init_section_gotocmd(self, page):
+    #        "Sets up the goto command section"
+
+    #        self.section_goto = page.add_section(_('Goto Commands'))
+
+    #        for entrytype in entry.ENTRYLIST:
+    #                if entrytype == entry.FolderEntry:
+    #                        continue
+
+    #                e = entrytype()
+
+    #                widget = ui.Entry()
+    #                ui.config_bind(self.config, "/apps/revelation/launcher/%s" % e.id, widget)
+
+    #                tooltip = _('Goto command for %s accounts. The following expansion variables can be used:\n\n') % e.typename
+
+    #                for field in e.fields:
+    #                        tooltip += "%%%s: %s\n" % ( field.symbol, field.name )
+
+    #                tooltip += "\n"
+    #                tooltip += _('%%: a % sign') + "\n"
+    #                tooltip += _('%?x: optional expansion variable') + "\n"
+    #                tooltip += _('%(...%): optional substring expansion')
+
+    #                widget.set_tooltip_text(tooltip)
+    #                self.section_goto.append_widget(e.typename, widget)
+
+
+    #def __init_section_menuaction(self, page):
+    #        "Sets up a menuaction section in a page"
+
+    #        self.section_menuaction = page.add_section(_('Menu Action'))
+
+    #        # radio-button for show
+    #        self.radio_show = ui.RadioButton(None, _('Display account info'))
+    #        ui.config_bind(self.config, "menuaction", self.radio_show, "show")
+
+    #        self.radio_show.set_tooltip_text(_('Display the account information'))
+    #        self.section_menuaction.append_widget(None, self.radio_show)
+
+    #        # radio-button for goto
+    #        self.radio_goto = ui.RadioButton(self.radio_show, _('Go to account, if possible'))
+    #        ui.config_bind(self.config, "menuaction", self.radio_goto, "goto")
+
+    #        self.radio_goto.set_tooltip_text(_('Open the account in an external application if possible, otherwise display it'))
+    #        self.section_menuaction.append_widget(None, self.radio_goto)
+
+    #        # radio-button for copy username/password
+    #        self.radio_copy = ui.RadioButton(self.radio_show, _('Copy password to clipboard'))
+    #        ui.config_bind(self.config, "menuaction", self.radio_copy, "copy")
+
+    #        self.radio_copy.set_tooltip_text(_('Copy the account password to the clipboard'))
+    #        self.section_menuaction.append_widget(None, self.radio_copy)
+
+
+    #def __init_section_misc(self, page):
+    #        "Sets up the misc section"
+
+    #        self.section_misc = page.add_section(_('Miscellaneous'))
+
+    #        # show searchentry checkbutton
+    #        self.check_show_searchentry = ui.CheckButton(_('Show search entry'))
+    #        ui.config_bind(self.config, "show_searchentry", self.check_show_searchentry)
+
+    #        self.check_show_searchentry.set_tooltip_text(_('Display an entry box in the applet for searching'))
+    #        self.section_misc.append_widget(None, self.check_show_searchentry)
+
+    #        # show passwords checkbutton
+    #        self.check_show_passwords = ui.CheckButton(_('Show passwords and other secrets'))
+    #        ui.config_bind(self.config, "show_passwords", self.check_show_passwords)
+
+    #        self.check_show_passwords.set_tooltip_text(_('Display passwords and other secrets, such as PIN codes (otherwise, hide with ******)'))
+    #        self.section_misc.append_widget(None, self.check_show_passwords)
+
+    #        # check-button for username
+    #        self.check_chain_username = ui.CheckButton(_('Also copy username when copying password'))
+    #        ui.config_bind(self.config, "chain_username", self.check_chain_username)
+
+    #        self.check_chain_username.set_tooltip_text(_('When the password is copied to clipboard, put the username before the password as a clipboard "chain"'))
+    #        self.section_misc.append_widget(None, self.check_chain_username)
+
+
+    def run(self):
+            self.show_all()
+
+
+class EntryViewPopup(dialog.Popup):
+
+    def __init__(self, e, cfg = None, clipboard = None):
+        dialog.Popup.__init__(self)
+        self.set_title(e.name)
+
+        self.entryview = ui.EntryView(cfg, clipboard)
+        self.entryview.set_border_width(0)
+        self.entryview.display_entry(e)
+
+        self.button_close = ui.Button(gtk.STOCK_CLOSE, lambda w: self.close())
+        self.button_goto = ui.Button(ui.STOCK_GOTO)
+        self.buttonbox = ui.HButtonBox(self.button_goto, self.button_close)
+
+        self.vbox = ui.VBox(self.entryview, self.buttonbox)
+        self.vbox.set_border_width(12)
+        self.vbox.set_spacing(15)
+
+        self.add(self.vbox)
+
+        self.connect("show", lambda w: self.button_close.grab_focus())
+
+
+def main(options=None):
+
+    revelation_indicator = RevelationIndicator(options)
+    revelation_indicator.main()
+
+if __name__ == "__main__":
+   
+    parser = argparse.ArgumentParser()
+    parser.add_argument('-d', '--debug', action='store_true', default=False)
+    parser.add_argument('-f', '--file', default='')
+    options = parser.parse_args()
+
+    print options
+
+    if options.debug:
+        logger.setLevel(logging.DEBUG)
+
+    main(options)