Ejemplo n.º 1
0
	def _sync_children(self):
		from list import List
		from preferences import Preferences

		Preferences.sync()
		List.sync()
		User.sync()
class GUI:
  
  def __init__(self):
    """Initializes the window and create pointers for all the important widgets.
    This function also runs some code to add functionality.
    """
    
    # Initialize the window and several other objects in the instance
    self.initialize_window()
    
    # Properties instance to handle the preferences window
    self.preferences = Preferences(self.main_window)
    
    # Now setup the variables needed for file access 
    try:
      self.setup_file_access()
    except Exception, e:
      # In case of error, the user must change the preferences
      log(e.__class__.__name__)
      log(e)
      self.preferences.run()
      self.setup_file_access()
    
    self.modified = set() # Store the names of the modified files
    
    # The next variable takes care of each file by holding the choices made for
    # it. The values of the dictionary are Annotator objects, where information
    # about the annotations made in the file
    self.results = {}
    
    # This flag determines whether signal handling should take place. It is True
    # when the interface is being adjusted programatically
    self.backend = False
Ejemplo n.º 3
0
 def testSaveLoad(self):
     prefs = Preferences('prefstest.conf')
     
     self.assertEqual(None, prefs.btDevice)
     self.assertEqual('bluetooth', prefs.connectionMethod)
     self.assertEqual('', prefs.customDevice)
     self.assertEqual(0, prefs.gammuIndex)
     
     prefs.btDevice = BluetoothDevice('00:00:00:00', 42, 'deviceName', 'serviceName')
     prefs.connectionMethod = 'connection'
     prefs.customDevice = '/dev/rfcomm0'
     prefs.gammuIndex = 2
             
     prefs.save()
     
     prefsLoaded = Preferences('prefstest.conf')
     prefsLoaded.load()
     
     self.assertNotEqual(None, prefsLoaded.btDevice, "Device has not been loaded")
     self.assertEqual('00:00:00:00', prefsLoaded.btDevice.address)
     self.assertEqual(42, prefsLoaded.btDevice.port)
     self.assertEqual('deviceName', prefsLoaded.btDevice.deviceName)
     self.assertEqual('serviceName', prefsLoaded.btDevice.serviceName)
     self.assertEqual('connection', prefsLoaded.connectionMethod)
     self.assertEqual('/dev/rfcomm0', prefsLoaded.customDevice)
     self.assertEqual(2, prefsLoaded.gammuIndex)
Ejemplo n.º 4
0
class Main:
    def __init__(self):
        pygame.init()
        pygame.display.init()
        pygame.font.init()

        self.screen_w = pygame.display.Info().current_w
        self.screen_h = pygame.display.Info().current_h
        self.w = int(self.screen_h * 1.2)
        self.h = int(self.screen_h * 0.8)

        self.preferences = Preferences()
        self.fullscreen = self.preferences.get("fullscreen")
        self.go_mode()

        pygame.mouse.set_visible(False)

        pygame.display.set_caption(Constants.CAPTION)

    def go_mode(self):
        if self.fullscreen:
            self.mode = (self.screen_w, self.screen_h)
            if not self.mode in pygame.display.list_modes():
                self.mode = pygame.display.list_modes()[0]
            self.screen = pygame.display.set_mode(self.mode, pygame.FULLSCREEN)
        else:
            self.mode = (self.w, self.h)
            self.screen = pygame.display.set_mode(self.mode)
        self.unit = int(self.mode[1] / Constants.UNITS)

    def main(self):
        self.boot_screen()
        while True:
            if not self.title_screen():
                break
            if self.preferences.edit_flag:
                self.preferences.save()
                fullscreen = self.preferences.get("fullscreen")
                if self.fullscreen != fullscreen:
                    self.fullscreen = fullscreen
                    self.go_mode()
            else:
                self.play_game()

    def boot_screen(self):
        bs = BootScreen(self.screen, self.unit)
        bs.main()
        return bs.running

    def title_screen(self):
        self.go_mode()
        ts = TitleScreen(self.screen, self.unit, self.preferences)
        ts.main()
        return ts.running

    def play_game(self):
        gm = Game(self.screen, self.unit, self.preferences)
        gm.main()
        return gm.running
Ejemplo n.º 5
0
def write(domain, key, value=None, user=kCFPreferencesCurrentUser, host=kCFPreferencesAnyHost):
    """Writes value as the value for key in domain, also accepts a dictionary of multiple key_value pairs to write"""

    domain = Preferences(domain, user, host)
    if type(key) is dict:
        domain.set_multiple(key)
    elif value is not None:
        domain[key] = value
Ejemplo n.º 6
0
def delete(domain, key=None, user=kCFPreferencesCurrentUser, host=kCFPreferencesAnyHost):
    """Removes the default named key from domain, also accepts a list of keys to remove"""
    
    domain = Preferences(domain, user, host)

    if type(key) is list:
        domain.delete_multiple(key)
    else:
        del domain[key]
Ejemplo n.º 7
0
 def on_actionPreferences_triggered(self):
     '''Display preferences dialog.
     '''
     prefs = Preferences(self.book_manager, parent=self)
     #prefs.setModal(True)
     #prefs.show()
     prefs.exec_()
     self.reload_books_list()
     self.reload_search_menu()
Ejemplo n.º 8
0
 def signInIfNecessary(parent=None):
     """Sign into SRS Collector, and return the API key."""
     apiKey = Preferences.apiKey()
     if not apiKey:
         dialog = SignInDialog()
         dialog.exec_()
         apiKey = dialog.apiKey
         if apiKey:
             Preferences.setApiKey(apiKey)
     return apiKey
Ejemplo n.º 9
0
def read(domain, key=None, default=None, user=kCFPreferencesCurrentUser, host=kCFPreferencesAnyHost):
    """Prints the value for the default of domain identified by key, also accepts a list of keys"""

    domain = Preferences(domain, user, host)
    if key is None:
        return domain

    if type(key) is list:
        return domain.get_multiple(key)

    return domain[key]
Ejemplo n.º 10
0
  def _do_load(self):

    self.load_config()

    component.get("TorrentView").add_text_column(DISPLAY_NAME,
        col_type=[str, str], status_field=[STATUS_NAME, STATUS_ID])

    component.get("TorrentView").treeview.connect(
      "button-press-event", self.on_tv_button_press)

    self.menu = self._create_context_menu()
    self.sep = component.get("MenuBar").add_torrentmenu_separator()
    component.get("MenuBar").torrentmenu.append(self.menu)

    self.label_sidebar = LabelSidebar()

    self.preferences = Preferences()

    self.add_torrent_ext = AddTorrentExt()

    self.enable_dnd()

    self.status_item = None

    self.initialized = True
Ejemplo n.º 11
0
 def importCards():
     """Import cards from the server."""
     apiKey = SignInDialog.signInIfNecessary()
     if apiKey:
         try:
             Importer().run(apiKey)
         except UpgradeRequiredException:
             showInfo("Please upgrade your copy of the SRS Collector addon.")
         except urllib2.HTTPError as e:
             if e.code == 401:
                 Preferences.setApiKey(None)
                 showInfo("Sign in expired. Please try again.")
             else:
                 showInfo("Unknown network error.")
         except urllib2.URLError:
             # Generally a DNS error.
             showInfo("Network error. Are you online?")
Ejemplo n.º 12
0
class RhythmWeb(rb.Plugin, Loggable):
    
    config = None
    preferences = None
    
    def __init__(self):
        base_path = os.path.dirname(__file__)
        
        config_path = os.path.join(base_path, 'cfg', 'rb-serve.conf')
        config = Configuration()
        config.load_configuration(config_path)
        serve.log.get_factory().configure(config)
        
        self.base_path = base_path
        self.config = config
        self.config_path = config_path
        
        resource_path = os.path.join(base_path, 'resources')
        config.put('*resources', resource_path)

        
    def activate(self, shell):
        config = self.config
        config.print_configuration(self)
        rbhandler = RBHandler(shell)
        
        components = {'config' : config, 'RB' : rbhandler}
        
        application = CGIApplication('RhythmWeb', self.base_path, components)
        
        server = CGIServer(application, config)
        server.start()
        shell.server = server
        
        self.preferences = Preferences(config, self.config_path)

        
        
    def deactivate(self, shell):
        if not shell.server is None:
            shell.server.stop()
        
        del shell.server
        del self.config
        del self.config_path
        del self.base_path

        if not self.preferences.button == None:
            self.preferences.button.disconnect(self.connect_id_pref2)
        del self.preferences 


    def create_configure_dialog(self, dialog=None):
        dialog = self.preferences.show_dialog()
        self.connect_id_pref2 = self.preferences.button.connect('clicked', lambda x: dialog.destroy() )
        return dialog
    def on_preferences_activated(self, event=None):
        """Raises the preferences dialog. If it's already open, it's
        focused"""
        if self._preferences_dialog is not None:
            self._preferences_dialog.present()
            return

        self._preferences_dialog = Preferences(self)
        self._preferences_dialog.run()
        self._preferences_dialog = None
Ejemplo n.º 14
0
    def __init__(self):
        pygame.init()

        #get preferences
        self.preferences = Preferences()
        # self.nickname = raw_input('Choose a username: '******'Choose a color (red, green, blue, yellow, white): ')
        #resolution, flags, depth, display
        self.unit=Constants.RESOLUTION[0]/Constants.UNITS
        self.banner = Banner()
        self.score_width=self.unit*15

        if self.preferences.fullscreen:
            self.screen = pygame.display.set_mode((Constants.RESOLUTION[0]+self.score_width,\
                                               Constants.RESOLUTION[1]),pygame.FULLSCREEN)
        else:
            self.screen = pygame.display.set_mode((Constants.RESOLUTION[0]+self.score_width,\
                                               Constants.RESOLUTION[1]),0,32)

        pygame.display.set_caption(Constants.CAPTION)

        #game area surface
        self.gamescreen = pygame.Surface(Constants.RESOLUTION)
        #score area rectangle surface
        self.scorescreen = pygame.Surface((self.score_width,Constants.RESOLUTION[1]))

        #Snake and foods manager
        self.me=Snake(color=pygame.color.THECOLORS[self.preferences.get("color")],\
                    nickname=self.preferences.get("nickname"))


        self.f=Foods()

        self.others = {}

        #Score manager
        self.scores=Scores((self.score_width,Constants.RESOLUTION[1]))

        #add our own score, the server will send us the remaining one at connection
        self.scores.new_score(self.preferences.get("nickname"),\
                        pygame.color.THECOLORS[self.preferences.get("color")])

	#game area background color
        self.gamescreen.fill(Constants.COLOR_BG)
        self.scorescreen.fill((100,100,100))

        #timers
        self.clock=pygame.time.Clock();
        self.current_time=0

        self.move_snake_timer=Timer(1.0/Constants.SNAKE_SPEED*1000,self.current_time,periodic=True)
        self.blink_snake_timer=Timer(1.0/Constants.SNAKE_BLINKING_SPEED*1000,self.current_time,periodic=True)
        self.blink_banner_timer=Timer(500,self.current_time,periodic=True)
        self.new_apple_timer=Timer(Constants.NEW_APPLE_PERIOD*1000,self.current_time,periodic=True)
Ejemplo n.º 15
0
    def __init__(self, photolist, photoframe):

        self.gui = Gtk.Builder()
        self.gui.add_from_file(os.path.join(constants.SHARED_DATA_DIR, 'menu.ui'))

        self.photoimage = photoframe.photoimage
        self.photolist = photolist

        self.preferences = Preferences(photolist)
        self.about = AboutDialog()

        self.is_show = False
Ejemplo n.º 16
0
	def OnOpen(self, event):
		# get a valid path from user
		dirDialog = wx.DirDialog(self, "Choose a directory for open:", \
			style=wx.DD_DEFAULT_STYLE)
		if platform.system() == 'Windows':
			dirDialog.SetPath('D:\\Projects\\treeseal-example') # TESTING
		else:
			dirDialog.SetPath('/home/phil/Projects/treeseal-example') # TESTING

		if dirDialog.ShowModal() == wx.ID_OK:
			self.UpdateRootDir(dirDialog.GetPath())
		else:
			self.UpdateRootDir(None)
			return

		# check pre-conditions
		if not os.path.exists(self.metaDir):
			wx.MessageBox('Path "' + self.rootDir + '" is no valid root dir.', \
				'Error', wx.OK | wx.ICON_ERROR)
			self.UpdateRootDir(None)
			return
		if not os.path.exists(self.dbFile):
			wx.MessageBox('Cannot find database file "' + self.dbFile + '".', \
				'Error', wx.OK | wx.ICON_ERROR)
			self.UpdateRootDir(None)
			return
		if not os.path.exists(self.sigFile):
			dial = wx.MessageBox('Cannot find database signature file "' + self.sigFile + '".\n\nUse database without verification?', \
				'Warning', wx.YES_NO | wx.ICON_WARNING | wx.NO_DEFAULT)
			if not dial == wx.YES:
				self.UpdateRootDir(None)
				return
		else:
			cs = Checksum()
			cs.calculateForFile(self.dbFile)
			if not cs.isValidUsingSavedFile(self.sigFile):
				dial = wx.MessageBox('Database or database signature file have been corrupted.\n\nUse database without verification?', \
					'Warning', wx.YES_NO | wx.ICON_WARNING | wx.NO_DEFAULT)
				if not dial == wx.YES:
					self.UpdateRootDir(None)
					return

		# close eventually existing previous instance
		self.list.ClearInstance()
		self.SetStatusBarText()

		# load preferences or create default ones
		self.preferences = Preferences()
		if os.path.exists(self.preferencesFile):
			self.preferences.load(self.preferencesFile)
		else:
			self.preferences.save(self.preferencesFile)
Ejemplo n.º 17
0
 def activate(self, shell):
     config = self.config
     config.print_configuration(self)
     rbhandler = RBHandler(shell)
     
     components = {'config' : config, 'RB' : rbhandler}
     
     application = CGIApplication('RhythmWeb', self.base_path, components)
     
     server = CGIServer(application, config)
     server.start()
     shell.server = server
     
     self.preferences = Preferences(config, self.config_path)
Ejemplo n.º 18
0
    def __init__(self):
        pygame.init()
        pygame.display.init()
        pygame.font.init()

        self.screen_w = pygame.display.Info().current_w
        self.screen_h = pygame.display.Info().current_h
        self.w = int(self.screen_h * 1.2)
        self.h = int(self.screen_h * 0.8)

        self.preferences = Preferences()
        self.fullscreen = self.preferences.get("fullscreen")
        self.go_mode()

        pygame.mouse.set_visible(False)

        pygame.display.set_caption(Constants.CAPTION)
Ejemplo n.º 19
0
def home(request):
	context = RequestContext(request)
	context_dict = get_context_dict(request)

	menu_path = os.path.join(conf.settings.PROJECT_ROOT, 'menu.txt')
	menu = MenuParser(menu_path)
	menu = menu.parse_menu()
	preferences = context_dict['userprofile'].preferences
	preferences = Preferences.createFromString(preferences)
	matches = menu.match_with(preferences)
	html = ""
	for item in matches.get_items(): # TODO: make menu object iterable
		html += "<div style='margin-bottom: 4px; width: 400px; float left;'>"
		html += "<font style='text-decoration: underline;'>"+item.name+"</font><font color='black'> for "+item.meal+" @ "+item.location+"</font>"
		html += "</div>"
	context_dict['matches'] = html
	return render_to_response("foodfinder/home.html", context_dict, context)
Ejemplo n.º 20
0
    def confirm_and_reset_defaults(self, widget):
        if utilityFunctions.decision_popup(self.parent, 'Reset appearance to defaults?',
           'Are you sure you want to reset your appearance preferences to default values?'):
            self.choices = Preferences.default_appearance_preferences()

            # Visual Effects
            # Set the view combo box to "Double" which is the second entry
            model = self.view_box.get_model()
            self.view_box.set_active_iter(model.iter_next(model.get_iter_first()))

            # Set the font buttons to display the default font values
            for fb, fi in zip(self.font_buttons, self.font_idents):
                fb.set_font_name(self.choices[fi])
                fb.emit("font_set")

            # Set the color buttons to display the default color values
            for cb, ci in zip(self.color_buttons, self.color_idents):
                cb.set_rgba(utilityFunctions.string_to_RGBA(self.choices[ci]))
Ejemplo n.º 21
0
 def __init__(self):
     appdata = str(QDesktopServices.storageLocation(QDesktopServices.DataLocation))
     MusicGuruBase.__init__(self, appdata)
     ApplicationBase.__init__(self)
     if not op.exists(appdata):
         os.makedirs(appdata)
     logging.basicConfig(filename=op.join(appdata, 'debug.log'), level=logging.WARNING)
     self.prefs = Preferences()
     self.prefs.load()
     self.selectedBoardItems = []
     self.selectedLocation = None
     self.mainWindow = MainWindow(app=self)
     self.locationsPanel = LocationsPanel(app=self)
     self.detailsPanel = DetailsPanel(app=self)
     self.ignoreBox = IgnoreBox(app=self)
     self.progress = Progress(self.mainWindow)
     self.aboutBox = AboutBox(self.mainWindow, self)
     
     self.connect(self.progress, SIGNAL('finished(QString)'), self.jobFinished)
     self.connect(self, SIGNAL('applicationFinishedLaunching()'), self.applicationFinishedLaunching)
 def __init__(self):
   """Initializes the window and create pointers for all the important widgets.
   This function also runs some code to add functionality.
   """
   
   # Initialize the window and several other objects in the instance
   self.initialize_window()
   
   # Properties instance to handle the preferences window
   self.preferences = Preferences(self.main_window)
   
   # Now setup the variables needed for file access 
   try:
     self.setup_file_access()
   except Exception, e:
     # In case of error, the user must change the preferences
     log(e.__class__.__name__)
     log(e)
     self.preferences.run()
     self.setup_file_access()
Ejemplo n.º 23
0
  def _do_load(self):

    self._config = deluge.configmanager.ConfigManager(
        GTKUI_CONFIG, defaults=GTKUI_DEFAULTS)

    component.get("TorrentView").add_text_column(DISPLAY_NAME,
        status_field=[STATUS_NAME])

    self.label_selection_menu = LabelSelectionMenu()
    self.sep = component.get("MenuBar").add_torrentmenu_separator()
    component.get("MenuBar").torrentmenu.append(self.label_selection_menu)

    self.label_sidebar = LabelSidebar()

    self.preferences = Preferences()

    self.add_torrent_ext = AddTorrentExt()

    self.enable_dnd()

    self.initialized = True
Ejemplo n.º 24
0
    def __init__(self):
        super(App, self).__init__("HipStatus")
        self.icon = _menu_bar_icon(0)
        self.preferences = Preferences()
        self._validate_preferences()

        self.keychain = Keychain(self.preferences.email())
        self._validate_keychain()

        self.hipchat = HipChat(self.keychain.read_token())
        self.office365 = Office365(self.preferences.email(), self.keychain.read_o365())

        self.menu_pause_button = rumps.MenuItem("Pause HipStatus", self.timer_pause)
        self.menu_preferences = rumps.MenuItem('Preferences...')

        self.menu = [self.menu_pause_button, rumps.separator, self.menu_preferences, rumps.separator]

        self.menu_preferences_message = rumps.MenuItem("", self.preferences_message)
        if self.preferences.default_message():
            self.menu_preferences_message.title = self.preferences.default_message()
        else:
            self.menu_preferences_message.title = "None..."

        self.menu_preferences_email = rumps.MenuItem("Change email address", self.preferences_update_email)
        self.menu_preferences_o365 = rumps.MenuItem("Update saved Office 365 password", self.preferences_update_o365)
        self.menu_preferences_token = rumps.MenuItem("Update saved HipChat token", self.preferences_update_token)
        self.menu_preferences_get_token = rumps.MenuItem("Get your HipChat token", open_browser)

        self.menu_preferences.add(rumps.MenuItem('Status message...'))
        self.menu_preferences.add(self.menu_preferences_message)
        self.menu_preferences.add(rumps.separator)
        self.menu_preferences.add(rumps.MenuItem('Preferences...'))
        self.menu_preferences.add(self.menu_preferences_email)
        self.menu_preferences.add(self.menu_preferences_o365)
        self.menu_preferences.add(self.menu_preferences_token)
        self.menu_preferences.add(rumps.separator)
        self.menu_preferences.add(self.menu_preferences_get_token)

        self.main_timer = rumps.Timer(self.timer_trigger, 300)
        self.main_timer.start()
Ejemplo n.º 25
0
class App(rumps.App):
    """This is the main class that runs the HipStatus app"""
    def __init__(self):
        super(App, self).__init__("HipStatus")
        self.icon = _menu_bar_icon(0)
        self.preferences = Preferences()
        self._validate_preferences()

        self.keychain = Keychain(self.preferences.email())
        self._validate_keychain()

        self.hipchat = HipChat(self.keychain.read_token())
        self.office365 = Office365(self.preferences.email(), self.keychain.read_o365())

        self.menu_pause_button = rumps.MenuItem("Pause HipStatus", self.timer_pause)
        self.menu_preferences = rumps.MenuItem('Preferences...')

        self.menu = [self.menu_pause_button, rumps.separator, self.menu_preferences, rumps.separator]

        self.menu_preferences_message = rumps.MenuItem("", self.preferences_message)
        if self.preferences.default_message():
            self.menu_preferences_message.title = self.preferences.default_message()
        else:
            self.menu_preferences_message.title = "None..."

        self.menu_preferences_email = rumps.MenuItem("Change email address", self.preferences_update_email)
        self.menu_preferences_o365 = rumps.MenuItem("Update saved Office 365 password", self.preferences_update_o365)
        self.menu_preferences_token = rumps.MenuItem("Update saved HipChat token", self.preferences_update_token)
        self.menu_preferences_get_token = rumps.MenuItem("Get your HipChat token", open_browser)

        self.menu_preferences.add(rumps.MenuItem('Status message...'))
        self.menu_preferences.add(self.menu_preferences_message)
        self.menu_preferences.add(rumps.separator)
        self.menu_preferences.add(rumps.MenuItem('Preferences...'))
        self.menu_preferences.add(self.menu_preferences_email)
        self.menu_preferences.add(self.menu_preferences_o365)
        self.menu_preferences.add(self.menu_preferences_token)
        self.menu_preferences.add(rumps.separator)
        self.menu_preferences.add(self.menu_preferences_get_token)

        self.main_timer = rumps.Timer(self.timer_trigger, 300)
        self.main_timer.start()

    def _validate_preferences(self):
        if not self.preferences.email().strip():
            logging.warning("No email address on record in preferences")
            self.preferences_update_email(None)

    def _validate_keychain(self):
        try:
            self.keychain.read_o365()
        except KeychainValueNotFound:
            logging.warning("Office 365 password not found")
            self.keychain.write_o365("Enter Password")
            self.preferences_update_o365(None, menu_call=False)

        try:
            self.keychain.read_token()
        except KeychainValueNotFound:
            logging.warning("HipChat API token not found")
            self.keychain.write_token("Enter Token")
            self.preferences_update_token(None, menu_call=False)

    @rumps.notifications
    def notification_center(self, info):
        logging.debug("Notification has been clicked")
        if 'update_o365' in info:
            self.preferences_update_o365(None)
        elif 'update_token' in info:
            self.preferences_update_token(None)
        elif 'update_email' in info:
            self.preferences_update_email(None)
        elif 'open_ticket' in info:
            webbrowser.open(info['open_ticket'])
        else:
            pass

    def preferences_message(self, sender):
        text = self.preferences.default_message()
        if text is None:
            text = ''
        prompt = rumps.Window("Leave blank to not set a status message",
                              "Enter a message to display when you are set to 'Do not disturb'", text,
                              dimensions=(275, 25))
        result = prompt.run()
        self.preferences.default_message(result.text)
        if self.preferences.default_message():
            self.menu_preferences_message.title = self.preferences.default_message()
        else:
            self.menu_preferences_message.title = "None..."

    def preferences_update_email(self, sender):
        text = self.preferences.email()
        logging.info("Prompting for new email")
        prompt = rumps.Window("", "Enter your email address", text, dimensions=(275, 25))
        result = prompt.run()
        self.preferences.email(result.text)

    def preferences_update_o365(self, sender, message="", menu_call=True):
        text = self.keychain.read_o365()
        logging.info("Prompting for Office 365 password...")
        prompt = SecureRumpsWindow(message, "Enter your Office 365 password:"******"", menu_call=True):
        text = self.keychain.read_token()
        message = "Paste your key using Ctrl+Click on the text field"
        logging.info("Prompting for HipChat API token...")
        prompt = rumps.Window(message, "Enter your HipChat API token:", text, dimensions=(375, 25))
        prompt.add_button('Get HipChat token...')
        result = prompt.run()

        if result.clicked == 2:
            open_browser()
            self.preferences_update_token(None, "Log into HipChat in the browser to copy your token, paste using "
                                          "Ctrl+Click on the text field",
                                          menu_call=menu_call)
        else:
            token = result.text
            self.keychain.write_token(token)
            if menu_call:
                self.hipchat.update_token(self.keychain.read_token())

    def timer_pause(self, sender):
        if not sender.state:
            self.icon = _menu_bar_icon(1)
            sender.title = "Resume HipStatus"
            logging.info("User has paused HipStatus")
        else:
            self.icon = _menu_bar_icon(0)
            sender.title = "Pause HipStatus"
            logging.info("User has resumed HipStatus")

        sender.state = not sender.state

    def timer_trigger(self, sender):
        now = datetime.datetime.now()
        delta = (5 - (now.minute % 5)) * 60 - now.second
        logging.debug("Timer will execute in {} seconds".format(delta))
        t = threading.Thread(target=self._update_status, args=[delta])
        t.start()

    def _update_status(self, delay):
        time.sleep(delay)
        if self.menu_pause_button.state:
            logging.info("HipStatus is paused: status will not be updated")
            return

        now = datetime.datetime.utcnow().strftime("%Y-%m-%d %H:%M:%S")
        try:
            hipchat_user = self.hipchat.get_status(self.preferences.email())
        except Unauthorized:
            rumps.notification("Authentication error to HipChat",'',
                               "It looks like something may be wrong with your API token. Click here to update, or use "
                               "the 'Preferences...' menu option.",
                               data={'update_token': ''})
            return

        except UserNotFound:
            rumps.notification("Could not find the user in HipChat", self.preferences.email(),
                               "Your saved email address could not be found in HipChat. Click here to update, or use "
                               "the 'Preferences...' menu option.", data={'update_email': ''})
            return

        except (RateLimited, ServerError, ServiceUnavailable):
            rumps.notification("There seems to be a problem with HipChat", '', "There was an error indicating an issue "
                               "on HipChat's end. If the issue persists click here to open an IT Help ticket.",
                               data={'open_ticket': ticket_url})
            return

        if not hipchat_user['presence']:
            logging.info("The user is not online")
            return

        busy_hipstatus = True if hipchat_user['presence']['show'] != 'chat' else False

        try:
            office365_calendar = self.office365.calendar_status(now)
        except Unauthorized:
            rumps.notification("Authentication error to Office 365", '',
                               "Something may be wrong with your Office 365 email address/password. Click here to try "
                               "updating your password.", data={'update_o365': ''})
            return

        except ServerError:
            rumps.notification("There seems to be a problem with Office 365", '', "There was an error indicating an "
                               "issue on Office 365's end. If the issue persists click here to open an IT Help ticket.",
                               data={'open_ticket': ticket_url})
            return

        if office365_calendar['value']:
            busy_office365 = True if office365_calendar['value'][0]['ShowAs'] == 'Busy' else False
        else:
            busy_office365 = False

        if busy_hipstatus == busy_office365:
            logging.info("Status unchanged")
            return

        message = ''
        update_data = {
            'name': hipchat_user['name'],
            'email': hipchat_user['email'],
            'mention_name': hipchat_user['mention_name'],
            'title': hipchat_user['title'],
            'timezone': self.preferences.timezone(),
            'is_group_admin': hipchat_user['is_group_admin'],
            'presence': {
                'status': None,
                'show': None,
            }
        }

        if busy_hipstatus and not busy_office365:
            logging.info("Setting HipChat status to 'Available'")
            update_data['presence']['status'] = ''
            update_data['presence']['show'] = None
            message = "You are now 'Available'"

        elif busy_office365 and not busy_hipstatus:
            logging.info("Setting HipChat status to 'Do not disturb'")
            update_data['presence']['status'] = self.preferences.default_message()
            update_data['presence']['show'] = 'dnd'
            message = "You are now set to 'Do not disturb'"

        self.hipchat.update_status(update_data)
        rumps.notification("Status Updated", message, "Your status in HipChat has been updated", sound=False)
Ejemplo n.º 26
0
        markdowner.on_focus_gained()
        self.web.setFocus()
        self.web.eval("focusField(%d);" % self.currentField)
        note.tags = tags
        try:
            time.sleep(0.001)
            self.updateTags()
        except AttributeError as e:
            print e  # TODO: log error
        utility.end_safe_block(const.MARKDOWN_PREFS)


def init_hook(self, mw, widget, parentWindow, addMode=False):
    addHook("editFocusGained", self.on_focus_gained)

Preferences.init()

if preferences.PREFS.get(const.MARKDOWN):
    editor.Editor.on_focus_gained = on_focus_gained
    editor.Editor.__init__ = wrap(editor.Editor.__init__, init_hook)

editor.Editor.create_button = create_button
editor.Editor.toggleMarkdown = toggleMarkdown
editor.Editor.toggleHeading = toggleHeading
editor.Editor.toggleAbbreviation = toggleAbbreviation
editor.Editor.toggleHyperlink = toggleHyperlink
editor.Editor.remove_garbage = remove_garbage
editor.Editor.unlink = unlink
editor.Editor.justifyFull = justifyFull
editor.Editor.justifyRight = justifyRight
editor.Editor.justifyLeft = justifyLeft
Ejemplo n.º 27
0
class PopUpMenu(object):

    def __init__(self, photolist, photoframe):

        self.gui = Gtk.Builder()
        self.gui.add_from_file(os.path.join(constants.SHARED_DATA_DIR, 'menu.ui'))

        self.photoimage = photoframe.photoimage
        self.photolist = photolist

        self.preferences = Preferences(photolist)
        self.about = AboutDialog()

        self.is_show = False

    def start(self, widget, event):
        self.set_recent_menu()

        if SETTINGS.get_boolean('window-fix'):
            self.gui.get_object('menuitem6').set_active(True)

        photo = self.photoimage.photo
        accessible = photo.can_open() if photo else False
        self.set_open_menu_sensitive(accessible)

        is_fullscreen = SETTINGS.get_boolean('fullscreen')
        self.gui.get_object('menuitem8').set_active(is_fullscreen)

        self.gui.connect_signals(self)

        menu = self.gui.get_object('menu')
        menu.popup(None, None, None, None, event.button, event.time)
        self.is_show = True

    def set_recent_menu(self):
        RecentMenu(self.gui, self.photolist)

    def set_open_menu_sensitive(self, state):
        self.gui.get_object('menuitem5').set_sensitive(state)


    def on_menuitem5_activate(self, *args):
        "open_photo"
        self.photoimage.photo.open()

    def on_next_photo(self, *args):
        self.photolist.next_photo(*args)

    def on_menuitem8_toggled(self, widget, *args):
        "_full_screen_cb"
        SETTINGS.set_boolean('fullscreen', widget.get_active())

    def on_menuitem6_toggled(self, widget):
        "_fix_window_cb"
        SETTINGS.set_boolean('window-fix', widget.get_active())

    def on_prefs(self, *args):
        self.preferences.start(*args)

    def on_help(self, widget):
        Gtk.show_uri(None, 'ghelp:gphotoframe', Gdk.CURRENT_TIME)

    def on_about(self, *args):
        self.about.start()

    def on_quit(self, *args):
        self.photolist.queue.clear_cache()
        reactor.stop()

    def on_menu_hide(self, *args):
        self.is_show = False
Ejemplo n.º 28
0
    def view_preferences(self):
        self.manager.current = 'preferences'

        self.preferences = Preferences()
Ejemplo n.º 29
0
class Indicator:

    # ----------------------------------------------------------------------- #
    def __init__(self, player):

        # apparently appindicator will not quit on Ctrl-C by default. fix
        # bellow allows it to do so in Ctrl-C run the default action kernel
        # action which allows indicator to exit
        signal.signal(signal.SIGINT, signal.SIG_DFL)

        # expose the passing player to tht class
        self._player = player

        # remove registration to dbus, disabling MPRIS integration, mainly this
        # is done because current anoise MPRIS integration does not notify the
        # GUI element of play/pause/next/forward changes internally an attempt
        # at dbus manager that listens for anoise mpris notification fails due
        # to double signaling and handling of multiple MPRIS subscribed clients
        # and inability to distinguish which come from anoise
        self._player.sound_menu.remove_from_connection()

        #: DEBUG SETTING, used during development
        #: hide window ui, if it's the GUI class (rather then Indicator class)
        # if self._player.window.__class__.__name__ == 'GUI':
        #     self._player.window.window.hide()

        # build the preferences window
        self._preferences_window = Preferences(self)

        # expose the default gtk settings
        self._gtk_settings = Gtk.Settings.get_default()

        # expose the default icon theme
        self._default_icon_theme = Gtk.IconTheme.get_default()

        # expose "hicolor" theme as fallback theme
        self._fallback_icon_theme = Gtk.IconTheme()
        self._fallback_icon_theme.set_custom_theme('hicolor')

        # expose found appindicator and appindicator-pause icons
        self._appindicator_icon, self._appindicator_icon_pause = \
            self._get_indicator_icons()

        # build the appindicator
        self._appindicator, builder = self._make_appindicator()

        # expose the play/pause menu item to the class
        self._menuitem_play = builder.get_object('play_pause_toggle')
        # expose now playing menu item
        self._menuitem_now_playing = builder.get_object('now_playing')

        # expose now playing image
        self._image_now_playing = builder.get_object('image_now_playing')
        # expose play image
        self._image_play = builder.get_object('image_play')
        # expose pause image
        self._image_pause = builder.get_object('image_pause')

        # disable startup autoplay (ugh, terrible approach)
        # runs before indicator is made visible to show the "paused" icon
        self._disable_startup_autoplay()

        # set the indicator status to active
        self._appindicator.set_status(AppIndicator3.IndicatorStatus.ACTIVE)

        # update the noise icon in the ui and the appindicator
        self._update_now_playing()

    # ----------------------------------------------------------------------- #
    def set_timer(self, enable, seconds):
        # method is run by preferences window code, which is why it's public

        # it's strange that this code is run in the UI code.
        # if window ui and appindicator will both install you will end up with
        # two timers, so seems like runing both "ui"s is not a good idea
        # exclusive, unless preferences can be a singleton

        if enable:
            self.timer = threading.Timer(seconds, self._set_future_pause)
            self.timer.start()
        else:
            self.timer.cancel()

    # ----------------------------------------------------------------------- #
    def _disable_startup_autoplay(self):
        """
        Disable auto play on aplication startup. This is done by patching
        the self._player._sound_menu_play with function that pauses the player
        insteady of playing it, and the restores the original function after it
        was ran once. Unfortunately this is the only way to do this at this
        point.
        """

        # set all the gui statuses to "pause"
        self._pause()
        # preserve the original function
        original_func = self._player._sound_menu_play

        # create a patched function which pauses the play when run the FIRST
        # time and then restores the original _sound_menu_play to the player
        # object (sad, should not need to patch)
        def _sound_menu_play(*args, **kwargs):
            # pause
            self._player._sound_menu_pause()
            self._player._sound_menu_play = original_func

        # now patch the play function with our patched function
        self._player._sound_menu_play = _sound_menu_play

    # ----------------------------------------------------------------------- #
    def _make_appindicator(self):
        """
        Return constructed AppIndicator and it's menu.
        Also return the menu builder so we can update few of it's items
        """

        # get full glade file. assumption here is that the ui file in the same
        # folder as this script
        ui_file_path = os.path.join(
            os.path.realpath(os.path.dirname(__file__)), 'appindicator.ui')

        # force showing of images despite whatever the global setting is
        self._gtk_settings.props.gtk_button_images = True

        # build the apindicator menu from the glade file
        builder = Gtk.Builder()
        builder.add_from_file(ui_file_path)

        # create the appindicator
        appindicator = AppIndicator3.Indicator.new(
            APPINDICATOR_ID, self._appindicator_icon,
            AppIndicator3.IndicatorCategory.APPLICATION_STATUS)

        # get the appindicator menu
        menu = builder.get_object('appindicator_menu')

        # setup the signals for the appindicator menu items
        builder.connect_signals(self)

        # get the play/pause menu iterm
        menuitem_play = builder.get_object('play_pause_toggle')

        # setup to trigger play/pause menu action on appindicator middle click
        appindicator.set_secondary_activate_target(menuitem_play)

        # set all menu items visible
        menu.show_all()

        # attach to the menu to the appindicator
        appindicator.set_menu(menu)

        return appindicator, builder

    # ----------------------------------------------------------------------- #
    def _get_indicator_icons(self):

        icons = []

        # for over both default and fallback theme to get icons
        for theme in [self._default_icon_theme, self._fallback_icon_theme]:
            # try to find both regular and pause icons
            for icon_name in [APPINDICATOR_ICON, APPINDICATOR_ICON_PAUSE]:
                # break out of the loop if we failed to find any of the icons
                # and set the icon collection to an empty list
                if theme.has_icon(icon_name) is True:
                    icon_info = theme.lookup_icon(icon_name, Gtk.IconSize.MENU,
                                                  0)
                    # get icon file path
                    icons.append(icon_info.get_filename())
                else:
                    icons = []
                    break

            # if we found both icons break out
            if len(icons) == 2 or all(icons) is True:
                break

        # if we could not find 2 icons fallback to very generic icons
        if len(icons) != 2 or all(icons) is False:
            icons = APPINDICATOR_ICONS_FALLBACK

        return icons

    # ----------------------------------------------------------------------- #
    def _on_toggle_play_pause_activate(self, widget):
        if self._player.is_playing:
            self._player._sound_menu_pause()
            self._pause()
        else:
            self._player._sound_menu_play()
            self._play()

    # ----------------------------------------------------------------------- #
    def _on_next_activate(self, widget):
        # tell the player to play next track
        self._player._set_new_play('next')
        # update noise status
        self._update_now_playing()

    # ----------------------------------------------------------------------- #
    def _on_previous_activate(self, widget):
        # tell the player to play track
        self._player._set_new_play('previous')
        # update noise status
        self._update_now_playing()

    # ----------------------------------------------------------------------- #
    def _on_preferences_window_show_activate(self, widget):
        self._preferences_window.show()

    # ----------------------------------------------------------------------- #
    def _on_about_activate(self, widget):
        # open default web browser to the homepage
        webbrowser.open_new('http://anoise.tuxfamily.org')

    # ----------------------------------------------------------------------- #
    def _on_quit_activate(self, widget):
        # try to cancel the timer catching all (really?) exceptions
        try:
            self.timer.cancel()
        except Exception:
            pass

        # tell gtk main loop to quit
        Gtk.main_quit()

    # ----------------------------------------------------------------------- #
    def _update_now_playing(self):
        # try to get the noise icon file, otherwise fallback to the default
        # note: it does not throw a specific error we can test for so
        #       we are testing for Exception
        try:
            # get the icon file name for the existing noise
            icon_file = self._player.noise.get_icon().replace('file://', '')
            fallback_icon_name = None
        except Exception:
            # retrieve the default application icon from the icon as a pixbuf
            icon_file = APPINDICATOR_ICON
            fallback_icon_name = PLAYING_NOW_FALLBACK_ICON

        # get the now playing noise
        now_playing = self._player.noise.get_name()
        # form "Not Playing: <noise>" string for the indicator
        new_label = "Now Playing: %s" % now_playing
        # update the indicator now playing label to the noise name
        self._menuitem_now_playing.set_label(new_label)

        # update the now playing menu icon
        #
        # if fallback icon name is not set then we set the found noise icon
        # otherwise we set the set the image to the fallback icons
        if fallback_icon_name is None:
            self._image_now_playing.set_from_file(icon_file)
        else:
            self._image_now_playing.set_from_icon_name(fallback_icon_name,
                                                       Gtk.IconSize.MENU)

        # update the now playing menu item with the now playing image
        self._menuitem_now_playing.set_image(self._image_now_playing)

    # ----------------------------------------------------------------------- #
    def _play(self):
        # tell player to play
        self._menuitem_play.set_label("P_ause")
        self._menuitem_play.set_image(self._image_pause)
        self._appindicator.set_icon(self._appindicator_icon)
        self._update_now_playing()

    # ----------------------------------------------------------------------- #
    def _pause(self):
        # pause the player
        self._menuitem_play.set_label("_Play")
        self._menuitem_play.set_image(self._image_play)
        self._appindicator.set_icon(self._appindicator_icon_pause)
        self._update_now_playing()

    # ----------------------------------------------------------------------- #
    def _set_future_pause(self):
        self._preferences_window.set_show_timer()
        self._player._sound_menu_pause()
        self._pause()
Ejemplo n.º 30
0
    def __init__(self, context, editor):
        PanelView.__init__(self, context)
        self._editor = editor
        self._base_handlers = {}

        self.set_orientation(Gtk.Orientation.VERTICAL)

        self._preferences = Preferences()

        grid = Gtk.Grid()
        grid.set_orientation(Gtk.Orientation.VERTICAL)
        self.add(grid)

        # toolbar

        btn_follow = Gtk.ToggleToolButton.new_from_stock(Gtk.STOCK_CONNECT)
        btn_follow.set_tooltip_text(_("Follow Editor"))
        btn_follow.set_active(
            self._preferences.get("outline-connect-to-editor"))
        self._base_handlers[btn_follow] = btn_follow.connect(
            "toggled", self._on_follow_toggled)

        btn_expand = Gtk.ToolButton.new_from_stock(Gtk.STOCK_ZOOM_IN)
        btn_expand.set_tooltip_text(_("Expand All"))
        self._base_handlers[btn_expand] = btn_expand.connect(
            "clicked", self._on_expand_clicked)

        btn_collapse = Gtk.ToolButton.new_from_stock(Gtk.STOCK_ZOOM_OUT)
        btn_collapse.set_tooltip_text(_("Collapse All"))
        self._base_handlers[btn_collapse] = btn_collapse.connect(
            "clicked", self._on_collapse_clicked)

        self._toolbar = Gtk.Toolbar()
        self._toolbar.set_style(Gtk.ToolbarStyle.ICONS)
        self._toolbar.set_icon_size(Gtk.IconSize.MENU)
        self._toolbar.insert(btn_follow, -1)
        self._toolbar.insert(Gtk.SeparatorToolItem(), -1)
        self._toolbar.insert(btn_expand, -1)
        self._toolbar.insert(btn_collapse, -1)
        self._toolbar.insert(Gtk.SeparatorToolItem(), -1)
        self._toolbar.set_hexpand(True)

        grid.add(self._toolbar)

        # tree view

        column = Gtk.TreeViewColumn()

        pixbuf_renderer = Gtk.CellRendererPixbuf()
        column.pack_start(pixbuf_renderer, False)
        column.add_attribute(pixbuf_renderer, "pixbuf", 1)

        text_renderer = Gtk.CellRendererText()
        column.pack_start(text_renderer, True)
        column.add_attribute(text_renderer, "markup", 0)

        self._offset_map = OutlineOffsetMap()

        self._store = Gtk.TreeStore(str, GdkPixbuf.Pixbuf,
                                    object)  # label, icon, node object

        self._view = Gtk.TreeView(model=self._store)
        self._view.append_column(column)
        self._view.set_headers_visible(False)
        self._cursor_changed_id = self._view.connect("cursor-changed",
                                                     self._on_cursor_changed)
        self._base_handlers[self._view] = self._view.connect(
            "row-activated", self._on_row_activated)

        scrolled = Gtk.ScrolledWindow()
        scrolled.add(self._view)
        scrolled.set_policy(Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC)
        scrolled.set_vexpand(True)

        grid.add(scrolled)

        # this holds a list of the currently expanded paths
        self._expandedPaths = None
Ejemplo n.º 31
0
class GtkUI(object):
    def __init__(self, args):
        self.daemon_bps = (0, 0, 0)
        # Setup signals
        try:
            import gnome.ui
            import gnome

            #Suppress: Warning: Attempt to add property GnomeProgram::*** after class was initialised
            original_filters = warnings.filters[:]
            warnings.simplefilter("ignore")
            try:
                self.gnome_prog = gnome.init("Deluge",
                                             deluge.common.get_version())
            finally:
                warnings.filters = original_filters

            self.gnome_client = gnome.ui.master_client()

            def on_die(*args):
                reactor.stop()

            self.gnome_client.connect("die", on_die)
            log.debug("GNOME session 'die' handler registered!")
        except Exception, e:
            log.warning(
                "Unable to register a 'die' handler with the GNOME session manager: %s",
                e)

        if deluge.common.windows_check():
            from win32api import SetConsoleCtrlHandler
            from win32con import CTRL_CLOSE_EVENT
            from win32con import CTRL_SHUTDOWN_EVENT

            def win_handler(ctrl_type):
                log.debug("ctrl_type: %s", ctrl_type)
                if ctrl_type in (CTRL_CLOSE_EVENT, CTRL_SHUTDOWN_EVENT):
                    reactor.stop()
                    return 1

            SetConsoleCtrlHandler(win_handler)

        if deluge.common.osx_check() and gtk.gdk.WINDOWING == "quartz":
            import gtkosx_application
            self.osxapp = gtkosx_application.gtkosx_application_get()

            def on_die(*args):
                reactor.stop()

            self.osxapp.connect("NSApplicationWillTerminate", on_die)

        # Set process name again to fix gtk issue
        setproctitle(getproctitle())

        # Attempt to register a magnet URI handler with gconf, but do not overwrite
        # if already set by another program.
        common.associate_magnet_links(False)

        # Make sure gtkui.conf has at least the defaults set
        self.config = deluge.configmanager.ConfigManager(
            "gtkui.conf", DEFAULT_PREFS)

        # We need to check on exit if it was started in classic mode to ensure we
        # shutdown the daemon.
        self.started_in_classic = self.config["classic_mode"]

        # Start the IPC Interface before anything else.. Just in case we are
        # already running.
        self.queuedtorrents = QueuedTorrents()
        self.ipcinterface = IPCInterface(args)

        # Initialize gdk threading
        gtk.gdk.threads_init()
        gobject.threads_init()

        # We make sure that the UI components start once we get a core URI
        client.set_disconnect_callback(self.__on_disconnect)

        self.trackericons = TrackerIcons()
        self.sessionproxy = SessionProxy()
        # Initialize various components of the gtkui
        self.mainwindow = MainWindow()
        self.menubar = MenuBar()
        self.toolbar = ToolBar()
        self.torrentview = TorrentView()
        self.torrentdetails = TorrentDetails()
        self.sidebar = SideBar()
        self.filtertreeview = FilterTreeView()
        self.preferences = Preferences()
        self.systemtray = SystemTray()
        self.statusbar = StatusBar()
        self.addtorrentdialog = AddTorrentDialog()

        if deluge.common.osx_check() and gtk.gdk.WINDOWING == "quartz":

            def nsapp_open_file(osxapp, filename):
                # Ignore command name which is raised at app launch (python opening main script).
                if filename == sys.argv[0]:
                    return True
                from deluge.ui.gtkui.ipcinterface import process_args
                process_args([filename])

            self.osxapp.connect("NSApplicationOpenFile", nsapp_open_file)
            from menubar_osx import menubar_osx
            menubar_osx(self, self.osxapp)
            self.osxapp.ready()

        # Initalize the plugins
        self.plugins = PluginManager()

        # Show the connection manager
        self.connectionmanager = ConnectionManager()

        from twisted.internet.task import LoopingCall
        rpc_stats = LoopingCall(self.print_rpc_stats)
        rpc_stats.start(10)

        reactor.callWhenRunning(self._on_reactor_start)
        # Start the gtk main loop
        gtk.gdk.threads_enter()
        reactor.run()
        self.shutdown()
        gtk.gdk.threads_leave()
Ejemplo n.º 32
0
class IssueView(PanelView):
    """
    """

    _log = getLogger("IssueView")

    def __init__(self, context, editor):
        PanelView.__init__(self, context)
        self._log.debug("init")

        self._editor = editor
        self._handlers = {}
        self._preferences = Preferences()

        self._preferences.connect("preferences-changed", self._on_preferences_changed)
        self._show_tasks = self._preferences.get("issues-show-tasks")
        self._show_warnings = self._preferences.get("issues-show-warnings")

        self._icons = { Issue.SEVERITY_WARNING : GdkPixbuf.Pixbuf.new_from_file(Resources().get_icon("warning.png")),
                        Issue.SEVERITY_ERROR : GdkPixbuf.Pixbuf.new_from_file(Resources().get_icon("error.png")),
                        Issue.SEVERITY_INFO : None,
                        Issue.SEVERITY_TASK : GdkPixbuf.Pixbuf.new_from_file(Resources().get_icon("task.png")) }

        grid = Gtk.Grid()
        self.add(grid)

        self._store = Gtk.ListStore(GdkPixbuf.Pixbuf, str, str, object)

        self._view = Gtk.TreeView(model=self._store)

        column = Gtk.TreeViewColumn()
        column.set_title(_("Message"))

        pixbuf_renderer = Gtk.CellRendererPixbuf()
        column.pack_start(pixbuf_renderer, False)
        column.add_attribute(pixbuf_renderer, "pixbuf", 0)

        text_renderer = Gtk.CellRendererText()
        column.pack_start(text_renderer, True)
        column.add_attribute(text_renderer, "markup", 1)

        self._view.append_column(column)

        column = Gtk.TreeViewColumn()
        column.set_title(_("File"))
        text_renderer2 = Gtk.CellRendererText()
        column.pack_start(text_renderer2, True)
        column.add_attribute(text_renderer2, "markup", 2)
        self._view.insert_column(column, -1)
        self._handlers[self._view] = self._view.connect("row-activated", self._on_row_activated)

        self._scr = Gtk.ScrolledWindow()

        self._scr.add(self._view)
        self._scr.set_policy(Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC)
        self._scr.set_shadow_type(Gtk.ShadowType.IN)
        self._scr.set_hexpand(True)
        self._scr.set_vexpand(True)

        grid.add(self._scr)

        # toolbar
        self._button_warnings = Gtk.ToggleToolButton()
        self._button_warnings.set_tooltip_text(_("Show/Hide Warnings"))
        image = Gtk.Image()
        image.set_from_file(Resources().get_icon("warning.png"))
        self._button_warnings.set_icon_widget(image)
        self._button_warnings.set_active(self._show_warnings)
        self._handlers[self._button_warnings] = self._button_warnings.connect("toggled", self.__on_warnings_toggled)

        self._button_tasks = Gtk.ToggleToolButton()
        self._button_tasks.set_tooltip_text(_("Show/Hide Tasks"))
        imageTask = Gtk.Image()
        imageTask.set_from_file(Resources().get_icon("task.png"))
        self._button_tasks.set_icon_widget(imageTask)
        self._button_tasks.set_active(self._show_tasks)
        self._handlers[self._button_tasks] = self._button_tasks.connect("toggled", self.__on_tasks_toggled)

        toolbar = Gtk.Toolbar()
        toolbar.set_orientation(Gtk.Orientation.VERTICAL)
        toolbar.set_style(Gtk.ToolbarStyle.ICONS)
        toolbar.set_icon_size(Gtk.IconSize.MENU)
        toolbar.insert(self._button_warnings, -1)
        toolbar.insert(self._button_tasks, -1)
        toolbar.set_vexpand(True)

        grid.add(toolbar)

        # theme like gtk3
        ctx = self._scr.get_style_context()
        ctx.set_junction_sides(Gtk.JunctionSides.RIGHT)

        ctx = toolbar.get_style_context()
        ctx.set_junction_sides(Gtk.JunctionSides.LEFT | Gtk.JunctionSides.RIGHT)
        ctx.add_class(Gtk.STYLE_CLASS_PRIMARY_TOOLBAR)

        self._issues = []

        self.show_all()

        self._log.debug("init finished")

    def get_label(self):
        return _("Issues")

    def get_icon(self):
        return Gtk.Image.new_from_stock(Gtk.STOCK_DIALOG_INFO, Gtk.IconSize.MENU)

    def _on_row_activated(self, view, path, column):
        """
        A row has been double-clicked on
        """
        issue = self._store.get(self._store.get_iter(path), 3)[0]

        self._context.activate_editor(issue.file)

        #~ # FIXME: this doesn't work correctly
        #~ if not self._context.active_editor is None:
            #~ self._context.active_editor.select(issue.start, issue.end)
        self._editor.select(issue.start, issue.end)

    def _on_preferences_changed(self, prefs, key, value):
        if key == "issues-show-warnings" or key == "issues-show-tasks":
            # update filter
            self._store.clear()
            for issue, local in self._issues:
                self._append_issue_filtered(issue, local)

    def __on_tasks_toggled(self, togglebutton):
        self._show_tasks = togglebutton.get_active()
        self._preferences.set("issues-show-tasks", self._show_tasks)

    def __on_warnings_toggled(self, togglebutton):
        self._show_warnings = togglebutton.get_active()
        self._preferences.set("issues-show-warnings", self._show_warnings)

    def clear(self):
        """
        Remove all issues from the view
        """
        self._store.clear()
        self._issues = []

    def append_issue(self, issue, local=True):
        """
        Append a new Issue to the view

        @param issue: the Issue object
        @param local: indicates whether the Issue occured in the edited file or not
        """
        self._issues.append((issue, local))
        self._append_issue_filtered(issue, local)

    def _append_issue_filtered(self, issue, local):
        if issue.severity == Issue.SEVERITY_WARNING:
            if self._show_warnings:
                self._do_append_issue(issue, local)
        elif issue.severity == Issue.SEVERITY_TASK:
            if self._show_tasks:
                self._do_append_issue(issue, local)
        else:
            self._do_append_issue(issue, local)

    def _do_append_issue(self, issue, local):
        if local:
            message = issue.message
            filename = escape(issue.file.basename)
        else:
            message = "<span color='%s'>%s</span>" % (self._preferences.get("light-foreground-color"), issue.message)
            filename = "<span color='%s'>%s</span>" % (self._preferences.get("light-foreground-color"), issue.file.basename)
        self._store.append([self._icons[issue.severity], message, filename, issue])
Ejemplo n.º 33
0
    def __init__(self, context, editor):
        PanelView.__init__(self, context)
        self._log.debug("init")

        self._editor = editor
        self._handlers = {}
        self._preferences = Preferences()

        self._preferences.connect("preferences-changed", self._on_preferences_changed)
        self._show_tasks = self._preferences.get("issues-show-tasks")
        self._show_warnings = self._preferences.get("issues-show-warnings")

        self._icons = { Issue.SEVERITY_WARNING : GdkPixbuf.Pixbuf.new_from_file(Resources().get_icon("warning.png")),
                        Issue.SEVERITY_ERROR : GdkPixbuf.Pixbuf.new_from_file(Resources().get_icon("error.png")),
                        Issue.SEVERITY_INFO : None,
                        Issue.SEVERITY_TASK : GdkPixbuf.Pixbuf.new_from_file(Resources().get_icon("task.png")) }

        grid = Gtk.Grid()
        self.add(grid)

        self._store = Gtk.ListStore(GdkPixbuf.Pixbuf, str, str, object)

        self._view = Gtk.TreeView(model=self._store)

        column = Gtk.TreeViewColumn()
        column.set_title(_("Message"))

        pixbuf_renderer = Gtk.CellRendererPixbuf()
        column.pack_start(pixbuf_renderer, False)
        column.add_attribute(pixbuf_renderer, "pixbuf", 0)

        text_renderer = Gtk.CellRendererText()
        column.pack_start(text_renderer, True)
        column.add_attribute(text_renderer, "markup", 1)

        self._view.append_column(column)

        column = Gtk.TreeViewColumn()
        column.set_title(_("File"))
        text_renderer2 = Gtk.CellRendererText()
        column.pack_start(text_renderer2, True)
        column.add_attribute(text_renderer2, "markup", 2)
        self._view.insert_column(column, -1)
        self._handlers[self._view] = self._view.connect("row-activated", self._on_row_activated)

        self._scr = Gtk.ScrolledWindow()

        self._scr.add(self._view)
        self._scr.set_policy(Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC)
        self._scr.set_shadow_type(Gtk.ShadowType.IN)
        self._scr.set_hexpand(True)
        self._scr.set_vexpand(True)

        grid.add(self._scr)

        # toolbar
        self._button_warnings = Gtk.ToggleToolButton()
        self._button_warnings.set_tooltip_text(_("Show/Hide Warnings"))
        image = Gtk.Image()
        image.set_from_file(Resources().get_icon("warning.png"))
        self._button_warnings.set_icon_widget(image)
        self._button_warnings.set_active(self._show_warnings)
        self._handlers[self._button_warnings] = self._button_warnings.connect("toggled", self.__on_warnings_toggled)

        self._button_tasks = Gtk.ToggleToolButton()
        self._button_tasks.set_tooltip_text(_("Show/Hide Tasks"))
        imageTask = Gtk.Image()
        imageTask.set_from_file(Resources().get_icon("task.png"))
        self._button_tasks.set_icon_widget(imageTask)
        self._button_tasks.set_active(self._show_tasks)
        self._handlers[self._button_tasks] = self._button_tasks.connect("toggled", self.__on_tasks_toggled)

        toolbar = Gtk.Toolbar()
        toolbar.set_orientation(Gtk.Orientation.VERTICAL)
        toolbar.set_style(Gtk.ToolbarStyle.ICONS)
        toolbar.set_icon_size(Gtk.IconSize.MENU)
        toolbar.insert(self._button_warnings, -1)
        toolbar.insert(self._button_tasks, -1)
        toolbar.set_vexpand(True)

        grid.add(toolbar)

        # theme like gtk3
        ctx = self._scr.get_style_context()
        ctx.set_junction_sides(Gtk.JunctionSides.RIGHT)

        ctx = toolbar.get_style_context()
        ctx.set_junction_sides(Gtk.JunctionSides.LEFT | Gtk.JunctionSides.RIGHT)
        ctx.add_class(Gtk.STYLE_CLASS_PRIMARY_TOOLBAR)

        self._issues = []

        self.show_all()

        self._log.debug("init finished")
Ejemplo n.º 34
0
 def __init__(self):
     self.preferences = Preferences("settings_default.yaml")
     self.mapping = None
Ejemplo n.º 35
0
 def openPrefs(self):
     prefs = Preferences()
     prefs.exec()
Ejemplo n.º 36
0
class MainWindow(QMainWindow, Ui_MainWindow):
    def __init__(self):
        super(MainWindow, self).__init__()
        self.setupUi(self)

        self.tableWidget_dropzone.setColumnCount(6)
        self.tableWidget_dropzone.setRowCount(9)
        self.tableWidget_dropzone.setAcceptDrops(True)
        self.tableWidget_dropzone.setColumnWidth(0, 128)
        self.tableWidget_dropzone.setColumnWidth(1, 64)
        self.tableWidget_dropzone.setColumnWidth(2, 128)
        self.tableWidget_dropzone.setColumnWidth(3, 64)
        self.tableWidget_dropzone.setColumnWidth(4, 128)
        self.tableWidget_dropzone.setColumnWidth(5, 64)
        self.tableWidget_dropzone.setHorizontalHeaderLabels([
            'A1 Sample IDs', 'Gender', 'A2 Sample IDs', 'Gender',
            'A3 Sample IDs', 'Gender'
        ])
        self.tableWidget_dropzone.setVerticalHeaderLabels(
            ['', 'R1', 'R2', 'R3', 'R4', 'R5', 'R6', 'R7', 'R8'])
        self.tableWidget_dropzone.setSpan(0, 0, 1, 2)
        self.tableWidget_dropzone.setSpan(0, 2, 1, 2)
        self.tableWidget_dropzone.setSpan(0, 4, 1, 2)

        # populate stuff
        # arrayUpload_settings = QSettings('vll', 'arrayUpload')
        # path_array_data_folder = arrayUpload_settings.value('path_array_data_folder', type=str)
        # dataComboBox1 = DataCombo(path_array_data_folder)
        # dataComboBox2 = DataCombo(path_array_data_folder)
        # dataComboBox3 = DataCombo(path_array_data_folder)
        #
        # self.tableWidget_dropzone.setCellWidget(0, 0, dataComboBox1)
        # self.tableWidget_dropzone.setCellWidget(0, 2, dataComboBox2)
        # self.tableWidget_dropzone.setCellWidget(0, 4, dataComboBox3)

        self.populateExcelComboBox()
        self.populateDataComboBoxes()
        self.populateInvestigators()

        # other settings

        self.dateEdit.setDateTime(QDateTime.currentDateTime())

        # actions

        self.actionPreferences.triggered.connect(self.show_preferences)
        self.load_samples_comboBox.activated.connect(self.loadExcel)

    def repopulate(self):
        self.populateExcelComboBox()
        self.populateDataComboBoxes()
        self.populateInvestigators()

    def populateInvestigators(self):
        arrayUpload_settings = QSettings('vll', 'arrayUpload')
        investigators_list = arrayUpload_settings.value('investigators',
                                                        type=list)

        investigators_list.insert(0, " -- none selected -- ")

        self.comboBox_investigator.clear()
        for i in investigators_list:
            self.comboBox_investigator.addItem(i)

    def populateDataComboBoxes(self):
        arrayUpload_settings = QSettings('vll', 'arrayUpload')
        path_array_data_folder = arrayUpload_settings.value(
            'path_array_data_folder', type=str)
        dataComboBox1 = DataCombo(path_array_data_folder)
        dataComboBox2 = DataCombo(path_array_data_folder)
        dataComboBox3 = DataCombo(path_array_data_folder)

        self.tableWidget_dropzone.setCellWidget(0, 0, dataComboBox1)
        self.tableWidget_dropzone.setCellWidget(0, 2, dataComboBox2)
        self.tableWidget_dropzone.setCellWidget(0, 4, dataComboBox3)

    def populateExcelComboBox(self):
        self.load_samples_comboBox.clear()
        arrayUpload_settings = QSettings('vll', 'arrayUpload')
        path_sample_excel_files_folder = arrayUpload_settings.value(
            'path_sample_excel_files_folder', type=str)
        files = os.listdir(path=path_sample_excel_files_folder)
        files_xls = []
        for f in files:
            if f.endswith(".xls"):
                files_xls.append(f)

        sfiles_xls = natsorted(files_xls)

        sfiles_xls.insert(0, " -- none selected -- ")

        for f in sfiles_xls:
            if f[0] != '$':
                self.load_samples_comboBox.addItem(f)

    def loadExcel(self):
        arrayUpload_settings = QSettings('vll', 'arrayUpload')
        path_sample_excel_files_folder = arrayUpload_settings.value(
            'path_sample_excel_files_folder', type=str)

        self.tableWidget_XLS.clear()

        cexcel = self.load_samples_comboBox.currentText()
        cexcel_path = path_sample_excel_files_folder + "/" + cexcel

        if cexcel != " -- none selected -- ":

            book = xlrd.open_workbook(cexcel_path, 'r')
            sheet = book.sheet_by_index(0)

            self.tableWidget_XLS.setColumnCount(sheet.ncols + 10)
            self.tableWidget_XLS.setRowCount(sheet.nrows + 10)
            self.check_change = False

            for row_index in range(0, sheet.nrows):
                for col_index in range(0, sheet.ncols):
                    content = sheet.cell(row_index, col_index).value
                    item = QTableWidgetItem(content)
                    self.tableWidget_XLS.setItem(row_index, col_index, item)
                    self.tableWidget_XLS.setDragEnabled(True)

            self.check_change = True

    def load_samples(self):

        files = os.listdir("C:/Users/parla/Documents/")
        sfiles = natsorted(files)
        sfiles.insert(0, " -- none selected -- ")

        for f in sfiles:
            # print(f)
            if f.endswith('.xls') or f.endswith(' -- none selected -- '):
                self.load_samples_comboBox.addItem(f)

    def show_preferences(self):
        self.p = Preferences(self)
        self.p.show()
Ejemplo n.º 37
0
 def show_preferences(self):
     self.p = Preferences(self)
     self.p.show()
Ejemplo n.º 38
0
class Client():
    def __init__(self, path="../database"):

        self.session_files = []

        self.books = self.getBooks(path)

        self.preferences = Preferences()
        self.preferences.readConfig()
        self.session = copy.deepcopy(self.preferences)

        self.db = Database()
        self.openDefaultDatabase()

        self.presenter = Presenter()

        self.songs = []
        self.uploaded_song = {}

    def getBooks(self, path):
        pattern = path + "/*.db3"
        files = []
        for file in glob.glob(pattern):
            files.append(file.replace('\\', '/'))
        log.config(files)
        return files

    def openDefaultDatabase(self):
        for book in self.books:  # database paths
            if self.preferences.database.default in book:
                self.db.open(book)
                return

    def updateSessionData(self, session_obj):
        self.session = session_obj

    # Calls database object to create image files for each page in the song.
    # Returns the list of file paths where the images have been stored.
    def getPageImagesForSong(self, page_ids):

        paths = []
        # Make a database request for each page id,
        for page_id in page_ids:
            file_path = "../tmp/image" + str(page_id) + ".png"
            # Database object writes the png file.
            # If the file is already written (arranger can do this)
            # don't re-write the file.
            if file_path not in paths:
                self.db.getImageData(page_id, file_path)
            # But we need redundant paths returned for arranger's sake.
            paths.append(file_path)

        self.session_files.extend(paths)

        return paths

    # Get the audio stream from the database and create a file.
    # Play the audio stream through the configured player.
    def getAudio(self, media_id):

        file_prefix = "../tmp/audio" + str(media_id)
        # The database will add the appropriate extension based on data type.
        audio_file = self.db.writeAudioData(media_id, file_prefix)

        if audio_file.endswith("mid"):
            xternal = self.preferences.external.midi
        elif audio_file.endswith("mp3"):
            xternal = self.preferences.external.mp3
        else:
            xternal = self.preferences.external.web
            link = audio_file
            command = xternal.replace('<link>', link)
            command = command.split(',')
            log.info("Client::getAudio External audio process:", command)
            p = subprocess.Popen(command,
                                 stdout=subprocess.PIPE,
                                 stderr=subprocess.PIPE)
            return

        log.info("Client::getAudio Database wrote audio file:", audio_file)

        command = []
        for subcmd in xternal.split(','):
            if subcmd == '<file>':
                subcmd = audio_file
            command.append(subcmd)

        log.info("Client::getAudio External audio process:", command)
        p = subprocess.Popen(command,
                             stdout=subprocess.PIPE,
                             stderr=subprocess.PIPE)
        self.session_files.append(audio_file)

    def getSplashConfiguration(self):

        splash = {
            'type': 'splash',
            'label1': self.preferences.splash.label1,
            'label2': self.preferences.splash.label2
        }
        return splash

    # Read the presentations/hymn, /scripture, /other folders (dive deep)
    # and return the list of html files found with their relative paths.
    def getPresentationFiles(self):

        # Get a list of just the paths of files in the org cache.
        org_cache = []
        paths = getOrganizerCache()
        for dictionary in paths:
            org_cache.append(dictionary['path'])

        all_files = getFilesInDir(self.preferences.presentation.path)

        for path in all_files:
            if path in org_cache:
                continue  # Already in the paths list.
            if '/hymn/' in path:
                ptype = "hymn"
            elif '/scripture/' in path:
                ptype = 'scripture'
            else:
                ptype = 'other'
            paths.append({'type': ptype, 'path': path})

        log.info('Client::getPresentationFiles Found', len(paths), 'files in:',
                 self.preferences.presentation.path)

        self.saveOrganizerSequence(paths)
        return paths

    # Start the presenter external program as per preference configuration.
    def launchPresenter(self, path):

        dot = path.rfind('.')
        extension = path[dot + 1:]

        external = getattr(self.preferences.external, extension)
        command = []
        for arg in external.split(','):
            if '<file>' in arg:
                arg = arg.replace('<file>', path)
            command.append(arg)

        if sys.platform == "linux":
            my_env = os.environ.copy()
            my_env['LD_LIBRARY_PATH'] = '/usr/lib/libreoffice/program'
            p = subprocess.Popen(command, env=my_env)
        elif sys.platform == "win32":
            command[-1] = command[-1].replace('/', '\\')
            log.info("Launching presenter:", command)
            p = subprocess.Popen(command)

    # Get a list of verses and pages for give song
    def getVerseAndPages(self, data):

        song_id = int(data['id'])
        idx = data['idx']
        for song in self.songs:
            if int(song['id']) == song_id:
                log.debug("Client::getVerseAndPages found song id:", song_id)
                break

        stanzas = {}
        log.debug('Client->database::getVerseAndPages verse id:',
                  song['music'])
        status = self.db.getVerseAndPages(song['music'], stanzas)
        if status == "error":
            return None

        pres_file = '../presentations/hymn/' + song['title'] + '.pptx'

        result = {'type': 'stanzas', 'id': song['music']}
        result['values'] = stanzas
        result['idx'] = idx
        result['path'] = pres_file
        if os.path.exists(pres_file):
            result['exists'] = True
        else:
            result['exists'] = False

        return result

    # Creates a song presentation from a supplied dict
    def createSongPresentation(self, song_id_list, page_list, ratio):

        song = None
        if len(song_id_list) > 1:
            song = self.compileMedley(song_id_list)
        else:
            for hymn in self.songs:
                if hymn['id'] == song_id_list[0]:
                    song = hymn
                    song['type'] = 'single'
                    break

        if song == None:
            return None

        # Remove redundant page_ids from page_list ('set' does this)
        unique_page_ids = list(set(page_list))
        if not len(unique_page_ids):
            return None

        unique_paths = self.getPageImagesForSong(unique_page_ids)

        # Build a path list that contains any duplicates because
        # Chorus elements often need to be pasted twice in the
        # presentation file.
        pres_file = '../presentations/hymn/' + song['title'] + '.pptx'
        pres_file = pres_file.replace('?', '')
        log.info("Creating song presentation:", pres_file)

        paths = []
        for pg_id in page_list:
            index = unique_page_ids.index(pg_id)
            paths.append(unique_paths[index])
        if self.presenter.createSongFile(pres_file, song, paths,
                                         self.preferences, ratio):
            if os.path.exists(pres_file):
                exists = True
            else:
                exists = False
            response = {
                'type': 'icon',
                'icon_type': 'hymnal',
                'path': pres_file,
                'exists': exists
            }
            return response
        else:
            return None

    def compileMedley(self, song_id_list):

        # Medley: Find each song object and create a unique
        # medley object compilation to send to presenter.
        medley = {}
        for hymn in self.songs:  # Only go through all songs once.
            for id in song_id_list:  # This is a list of unique ids.
                if hymn['id'] == id:
                    # Found a matching id. If medley not initialized...
                    if len(medley) == 0:
                        # Copy the first hymn converting each key to list
                        for key, item in hymn.items():
                            medley[key] = [item]  # Make a list of each item
                    else:
                        # Append each item to its key in dict.
                        for key, item in hymn.items():
                            medley[key].append(item)

        medley['type'] = 'medley'
        medley['titles'] = medley['title']
        medley['title'] = 'Medley-'
        for number in medley['number']:
            medley['title'] += str(number) + ','

        medley['title'] = medley['title'][:-1]
        return medley

    # Create a scripture presentation from data dictionary
    def createScripturePresentation(self, data):

        ref = data['ref']
        font_sz = data['font_sz']
        text = data['text']
        version = data['version']
        ratio = data['ratio']
        text += "\n(" + version + ")"
        path = "../presentations/scripture/" + ref.replace(':', '_') + ".pptx"
        if os.path.exists(path):
            exists = True
        else:
            exists = False
        self.presenter.createScriptureFile(path, font_sz, ref, text,
                                           self.preferences, ratio)
        response = {
            'type': 'icon',
            'icon_type': 'bible',
            'path': path,
            'exists': exists
        }
        return response

    def getEditorInitialData(self):
        versions = self.getAvailableBibleVersions()
        log.config('Client::getEditorInitialData Available bible versions:',
                   ', '.join(versions))
        rtn_dict = {'type': 'editor', 'bibles': versions}
        return rtn_dict

    # Get the available bible versions on this system.
    def getAvailableBibleVersions(self):

        version_path = self.preferences.bible.sword_path

        log.info('Client::getAvailableBibleVersions searching ', version_path)
        version_names = []
        version_configs = glob.glob(version_path + "/*.conf")
        for file in version_configs:
            if "globals.conf" in file:
                continue

            # Open file and read first line.
            with open(file, 'r') as vfile:
                line = vfile.readline()
            vname = line[1:-2]

            version_names.append(vname)

        version_names.sort()
        return version_names

    # Look up a scripture in a particular version of the bible.
    # The data object has 2 pertinent attributes:
    #	 data.version -- the version of the bible to look up:
    #    data.passage -- the passage (e.g. Acts 2:38)
    def getBibleVerse(self, data):

        external = self.preferences.external.bible
        command = []
        for arg in external.split(','):
            if '<version>' in arg:
                arg = arg.replace('<version>', data['version'])
            elif '<passage>' in arg:
                arg = arg.replace('<passage>', data['ref'])
            command.append(arg)

        log.info('Client::getBibleVerse Request:', command)

        try:
            p = subprocess.Popen(command,
                                 stdout=subprocess.PIPE,
                                 stderr=subprocess.PIPE)
            log.info('Client::getBibleVerse Successful command execution.')
        except:
            log.error("Client::getBibleVerse Unexpected error:",
                      sys.exc_info()[0])
        ''' Diatheke output is: <book> <chapter>:<verse>: <verse text>EOL
			and continues until the last verse is printed. Then it prints
			another EOL, a ": " and repeats the (last) verse, then another EOL
			and prints the (<bible_version>).
		'''
        if p.returncode != 0 and p.returncode != None:
            #log.error('Client::getBibleVerse', p.stderr.decode())
            log.error('Client::getBibleVerse Scripture not found:',
                      data['ref'])
            try:
                log.error('Client::getBibleVerse', p.stdout.read().decode())
            except:
                log.error('Client::getBibleVerse unable to read stdout')
                pass
            return {
                'type': 'scripture',
                'status': 'error',
                'command': external,
                'code': p.returncode
            }

        try:
            raw_result = p.stdout.read().decode()

            # Remove the duplicate scripture (rfind(':')) and convert to list.
            delim = '\n'
            if sys.platform == "win32":
                scripture = raw_result.replace('\r', '').split(delim)[0:-2]
            else:
                scripture = raw_result.split(delim)[0:-3]
            log.info(raw_result)
        except:
            log.error('Client::getBibleVerse unable to process stdout')

        # To preemptively let the browser know whether the file exists
        # so that it can display an Are You Sure dialog without sending
        # multiple messages to get it done.
        path = "../presentations/scripture/" + data['ref'] + ".pptx"
        if os.path.exists(path):
            exists = True
            log.warning('Client::getBibleVerse File exists:', path)
        else:
            exists = False

        result = {
            'type': 'scripture',
            'status': 'ok',
            'text': scripture,
            'command': external,
            'passage': data['ref'],
            'version': data['version'],
            'exists': exists,
            'path': path
        }
        return result

    # Organizer confirm file (in browser) causes this to be called.
    def deleteFile(self, path):
        if os.path.exists(path):
            log.info('Client::deleteFile Organizer request to delete file:',
                     path)
            try:
                os.remove(path)
                log.info('Client::deleteFile Deleted file:', path)
                return "ok"
            except:
                log.warn('Client::deleteFile Failed to delete file:', path)
                return "fail"
        else:
            log.error('Client::deleteFile File does not exist:', path)
            return "does not exist"

    # Update the .organizer file with the current sequence of files
    # that were displayed at the time. The items argument is a list
    # of dicts with 'path' and 'icon' keys sent from the browser.
    def saveOrganizerSequence(self, items):
        with open("../cache/.organizer.txt", 'w') as organizer:
            for item in items:
                organizer.write('type=' + item['type'] + '\n')
                organizer.write('path=' + item['path'] + '\n\n')
        log.info('Client::saveOrganizerSequence Saved', len(items),
                 'presentation paths to organizer cache.')

    # Clean up the temporary image and media files created this session.
    def cleanupTempFiles(self):
        count = 0
        for file in set(self.session_files):
            count += 1
            if os.path.exists(file):
                try:
                    os.remove(file)
                    count += 1
                except:
                    log.warning('Unable to delete file:', file)
                    pass
        log.info('Client::cleanupTempFiles Deleted', count,
                 'temporary session files.')

    # Opens a process to select a folder. Returns the folder
    # image files (.png) as a list.
    def getFolder(self, starting=''):
        command = self.preferences.external.browse_folder
        if len(starting):
            command = command.replace('<file>', starting)
        command = command.split(',')

        log.info('Client::getFolder Browsing for folder command:', command)
        p = subprocess.Popen(command,
                             stdout=subprocess.PIPE,
                             stderr=subprocess.PIPE)

        folder = p.stdout.read().decode().strip()
        # Stdout will be blank if cancel was pressed. We return nothing.
        if len(folder) < 2:
            log.info(
                'Client::getFolder Browsing for folder dialog was canceled by user.'
            )
            return None

        image_files = glob.glob(folder + '/*.png')
        audio_files = glob.glob(folder + '/*.mid')
        for file in glob.glob(folder + '/.mp3'):
            audio_files.append(file)

        image_files.sort()
        audio_files.sort()

        result = {'type': 'folder', 'folder': folder}
        result['image_files'] = image_files
        result['audio_files'] = audio_files
        log.info('Client::getFolder Found:', len(image_files), 'and',
                 len(audio_files), 'in', folder)
        return result

    # The song argument is a dictionary received from the browser.
    # It contains everything necessary to create a new hymn record
    # in the database.
    def uploadHymn(self, song):

        # Need to connect to the database (book) indicated in song dict.
        # Save the current one in case of error (we'll reset).
        reconnect = None
        log.info('Client::uploadHymn request:', song)
        if song['book'] not in self.db.file:
            for book in self.books:
                if song['book'] in book:
                    reconnect = self.db.file  # Current connection
                    self.db.open(book)  # New connection
                    break

        # Upload each page, making sure each is successful.
        pageid_list = []
        for path in song['paths']:
            page_id = self.db.uploadPage(path)
            if page_id == None:
                if reconnect != None:
                    self.db.open(reconnect)
                message = "Error uploading " + path
                log.error(message)
                return {
                    'type': 'upload',
                    'status': 'error',
                    'message': message
                }
            # Save the page ids to for mapping (next loop)
            pageid_list.append(page_id)

        # Create a verse record. Required format to send to database is
        # a stanza comma-separated string for the SEQUENCE of part names.
        stanzas = ','.join(song['sequence'])

        # Use the pageid_list list created above with the song['verses'] and the
        # song['sequence'] to create a page string that represents the
        # full arrangement.
        page_sequence = ""
        for verse in song['sequence']:
            page_string = ""
            for index in song[verse]:
                page_string += "," + str(pageid_list[index])
            page_sequence += "|" + page_string[1:]  # Strip the first ,
        page_sequence = page_sequence[1:]  # Strip the first |

        # Commit the verse record to the database.
        verse_id = self.db.newVerseRecord(stanzas, page_sequence)
        if verse_id == None:
            if reconnect != None:
                self.db.open(reconnect)
            message = "Client::uploadHymn Error creating verse record."
            log.error(message, stanzas, page_sequence)
            return {'type': 'upload', 'status': 'error', 'message': message}

        # Create the audio record. Database figures out the type based
        # on the extension.
        media_id = self.db.newAudioRecord(song['audio'])
        if media_id == None:
            if reconnect != None:
                self.db.open(reconnect)
            message = "Client::uploadHymn Error uploading media file."
            log.error(message, song['audio'])
            return {'type': 'upload', 'status': 'error', 'message': message}

        # Create author records for lyricist and composer. The database
        # will return either a new record id (not a duplicate name), an
        # existing record id (matches exactly a name already there), or
        # None if it has trouble creating the record.
        lyricist_id = self.db.newAuthorRecord(song['lyricist'])
        if lyricist_id == None:
            if reconnect != None:
                self.db.open(reconnect)
            message = "Client::uploadHymn Error creating lyricist record."
            log.error(message, song['lyricist'])
            return {'type': 'upload', 'status': 'error', 'message': message}

        composer_id = self.db.newAuthorRecord(song['composer'])
        if composer_id == None:
            if reconnect != None:
                self.db.open(reconnect)
            message = "Client::uploadHymn Error creating composer record."
            log.error(message, song['composer'])
            return {'type': 'upload', 'status': 'error', 'message': message}

        # Create the meta record, which is basically a container of all
        # of the record ids for the inserts above (and a little more).
        meta = self.db.newMetaRecord(song['number'], song['title'],
                                     lyricist_id, song['ldate'], composer_id,
                                     song['mdate'], song['copyright'],
                                     verse_id, media_id)

        if meta == None:
            if reconnect != None:
                self.db.open(reconnect)
            message = "Client::uploadHymn Error creating meta record."
            log.error(message)
            return {'type': 'upload', 'status': 'error', 'message': message}

        # Successful upload has occurred. Leave the database connected,
        # since the next thing that will be done is to get

        self.uploaded_song = song
        songs = []
        self.db.getAllSongs(songs)

        return {'type': 'upload', 'status': 'success', 'song': song}
 def headerLabelType(self):
     """
     Returns the type of the header label.
     """
     return Preferences.HeaderLabel(self.grpHeaderLabel.checkedId())
Ejemplo n.º 40
0
class GtkUI(object):
    def __init__(self, args):
        self.daemon_bps = (0,0,0)
        # Setup signals
        try:
            import gnome.ui
            import gnome
            self.gnome_prog = gnome.init("Deluge", deluge.common.get_version())
            self.gnome_client = gnome.ui.master_client()
            def on_die(*args):
                reactor.stop()
            self.gnome_client.connect("die", on_die)
            log.debug("GNOME session 'die' handler registered!")
        except Exception, e:
            log.warning("Unable to register a 'die' handler with the GNOME session manager: %s", e)

        if deluge.common.windows_check():
            from win32api import SetConsoleCtrlHandler
            from win32con import CTRL_CLOSE_EVENT
            from win32con import CTRL_SHUTDOWN_EVENT
            def win_handler(ctrl_type):
                log.debug("ctrl_type: %s", ctrl_type)
                if ctrl_type in (CTRL_CLOSE_EVENT, CTRL_SHUTDOWN_EVENT):
                    reactor.stop()
                    return 1
            SetConsoleCtrlHandler(win_handler)

        # Attempt to register a magnet URI handler with gconf, but do not overwrite
        # if already set by another program.
        common.associate_magnet_links(False)

        # Make sure gtkui.conf has at least the defaults set
        self.config = deluge.configmanager.ConfigManager("gtkui.conf", DEFAULT_PREFS)

        # We need to check on exit if it was started in classic mode to ensure we
        # shutdown the daemon.
        self.started_in_classic = self.config["classic_mode"]

        # Start the IPC Interface before anything else.. Just in case we are
        # already running.
        self.queuedtorrents = QueuedTorrents()
        self.ipcinterface = IPCInterface(args)

        # Initialize gdk threading
        gtk.gdk.threads_init()


        # We make sure that the UI components start once we get a core URI
        client.set_disconnect_callback(self.__on_disconnect)

        self.trackericons = TrackerIcons()
        self.sessionproxy = SessionProxy()
        # Initialize various components of the gtkui
        self.mainwindow = MainWindow()
        self.menubar = MenuBar()
        self.toolbar = ToolBar()
        self.torrentview = TorrentView()
        self.torrentdetails = TorrentDetails()
        self.sidebar = SideBar()
        self.filtertreeview = FilterTreeView()
        self.preferences = Preferences()
        self.systemtray = SystemTray()
        self.statusbar = StatusBar()
        self.addtorrentdialog = AddTorrentDialog()

        # Initalize the plugins
        self.plugins = PluginManager()

        # Late import because of setting up translations
        from connectionmanager import ConnectionManager
        # Show the connection manager
        self.connectionmanager = ConnectionManager()

        from twisted.internet.task import LoopingCall
        rpc_stats = LoopingCall(self.print_rpc_stats)
        rpc_stats.start(10)

        reactor.callWhenRunning(self._on_reactor_start)

        # Initialize gdk threading
        gtk.gdk.threads_enter()
        reactor.run()
        self.shutdown()
        gtk.gdk.threads_leave()
Ejemplo n.º 41
0
class TTS_CLI:
    def __init__(self):
        self.preferences = Preferences()

        parser = argparse.ArgumentParser(
            description="Manipulate Tabletop Simulator files")
        parser.add_argument("-d",
                            "--directory",
                            help="Override TTS cache directory")
        parser.add_argument("-l",
                            "--loglevel",
                            help="Set logging level",
                            choices=['debug', 'info', 'warn', 'error'])
        subparsers = parser.add_subparsers(dest='parser',
                                           title='command',
                                           description='Valid commands.')
        subparsers.required = True

        # add list command
        parser_list = subparsers.add_parser('list',
                                            help="List installed mods.",
                                            description='''
    List installed mods.
    If no id is provided, then this will return a list of all installed modules.
    If an id is provided, then this will list the contents of that modules.
    ''')
        group_list = parser_list.add_mutually_exclusive_group()
        group_list.add_argument("-w",
                                "--workshop",
                                action="store_const",
                                metavar='save_type',
                                dest='save_type',
                                const=SaveType.workshop,
                                help="List workshop files (the default).")
        group_list.add_argument("-s",
                                "--save",
                                action="store_const",
                                metavar='save_type',
                                dest='save_type',
                                const=SaveType.save,
                                help="List saves.")
        group_list.add_argument("-c",
                                "--chest",
                                action="store_const",
                                metavar='save_type',
                                dest='save_type',
                                const=SaveType.chest,
                                help="List chest files.")

        parser_list.add_argument("id",
                                 nargs='?',
                                 help="ID of specific mod to list details of.")
        parser_list.set_defaults(func=self.do_list)

        # export command
        parser_export = subparsers.add_parser(
            'export',
            help="Export a mod.",
            description='Export a mod in a format suitible for later import.')
        group_export = parser_export.add_mutually_exclusive_group()
        group_export.add_argument("-w",
                                  "--workshop",
                                  action="store_const",
                                  dest='save_type',
                                  metavar='save_type',
                                  const=SaveType.workshop,
                                  help="ID is of workshop file (the default).")
        group_export.add_argument("-s",
                                  "--save",
                                  action="store_const",
                                  dest='save_type',
                                  metavar='save_type',
                                  const=SaveType.save,
                                  help="ID is of savegame file.")
        group_export.add_argument("-c",
                                  "--chest",
                                  action="store_const",
                                  dest='save_type',
                                  metavar='save_type',
                                  const=SaveType.chest,
                                  help="ID is of chest file.")
        parser_export.add_argument(
            "id", help="ID of mod/name of savegame to export.")
        parser_export.add_argument("-o",
                                   "--output",
                                   help="Location/file to export to.")
        parser_export.add_argument("-f",
                                   "--force",
                                   action="store_true",
                                   help="Force creation of export file.")
        parser_export.add_argument(
            "-d",
            "--download",
            action="store_true",
            help="Attempt to download missing cache files. (EXPERIMENTAL)")
        parser_export.set_defaults(func=self.do_export)

        # import command
        parser_import = subparsers.add_parser(
            'import',
            help="Import a mod.",
            description="Import an previously exported mod.")
        parser_import.add_argument("file", help="Mod pak file to import.")
        parser_import.set_defaults(func=self.do_import)

        # download command
        parser_download = subparsers.add_parser(
            'download',
            help='Download mod files.',
            description=
            'Attempt to download any missing files for an installed mod.')
        group_download = parser_download.add_mutually_exclusive_group()
        group_download.add_argument("-w",
                                    "--workshop",
                                    action="store_const",
                                    dest='save_type',
                                    metavar='save_type',
                                    const=SaveType.workshop,
                                    help="ID is of workshop file.")
        group_download.add_argument("-s",
                                    "--save",
                                    action="store_const",
                                    dest='save_type',
                                    metavar='save_type',
                                    const=SaveType.save,
                                    help="ID is of savegame file.")
        group_download.add_argument("-c",
                                    "--chest",
                                    action="store_const",
                                    dest='save_type',
                                    metavar='save_type',
                                    const=SaveType.chest,
                                    help="ID is of chest file.")
        group_download_target = parser_download.add_mutually_exclusive_group(
            required=True)
        group_download_target.add_argument("-a",
                                           "--all",
                                           action="store_true",
                                           help="Download all.")
        group_download_target.add_argument(
            "id", nargs='?', help="ID of mod/name of savegame to download.")
        parser_download.set_defaults(func=self.do_download)

        # cache command
        parser_cache = subparsers.add_parser('cache',
                                             help='Work with the cache.')
        subparsers_cache = parser_cache.add_subparsers(
            dest='parser_cache',
            title='cache_command',
            description='Valid sub-commands.')
        subparsers_cache.required = True
        parser_cache_create = subparsers_cache.add_parser(
            'create', help='(re)create cache directory')
        parser_cache_create.set_defaults(func=self.do_cache_create)

        # config command
        parser_config = subparsers.add_parser('config',
                                              help='Configure tts manager.')
        subparsers_config = parser_config.add_subparsers(
            dest='parser_config',
            title='config_command',
            description='Valid sub-commands.')
        subparsers_config.required = True
        parser_config_list = subparsers_config.add_parser(
            'list', help='List configuration.')
        parser_config_list.set_defaults(func=self.do_config_list)
        parser_config_validate = subparsers_config.add_parser(
            'validate', help='Validate configuration.')
        parser_config_validate.set_defaults(func=self.do_config_validate)
        parser_config_reset = subparsers_config.add_parser(
            'reset', help='Reset configuration.')
        parser_config_reset.set_defaults(func=self.do_config_reset)
        parser_config_set = subparsers_config.add_parser(
            'set', help='Set configuration parameters.')
        parser_config_set.set_defaults(func=self.do_config_set)
        parser_config_set.add_argument("-m",
                                       "--mod_location",
                                       choices=['documents', 'gamedata'],
                                       help="Where mods are stored.")
        parser_config_set.add_argument("-t",
                                       "--tts_location",
                                       help="TTS Install directory")

        args = parser.parse_args()

        # set logging
        if args.loglevel:
            logmap = {
                'debug': logging.DEBUG,
                'info': logging.INFO,
                'warn': logging.WARN,
                'error': logging.ERROR
            }
            logger().setLevel(logmap[args.loglevel])
        else:
            logger().setLevel(logging.WARN)

        # load filesystem values
        if args.directory:
            self.filesystem = FileSystem(os.path.abspath(args.directory))
        else:
            self.filesystem = self.preferences.get_filesystem()

        if (args.parser == 'list'
                or args.parser == 'export') and not args.save_type:
            # set default
            args.save_type = SaveType.workshop

        if (args.parser == 'config' and args.parser_config == 'set'
                and not args.mod_location and not args.tts_location):
            parser_config_set.error("At least one of -m or -t is required.")

        rc, message = args.func(args)
        if message:
            print(message)
        sys.exit(rc)

    def do_config_set(self, args):
        if args.mod_location:
            self.preferences.locationIsUser = args.mod_location == 'documents'
        if args.tts_location:
            self.preferences.TTSLocation = args.mod_location
        self.preferences.save()
        return 0, "Preferences set"

    def do_config_reset(self, args):
        self.preferences.reset()
        return 0, "Preferences Reset."

    def do_config_list(self, args):
        return 0, self.preferences

    def do_config_validate(self, args):
        if self.preferences.validate():
            return 0, "Configuration validated OK."
        else:
            return 1, "Configuration failed to validate."

    def do_cache_create(self, args):
        try:
            self.filesystem.create_dirs()
        except OSError as exception:
            return 1, "OS error: {0}".format(exception)
        return 0, "All directories created OK."

    def list_by_type(self, save_type):
        result = ""
        for (name, id) in describe_files_by_type(self.filesystem, save_type):
            result += "\n%s (%s)" % (name, id)
        return 0, result

    def list_item(self, data, filename, ident):
        if not data:
            # self.list_installed()
            return
        save = Save(savedata=data,
                    ident=ident,
                    filename=filename,
                    filesystem=self.filesystem)
        return 0, save

    def do_download(self, args):
        successful = True
        if not args.all:
            if not args.save_type:
                args.save_type = self.filesystem.get_json_filename_type(
                    args.id)
            if not args.save_type:
                return 1, "Unable to determine type of id %s" % args.id
            successful = download_file(self.filesystem, args.id,
                                       args.save_type)
        else:
            if args.save_type:
                for ident in self.filesystem.get_filenames_by_type(
                        args.save_type):
                    if not download_file(self.filesystem, ident,
                                         args.save_type):
                        successful = False
                        break
            else:
                for save_type in SaveType:
                    for ident in self.filesystem.get_filenames_by_type(
                            save_type):
                        if not download_file(self.filesystem, ident,
                                             save_type):
                            successful = False
                            break

        if successful:
            return 0, "All files downloaded."
        else:
            return 1, "Some files failed to download."

    def do_list(self, args):
        rc = 0
        result = None

        if not args.id:
            rc, result = self.list_by_type(args.save_type)
        else:
            if not args.save_type:
                args.save_type = self.filesystem.get_json_filename_type(
                    args.id)
            if not args.save_type:
                return 1, "Unable to determine type of id %s" % args.id
            filename = self.filesystem.get_json_filename_for_type(
                args.id, args.save_type)
            data = load_json_file(filename)
            rc, result = self.list_item(data, filename, args.id)
        return rc, result

    def do_export(self, args):
        filename = None
        if args.output:
            if os.path.isdir(args.output):
                filename = os.path.join(args.output, args.id + ".pak")
            else:
                filename = args.output
        else:
            filename = args.id + ".pak"

        data = None
        json_filename = None
        if not args.save_type:
            args.save_type = self.filesystem.get_json_filename_type(args.id)
        if not args.save_type:
            return 1, "Unable to determine type of id %s" % args.id

        json_filename = self.filesystem.get_json_filename_for_type(
            args.id, args.save_type)

        if not json_filename:
            return 1, "Unable to find filename for id %s (wrong -s/-w/-c specified?)" % args.id
        data = load_json_file(json_filename)
        if not data:
            return 1, "Unable to load data for file %s" % json_filename

        save = Save(savedata=data,
                    filename=json_filename,
                    ident=args.id,
                    save_type=args.save_type,
                    filesystem=self.filesystem)
        if not save.isInstalled:
            if not args.download:
                return 1, "Unable to find all urls required by %s. Rerun with -d to try and download them or open it within TTS.\n%s" % (
                    args.id, save)
            else:
                logger().info("Downloading missing files...")
                successful = save.download()
                if successful:
                    logger().info("Files downloaded successfully.")
                else:
                    return 1, "Some files failed to download"
        if os.path.isfile(filename) and not args.force:
            return 1, "%s already exists. Please specify another file or use '-f'" % filename
        logger().info("Exporting json file %s to %s" % (args.id, filename))
        save.export(filename)
        # TODO: exception handling
        return 0, "Exported %s to %s" % (args.id, filename)

    def do_import(self, args):
        return 0, save_helper.importPak(self.filesystem, args.file)
Ejemplo n.º 42
0
 def on_actionPreferences_triggered(self):
     if not self.preferences_dialog:
         self.preferences_dialog = Preferences(self.data['preferences'])
         self.preferences_dialog.rejected.connect(self.update_preferences)
     self.preferences_dialog.show()
Ejemplo n.º 43
0
    def __init__(self, pyroom_config):
        self.current = 0
        self.buffers = []
        self.config = pyroom_config.config
        self.gui = GUI(pyroom_config, self)
        self.preferences = Preferences(gui=self.gui,
                                       pyroom_config=pyroom_config)
        try:
            self.recent_manager = gtk.recent_manager_get_default()
        except AttributeError:
            self.recent_manager = None
        self.status = self.gui.status
        self.window = self.gui.window
        self.window.add_accel_group(make_accel_group(self))
        self.textbox = self.gui.textbox
        self.UNNAMED_FILENAME = FILE_UNNAMED

        self.autosave_timeout_id = ''
        self.autosave_elapsed = ''

        self.new_buffer()

        self.textbox.connect('key-press-event', self.key_press_event)

        self.textbox.set_pixels_below_lines(
            int(self.config.get("visual", "linespacing")))
        self.textbox.set_pixels_above_lines(
            int(self.config.get("visual", "linespacing")))
        self.textbox.set_pixels_inside_wrap(
            int(self.config.get("visual", "linespacing")))

        # Autosave timer object
        autosave.start_autosave(self)

        self.window.show_all()
        self.window.fullscreen()

        # Handle multiple monitors
        screen = gtk.gdk.screen_get_default()
        root_window = screen.get_root_window()
        mouse_x, mouse_y, mouse_mods = root_window.get_pointer()
        current_monitor_number = screen.get_monitor_at_point(mouse_x, mouse_y)
        monitor_geometry = screen.get_monitor_geometry(current_monitor_number)
        self.window.move(monitor_geometry.x, monitor_geometry.y)
        self.window.set_geometry_hints(None,
                                       min_width=monitor_geometry.width,
                                       min_height=monitor_geometry.height,
                                       max_width=monitor_geometry.width,
                                       max_height=monitor_geometry.height)

        # Defines the glade file functions for use on closing a buffer
        self.wTree = gtk.glade.XML(
            os.path.join(pyroom_config.pyroom_absolute_path,
                         "interface.glade"), "SaveBuffer")
        self.dialog = self.wTree.get_widget("SaveBuffer")
        self.dialog.set_transient_for(self.window)
        dic = {
            "on_button-close_clicked": self.unsave_dialog,
            "on_button-cancel_clicked": self.cancel_dialog,
            "on_button-save_clicked": self.save_dialog,
        }
        self.wTree.signal_autoconnect(dic)

        #Defines the glade file functions for use on exit
        self.aTree = gtk.glade.XML(
            os.path.join(pyroom_config.pyroom_absolute_path,
                         "interface.glade"), "QuitSave")
        self.quitdialog = self.aTree.get_widget("QuitSave")
        self.quitdialog.set_transient_for(self.window)
        dic = {
            "on_button-close2_clicked": self.quit_quit,
            "on_button-cancel2_clicked": self.cancel_quit,
            "on_button-save2_clicked": self.save_quit,
        }
        self.aTree.signal_autoconnect(dic)
        self.keybindings = define_keybindings(self)
        # this sucks, shouldn't have to call this here, textbox should
        # have its background and padding color from GUI().__init__() already
        self.gui.apply_theme()
Ejemplo n.º 44
0
class NoduleCADx(QMainWindow):
    def __init__(self):
        super().__init__()
        loadUi('mainwindow.ui', self)
        self.setWindowFlags(Qt.WindowMaximizeButtonHint
                            | Qt.WindowMinimizeButtonHint
                            | Qt.WindowCloseButtonHint)

        self.display_dialog = None
        # ColumnWidth of Patient List
        self.treeWidget.setColumnWidth(0, 70)
        self.treeWidget.setColumnWidth(1, 100)
        self.treeWidget.setColumnWidth(2, 100)
        self.treeWidget.setColumnWidth(3, 50)
        self.treeWidget.setColumnWidth(4, 50)
        # ColumnWidth of Scan and Nodule List
        self.noduletreeWidget.setColumnWidth(0, 70)
        self.noduletreeWidget.setColumnWidth(1, 100)
        self.noduletreeWidget.setColumnWidth(2, 100)
        self.noduletreeWidget.setColumnWidth(3, 50)
        self.noduletreeWidget.setColumnWidth(4, 100)
        self.noduletreeWidget.setColumnWidth(5, 100)
        self.noduletreeWidget.setColumnWidth(6, 100)
        self.noduletreeWidget.setColumnWidth(7, 100)
        self.noduletreeWidget.setColumnWidth(8, 100)
        self.preferences_dialog = None

        # pkg_name is the JSON file saved all the detected information (including scan path)
        # create a pkg_name.json if it doesn't exist.
        if not os.path.exists(pkg_name):
            with open(pkg_name, 'w') as json_file:
                initial_json = {
                    'app': 'Nodule CADx',
                    'version': '1.0.0',
                    "preferences": {
                        "threshold": "0.8",
                        "project_directory": os.getcwd(),
                        "automatic_classification": True,
                        "windowlevel": "?"
                    },
                    'members': []
                }
                json.dump(initial_json, json_file, indent=2)

        # load pkg_name.json
        with open(pkg_name, 'r') as f:
            self.data = json.load(f)
        # load nodulenet and classification model and refresh patient list.
        self.nodulenet_model = None
        self.classification_model = None
        self.load_model()
        self.refresh_patient_list()

    def load_model(self):
        """
        Load (1)NoduleNet and (2)Classification model.
        Since I didn't install NoduleNet on my macOS, so only load it on Windows10.
        """
        # NoduleNet model
        if use_win10:
            args = parser.parse_args()
            initial_checkpoint = args.weight
            net = args.net
            net = getattr(this_module, net)(config)
            if initial_checkpoint:
                print('[Loading model from %s]' % initial_checkpoint)
                checkpoint = torch.load(initial_checkpoint, map_location='cpu')
                net.load_state_dict(checkpoint['state_dict'], )
            else:
                print('No model weight file specified')
            net.set_mode('eval')
            net.use_mask = True
            net.use_rcnn = True
            self.nodulenet_model = net
        else:
            self.nodulenet_model = None

        # Classification model
        self.classification_model = joblib.load(
            'model/classification_model.pkl')

    @pyqtSlot()
    def on_reportButton_clicked(self):
        """
        Export system report in CSV format.
        """
        report = [[
            'Name', 'Date of Birth', 'Sex', 'Final-Score', 'Management',
            'Scan Path', 'Nodule', 'Diameter', 'Type', 'Calcification',
            'Spiculation', 'Perifissural', 'Endobronchial', 'Score'
        ]]
        for m in self.data['members']:
            report.append([
                m['patient_name'], m['date_of_birth'], m['sex'], m['score'],
                m['management']
            ])
            for s in m['scans']:
                report.append([''] * 5 + [s['scan_path']])
                for i, n in enumerate(s['nodules'], start=1):
                    type_name = self.get_type_name(n['type'])
                    report.append([''] * 6 + [
                        f'Nodule{i}', n['diameter'], type_name,
                        n['calcification'], n['spiculation'],
                        n['perifissural'], n['endobronchial'], n['score']
                    ])
        with open('report.csv', 'w') as csvfile:
            writer = csv.writer(csvfile)
            writer.writerows(report)

    @staticmethod
    def get_type_name(nodule_type):
        """
        Get type name for display.
        """
        if nodule_type == '1':
            return 'non-solid'
        elif nodule_type == '2':
            return 'non/part'
        elif nodule_type == '3':
            return 'part-solid'
        elif nodule_type == '4':
            return 'part/solid'
        elif nodule_type == '5':
            return 'solid'

    def refresh_patient_list(self):
        """
        refresh patient list (upper block of main window).
        """
        self.treeWidget.clear()
        for m in self.data['members']:
            scan_item = QTreeWidgetItem(self.treeWidget, [
                '\u2713' if m['updated'] else '\u2717', m['patient_name'],
                m['date_of_birth'], m['sex'], m['score'], m['management']
            ])
            for i in range(scan_item.columnCount()):
                scan_item.setTextAlignment(i, Qt.AlignHCenter)

    def refresh_scan_list(self, member):
        """
        refresh scan and nodule list (lower block of main window).
        """
        self.noduletreeWidget.clear()
        for scan in member['scans']:
            p = QTreeWidgetItem(self.noduletreeWidget, [
                '\u2713' if scan['updated'] else '\u2717', scan['scan_date'],
                scan['scan_path']
            ])
            if scan['updated']:
                for count, nodule in enumerate(scan['nodules'], start=1):
                    type_name = self.get_type_name(nodule['type'])
                    n_item = QTreeWidgetItem(p, [
                        '', '', f'Nodule{count}',
                        str(nodule['prob']),
                        str(nodule['diameter']), type_name,
                        str(nodule['calcification']),
                        str(nodule['spiculation']),
                        str(nodule['perifissural']),
                        str(nodule['endobronchial']), nodule['score']
                    ])
                    for i in range(n_item.columnCount()):
                        n_item.setTextAlignment(i, Qt.AlignHCenter)
            for i in range(p.columnCount()):
                p.setTextAlignment(i, Qt.AlignHCenter)
        self.noduletreeWidget.expandAll()

    @pyqtSlot()
    def on_actionPreferences_triggered(self):
        if not self.preferences_dialog:
            self.preferences_dialog = Preferences(self.data['preferences'])
            self.preferences_dialog.rejected.connect(self.update_preferences)
        self.preferences_dialog.show()

    def update_preferences(self):
        """
        update preferences when OK in preferences dialog is clicked.
        """
        self.data['preferences'] = self.preferences_dialog.preferences

    def on_treeWidget_itemClicked(self):
        index_member = self.treeWidget.currentIndex().row()
        self.refresh_scan_list(member=self.data['members'][index_member])

    @pyqtSlot()
    def on_loadscanButton_clicked(self):
        fname, _filter = QFileDialog.getOpenFileName(self, 'open file',
                                                     '~/Desktop',
                                                     'Scan (*.mhd *.nrrd)')

        # make up some patient information for .mhd file from LUNA16
        faker = Faker()
        patient_name = faker.name()
        birth_date = faker.date()
        patient_sex = faker.profile()['sex']
        scan_date = faker.date()

        # For general DICOM series
        '''
        reader = sitk.ImageSeriesReader()
        reader = sitk.ImageSeriesReader()
        dir = '/Users/apple/Desktop/神農/一些參考/Patient CT EDU (Anonym-TR123)'
        seriesIDs = reader.GetGDCMSeriesIDs(dir)
        dcm_series = reader.GetGDCMSeriesFileNames(dir, seriesIDs[0])
        reader.SetFileNames(dcm_series)
        reader.MetaDataDictionaryArrayUpdateOn()
        # Execute() is needed to GetMetaData
        img = reader.Execute()
        patient_name = reader.GetMetaData(0,'0010|0010').strip()
        birth_date = reader.GetMetaData(0,'0010|0030').strip()
        patient_sex = reader.GetMetaData(0,'0010|0040').strip()
        '''

        exist = False
        for i, m in enumerate(self.data['members']):
            if patient_name == m['patient_name']:
                self.data['members'][i]['scans'].append({
                    'updated': False,
                    'scan_path': fname,
                    'scan_date': scan_date,
                    'nodules': []
                })
                self.data['members'][i]['updated'] = False
                exist = True
        if not exist:
            self.data['members'].append({
                'updated':
                False,
                'patient_name':
                patient_name,
                'date_of_birth':
                birth_date,
                'sex':
                patient_sex,
                'score':
                '?',
                'management':
                '?',
                'scans': [{
                    'updated': False,
                    'scan_path': fname,
                    'scan_date': scan_date,
                    'nodules': []
                }]
            })
        self.refresh_patient_list()

    @pyqtSlot()
    def on_displayButton_clicked(self):
        index_member = self.treeWidget.currentIndex().row()
        nodule_select = None
        if self.noduletreeWidget.selectedItems()[0].parent():
            directory = self.noduletreeWidget.selectedItems()[0].parent().text(
                2)
            nodule_select = self.noduletreeWidget.currentIndex().row()
            index_scan = self.noduletreeWidget.indexFromItem(
                self.noduletreeWidget.selectedItems()[0].parent()).row()
        else:
            directory = self.noduletreeWidget.selectedItems()[0].text(2)
            index_scan = self.noduletreeWidget.indexFromItem(
                self.noduletreeWidget.selectedItems()[0]).row()

        self.display_dialog = CthreeD()
        self.display_dialog.updata_data_signal.connect(
            partial(self.update_data, index_member, index_scan))
        self.display_dialog.show()
        self.display_dialog.w = self.display_dialog.imgLabel_1.width()
        self.display_dialog.h = self.display_dialog.imgLabel_1.height()
        self.display_dialog.load_dicomfile(
            directory=directory,
            nodule_select=nodule_select,
            scan=self.data['members'][index_member]['scans'][index_scan])

    def update_data(self, index_member, index_scan, data_csv):
        self.data['members'][index_member]['scans'][index_scan]['nodules'] = []
        for row in data_csv:
            self.data['members'][index_member]['scans'][index_scan][
                'nodules'].append(row)
        self.refresh_scan_list(member=self.data['members'][index_member])

        self.management(index_member)

    def mousePressEvent(self, event):
        if app.focusWidget():
            self.setFocus()

    # TODO Not complete enough
    def management(self, index_member=None):
        """
        Get highest Lung-RADS score and match the date to show management
        """
        # diameter for solid component is needed for class 4 if nodule type is part-solid
        scores = []
        scans_date = []
        max_solid_component_diameter = 0
        for s in self.data['members'][index_member]['scans']:
            y, m, d = s['scan_date'].split(sep='-')
            scans_date.append(datetime(int(y), int(m), int(d)))
            for n in s['nodules']:
                scores.append(n['score'])
                if n['type'] == '3':
                    if eval(n['diameter']
                            ) * 0.5 > max_solid_component_diameter:
                        max_solid_component_diameter = eval(
                            n['diameter']) * 0.5
        newest = datetime(1000, 1, 1)
        for scan_date in scans_date:
            if scan_date > newest:
                newest = scan_date
        management = ''
        if '?' in scores:
            max_score = '?'
            management = '?'
        else:
            breaker = False
            max_score = '0'
            for s in ['4X', '4B', '4A', '3', '2', '1', '0']:
                if scores.__len__() == 0:
                    print('no nodule')
                    max_score = '1'
                    break

                for score in scores:
                    if score == s:
                        max_score = s
                        breaker = True
                        break
                if breaker:
                    break

            if max_score == '0':
                management = 'Additional lung cancer screening CT images and/or comparison to ' \
                             'prior chest CT examinations is needed'
            elif max_score == '1' or max_score == '2':
                management = f'LDCT @ {newest.date()+relativedelta(years=1)}'
            elif max_score == '3':
                management = f'LDCT @ {newest.date()+relativedelta(months=6)}'
            elif max_score == '4A':
                management = f'LDCT @ {newest.date()+relativedelta(months=3)}'
                if max_solid_component_diameter >= 8:
                    management += ' (PET/CT may be used)'
            elif max_score == '4B' or max_score == '4X':
                management = f'Chest CT w/ or w/o contrast, PET/CT and/or tissue sampling may be used'
                # TODO 這邊是如果有新生大結節才要的
                # management += '1 month LDCT may be recommended to
                # address potentially infectious or inflammatory conditions'

        self.data['members'][index_member]['score'] = max_score
        self.data['members'][index_member]['management'] = management
        self.refresh_patient_list()

    @pyqtSlot()
    def on_detectButton_clicked(self):
        # show status on statusbar
        self.statusBar().showMessage(
            'Model predicting, please wait for a while ...')
        self.statusBar().repaint()
        QApplication.instance().processEvents()

        # TODO Check if selected scan is already detected
        index_member = self.treeWidget.currentIndex().row()
        index_scan = self.noduletreeWidget.currentIndex().row()

        if use_win10:
            csv_data = detect(
                self.data['members'][index_member]['scans'][index_scan]
                ['scan_path'], self.nodulenet_model, self.classification_model,
                self.data['preferences'])
        else:
            csv_data = None

        self.update_data(index_member, index_scan, csv_data)
        self.data['members'][index_member]['scans'][index_scan][
            'updated'] = True
        self.refresh_scan_list(self.data['members'][index_member])
        status = [
            scan['updated']
            for scan in self.data['members'][index_member]['scans']
        ]
        if False not in status:
            self.data['members'][index_member]['updated'] = True
            self.refresh_patient_list()
        self.statusBar().showMessage('Done.', msecs=5000)
        self.management(index_member)

    @pyqtSlot()
    def on_savechangesButton_clicked(self):
        messagebox = QMessageBox.warning(
            self, 'Are you sure you want to save changes?',
            'You cannot undo this action, re-detect scans if necessary.',
            QMessageBox.Ok | QMessageBox.Cancel, QMessageBox.Ok)
        if messagebox == QMessageBox.Ok:
            with open(pkg_name, 'w') as json_file:
                json.dump(self.data, json_file, indent=2)
Ejemplo n.º 45
0
    def init(self, context):
        self._log.debug("init")

        self._preferences = Preferences()
        self._show_tasks = self._preferences.get_bool("IssuesShowTasks", True)
        self._show_warnings = self._preferences.get_bool(
            "IssuesShowWarnings", True)

        self._context = context

        self._icons = {
            Issue.SEVERITY_WARNING:
            pixbuf_new_from_file(find_resource("icons/warning.png")),
            Issue.SEVERITY_ERROR:
            pixbuf_new_from_file(find_resource("icons/error.png")),
            Issue.SEVERITY_INFO:
            None,
            Issue.SEVERITY_TASK:
            pixbuf_new_from_file(find_resource("icons/task.png"))
        }

        self._store = gtk.ListStore(Pixbuf, str, str, object)

        self._view = gtk.TreeView(self._store)

        column = gtk.TreeViewColumn()
        column.set_title("Message")

        pixbuf_renderer = gtk.CellRendererPixbuf()
        column.pack_start(pixbuf_renderer, False)
        column.add_attribute(pixbuf_renderer, "pixbuf", 0)

        text_renderer = gtk.CellRendererText()
        column.pack_start(text_renderer, True)
        column.add_attribute(text_renderer, "markup", 1)

        self._view.append_column(column)
        self._view.insert_column_with_attributes(-1,
                                                 "File",
                                                 gtk.CellRendererText(),
                                                 markup=2)
        self._handlers[self._view] = self._view.connect(
            "row-activated", self._on_row_activated)

        self._scr = gtk.ScrolledWindow()

        self._scr.add(self._view)
        self._scr.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
        self._scr.set_shadow_type(gtk.SHADOW_IN)

        self.pack_start(self._scr, True)

        # toolbar

        self._button_warnings = gtk.ToggleToolButton()
        self._button_warnings.set_tooltip_text("Show/Hide Warnings")
        image = gtk.Image()
        image.set_from_file(find_resource("icons/warning.png"))
        self._button_warnings.set_icon_widget(image)
        self._button_warnings.set_active(self._show_warnings)
        self._handlers[self._button_warnings] = self._button_warnings.connect(
            "toggled", self.__on_warnings_toggled)

        self._button_tasks = gtk.ToggleToolButton()
        self._button_tasks.set_tooltip_text("Show/Hide Tasks")
        imageTask = gtk.Image()
        imageTask.set_from_file(find_resource("icons/task.png"))
        self._button_tasks.set_icon_widget(imageTask)
        self._button_tasks.set_active(self._show_tasks)
        self._handlers[self._button_tasks] = self._button_tasks.connect(
            "toggled", self.__on_tasks_toggled)

        toolbar = gtk.Toolbar()
        toolbar.set_orientation(gtk.ORIENTATION_VERTICAL)
        toolbar.set_style(gtk.TOOLBAR_ICONS)
        toolbar.set_icon_size(gtk.ICON_SIZE_MENU)
        toolbar.insert(self._button_warnings, -1)
        toolbar.insert(self._button_tasks, -1)

        self.pack_start(toolbar, False)

        self._issues = []
        self._preferences.register_monitor(self)

        self._log.debug("init finished")
Ejemplo n.º 46
0
class IndicatorSysmonitor(object):
    SENSORS_DISABLED = False

    def __init__(self):
        self._preferences_dialog = None
        self._help_dialog = None

        self.ind = Gtk.Button.new()
        self.ind.set_label("Init...")

        self._create_menu()

        self.alive = Event()
        self.alive.set()

        self.sensor_mgr = SensorManager()
        self.load_settings()

    def _create_menu(self):
        """Creates the main menu and shows it."""
        # create menu {{{
        menu = Gtk.Menu()
        # add System Monitor menu item
        full_sysmon = Gtk.MenuItem(_('System Monitor'))
        full_sysmon.connect('activate', self.on_full_sysmon_activated)
        menu.add(full_sysmon)
        menu.add(Gtk.SeparatorMenuItem())

        # add preferences menu item
        pref_menu = Gtk.MenuItem(_('Preferences'))
        pref_menu.connect('activate', self.on_preferences_activated)
        menu.add(pref_menu)

        # add help menu item
        help_menu = Gtk.MenuItem(_('Help'))
        help_menu.connect('activate', self._on_help)
        menu.add(help_menu)

        menu.show_all()

        self.popup = menu
        self.ind.connect('clicked', self.popup_menu)
        logging.info("Menu shown")
        # }}} menu done!

    def popup_menu(self, *args):
        self.popup.popup(None, None, None, None, 0,
                         Gtk.get_current_event_time())

    def update_indicator_guide(self):

        guide = self.sensor_mgr.get_guide()

    def update(self, data):
        # data is the dict of all sensors and their values
        # { name, label }

        # look through data and find out if there are any icons to be set
        for sensor in data:
            test_str = data[sensor].lower()
            if "use_icon" in test_str:
                path = data[sensor].split(":")[1]
                print(path)
                self.ind.set_icon_full(path, "")
                # now strip the icon output from data so that it is not displayed
                remaining = test_str.split("use_icon")[0].strip()
                if not remaining:
                    remaining = " "

                data[sensor] = remaining

            if "clear_icon" in test_str:
                self.ind.set_icon_full(self.tindicator, "")

                remaining = test_str.split("clear_icon")[0].strip()
                if not remaining:
                    remaining = " "

                data[sensor] = remaining

        label = self.sensor_mgr.get_label(data)

        def update_label(label):
            self.ind.set_label(label)
            return False

        if label and self.ind:
            GLib.idle_add(update_label, label.strip())

    def load_settings(self):

        self.sensor_mgr.load_settings()
        self.sensor_mgr.initiate_fetcher(self)
        self.update_indicator_guide()

    # @staticmethod
    def save_settings(self):
        self.sensor_mgr.save_settings()

    def update_settings(self):
        self.sensor_mgr.initiate_fetcher(self)

    # actions raised from menu
    def on_preferences_activated(self, event=None):
        """Raises the preferences dialog. If it's already open, it's
        focused"""
        if self._preferences_dialog is not None:
            self._preferences_dialog.present()
            return

        self._preferences_dialog = Preferences(self)
        self._preferences_dialog.run()
        self._preferences_dialog = None

    def on_full_sysmon_activated(self, event=None):
        os.system('gnome-system-monitor &')

    def on_exit(self, event=None, data=None):
        """Action call when the main programs is closed."""
        # cleanup temporary indicator icon
        os.remove(self.tindicator)
        # close the open dialogs
        if self._help_dialog is not None:
            self._help_dialog.destroy()

        if self._preferences_dialog is not None:
            self._preferences_dialog.destroy()

        logging.info("Terminated")
        self.alive.clear()  # DM: why bother with Event() ???

        try:
            Gtk.main_quit()
        except RuntimeError:
            pass

    def _on_help(self, event=None, data=None):
        """Raise a dialog with info about the app."""
        if self._help_dialog is not None:
            self._help_dialog.present()
            return

        self._help_dialog = Gtk.MessageDialog(
            None, Gtk.DialogFlags.DESTROY_WITH_PARENT, Gtk.MessageType.INFO,
            Gtk.ButtonsType.OK, None)

        self._help_dialog.set_title(_("Help"))
        self._help_dialog.set_markup(HELP_MSG)
        self._help_dialog.run()
        self._help_dialog.destroy()
        self._help_dialog = None
Ejemplo n.º 47
0
class IssueView(BottomView, IPreferencesMonitor):
    """
	"""

    _log = getLogger("IssueView")

    label = "Issues"
    icon = gtk.STOCK_DIALOG_INFO
    scope = View.SCOPE_EDITOR

    def __init__(self, context, editor):
        BottomView.__init__(self, context)
        self._editor = editor
        self._handlers = {}

    def init(self, context):
        self._log.debug("init")

        self._preferences = Preferences()
        self._show_tasks = self._preferences.get_bool("IssuesShowTasks", True)
        self._show_warnings = self._preferences.get_bool(
            "IssuesShowWarnings", True)

        self._context = context

        self._icons = {
            Issue.SEVERITY_WARNING:
            pixbuf_new_from_file(find_resource("icons/warning.png")),
            Issue.SEVERITY_ERROR:
            pixbuf_new_from_file(find_resource("icons/error.png")),
            Issue.SEVERITY_INFO:
            None,
            Issue.SEVERITY_TASK:
            pixbuf_new_from_file(find_resource("icons/task.png"))
        }

        self._store = gtk.ListStore(Pixbuf, str, str, object)

        self._view = gtk.TreeView(self._store)

        column = gtk.TreeViewColumn()
        column.set_title("Message")

        pixbuf_renderer = gtk.CellRendererPixbuf()
        column.pack_start(pixbuf_renderer, False)
        column.add_attribute(pixbuf_renderer, "pixbuf", 0)

        text_renderer = gtk.CellRendererText()
        column.pack_start(text_renderer, True)
        column.add_attribute(text_renderer, "markup", 1)

        self._view.append_column(column)
        self._view.insert_column_with_attributes(-1,
                                                 "File",
                                                 gtk.CellRendererText(),
                                                 markup=2)
        self._handlers[self._view] = self._view.connect(
            "row-activated", self._on_row_activated)

        self._scr = gtk.ScrolledWindow()

        self._scr.add(self._view)
        self._scr.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
        self._scr.set_shadow_type(gtk.SHADOW_IN)

        self.pack_start(self._scr, True)

        # toolbar

        self._button_warnings = gtk.ToggleToolButton()
        self._button_warnings.set_tooltip_text("Show/Hide Warnings")
        image = gtk.Image()
        image.set_from_file(find_resource("icons/warning.png"))
        self._button_warnings.set_icon_widget(image)
        self._button_warnings.set_active(self._show_warnings)
        self._handlers[self._button_warnings] = self._button_warnings.connect(
            "toggled", self.__on_warnings_toggled)

        self._button_tasks = gtk.ToggleToolButton()
        self._button_tasks.set_tooltip_text("Show/Hide Tasks")
        imageTask = gtk.Image()
        imageTask.set_from_file(find_resource("icons/task.png"))
        self._button_tasks.set_icon_widget(imageTask)
        self._button_tasks.set_active(self._show_tasks)
        self._handlers[self._button_tasks] = self._button_tasks.connect(
            "toggled", self.__on_tasks_toggled)

        toolbar = gtk.Toolbar()
        toolbar.set_orientation(gtk.ORIENTATION_VERTICAL)
        toolbar.set_style(gtk.TOOLBAR_ICONS)
        toolbar.set_icon_size(gtk.ICON_SIZE_MENU)
        toolbar.insert(self._button_warnings, -1)
        toolbar.insert(self._button_tasks, -1)

        self.pack_start(toolbar, False)

        self._issues = []
        self._preferences.register_monitor(self)

        self._log.debug("init finished")

    def _on_row_activated(self, view, path, column):
        """
		A row has been double-clicked on
		"""
        issue = self._store.get(self._store.get_iter(path), 3)[0]

        self._context.activate_editor(issue.file)

        #~ # FIXME: this doesn't work correctly
        #~ if not self._context.active_editor is None:
        #~ self._context.active_editor.select(issue.start, issue.end)
        self._editor.select(issue.start, issue.end)

    def _on_value_changed(self, key, value):
        if key == "IssuesShowWarnings" or key == "IssuesShowTasks":
            # update filter
            self._store.clear()
            for issue, local in self._issues:
                self.__append_issue_filtered(issue, local)

    def __on_tasks_toggled(self, togglebutton):
        self._show_tasks = togglebutton.get_active()
        self._preferences.set("IssuesShowTasks", self._show_tasks)

    def __on_warnings_toggled(self, togglebutton):
        self._show_warnings = togglebutton.get_active()
        self._preferences.set("IssuesShowWarnings", self._show_warnings)

    def clear(self):
        """
		Remove all issues from the view
		"""
        self.assure_init()
        self._store.clear()
        self._issues = []

    def append_issue(self, issue, local=True):
        """
		Append a new Issue to the view
		
		@param issue: the Issue object
		@param local: indicates whether the Issue occured in the edited file or not
		"""
        self.assure_init()
        self._issues.append((issue, local))
        self.__append_issue_filtered(issue, local)

    def __append_issue_filtered(self, issue, local):
        if issue.severity == Issue.SEVERITY_WARNING:
            if self._show_warnings:
                self.__do_append_issue(issue, local)
        elif issue.severity == Issue.SEVERITY_TASK:
            if self._show_tasks:
                self.__do_append_issue(issue, local)
        else:
            self.__do_append_issue(issue, local)

    def __do_append_issue(self, issue, local):
        if local:
            message = issue.message
            filename = escape(issue.file.basename)
        else:
            message = "<span color='%s'>%s</span>" % (self._preferences.get(
                "LightForeground", "#7f7f7f"), issue.message)
            filename = "<span color='%s'>%s</span>" % (self._preferences.get(
                "LightForeground", "#7f7f7f"), issue.file.basename)
        self._store.append(
            [self._icons[issue.severity], message, filename, issue])

    def destroy(self):
        del self._editor
        self._preferences.remove_monitor(self)
        for obj in self._handlers:
            obj.disconnect(self._handlers[obj])
        BottomView.destroy(self)
Ejemplo n.º 48
0
    def open_preferences_window(self):
        """Opens settings window."""

        settings = Preferences(self)
        if settings.exec():
            self.server_IP = settings.server_IP.text()
Ejemplo n.º 49
0
class ANoise:
    """Control the sound indicator"""
    def __init__(self):
        # These 3 are need
        GObject.threads_init()
        DBusGMainLoop(set_as_default=True)
        Gst.init(None)

        self.sound_menu = SoundMenuControls('anoise')
        self.noise = Noise()
        self.win_preferences = Preferences(self)

        # Need in a few DE
        try:
            self.window = GUI(self)
        except:
            pass

        self.player = Gst.ElementFactory.make(PLAYBIN, "player")
        self.player.connect("about-to-finish", self._loop)

        self.player.set_property('uri', self.noise.get_current_filename())
        self.is_playing = True

        dummy_i18n = (_("Coffee Shop"), _("Fire"), _("Forest"), _("Night"),
                      _("Rain"), _("River"), _("Sea"), _("Storm"), _("Wind")
                      )  # Need i18n

        # Overwrite libraty methods
        self.sound_menu._sound_menu_is_playing = self._sound_menu_is_playing
        self.sound_menu._sound_menu_play = self._sound_menu_play
        self.sound_menu._sound_menu_pause = self._sound_menu_pause
        self.sound_menu._sound_menu_next = self._sound_menu_next
        self.sound_menu._sound_menu_previous = self._sound_menu_previous
        self.sound_menu._sound_menu_raise = self._sound_menu_raise

        # Autostart when click on sound indicator icon
        threading.Timer(2, self._sound_menu_play).start()

    def _loop(self, message):
        """Start again the same sound in the EOS"""
        self.player.set_property('uri', self.noise.get_current_filename())

    def _sound_menu_is_playing(self):
        """Called in the first click"""
        return self.is_playing

    def _sound_menu_play(self):
        """Play"""
        self.is_playing = True  # Need to overwrite this for an issue with autstart
        self.sound_menu.song_changed('', '', self.noise.get_name(),
                                     self.noise.get_icon())
        self.player.set_state(Gst.State.PLAYING)
        self.sound_menu.signal_playing()

    def _sound_menu_pause(self):
        """Pause"""
        self.is_playing = False  # Need to overwrite this for an issue with autstart
        self.player.set_state(Gst.State.PAUSED)
        self.sound_menu.signal_paused()

    def _set_new_play(self, what):
        """Next or Previous"""
        self.noise.refresh_all_ogg()
        # Get Next/Previous
        if what == 'next':
            self.noise.set_next()
        if what == 'previous':
            self.noise.set_previous()
        # From pause?
        self.player.set_state(Gst.State.READY)
        if not self.is_playing:
            self.is_playing = True
        # Set new sound
        self.player.set_property('uri', self.noise.get_current_filename())
        # Play
        self._sound_menu_play()

    def _sound_menu_previous(self):
        """Previous"""
        self._set_new_play('previous')

    def _sound_menu_next(self):
        """Next"""
        self._set_new_play('next')

    def _sound_menu_raise(self):
        """Click on player"""
        self.win_preferences.show()

    def set_timer(self, enable, seconds):
        if enable:
            self.timer = threading.Timer(seconds, self._set_future_pause)
            self.timer.start()
        else:
            self.timer.cancel()

    def _set_future_pause(self):
        self.win_preferences.set_show_timer()
        self._sound_menu_pause()
Ejemplo n.º 50
0
    def storeSliderValue(self):
        if self.sizeButton.isChecked():
            if self.editMode == editModes.newTextBox:
                Preferences.updateKeyValue('textSize', self.slider.value())
            elif self.editMode == editModes.marker:
                Preferences.updateKeyValue('markerSize', self.slider.value())
            elif self.editMode == editModes.freehand:
                Preferences.updateKeyValue('freehandSize', self.slider.value())
            elif self.editMode == editModes.forms:
                Preferences.updateKeyValue('formSize', self.slider.value())
        elif self.colorButton.isChecked():
            normRGB = colorsys.hsv_to_rgb(self.slider.value() / 100, 1, 1)

            if self.editMode == editModes.marker:
                Preferences.updateKeyValue(
                    'markerColor', tuple(map(lambda x: str(x), normRGB)))
            elif self.editMode == editModes.freehand:
                Preferences.updateKeyValue(
                    'freehandColor', tuple(map(lambda x: str(x), normRGB)))
            elif self.editMode == editModes.forms:
                Preferences.updateKeyValue(
                    'formColor', tuple(map(lambda x: str(x), normRGB)))

        self.settingsChanged.emit()
Ejemplo n.º 51
0
class GtkUI(GtkPluginBase):


  def __init__(self, plugin_name):

    super(GtkUI, self).__init__(plugin_name)
    self.initialized = False
    self.retries = 0


  def enable(self):

    self.timestamp = None
    self.label_data = None

    client.labelplus.is_initialized().addCallback(self.cb_check)


  def cb_check(self, result):

    if result == True:
      client.labelplus.get_label_data(self.timestamp).addCallback(
        self.cb_data_init)
    elif self.retries < MAX_RETRIES:
      reactor.callLater(WAIT_TIME, self.enable)
      self.retries += 1


  def cb_data_init(self, data):

    self.timestamp = data[0]
    self.label_data = data[1]

    self.label_data[ID_ALL]["name"] = _(ID_ALL)
    self.label_data[ID_NONE]["name"] = _(ID_NONE)

    self._do_load()


  def _do_load(self):

    self._config = deluge.configmanager.ConfigManager(
        GTKUI_CONFIG, defaults=GTKUI_DEFAULTS)

    component.get("TorrentView").add_text_column(DISPLAY_NAME,
        status_field=[STATUS_NAME])

    self.label_selection_menu = LabelSelectionMenu()
    self.sep = component.get("MenuBar").add_torrentmenu_separator()
    component.get("MenuBar").torrentmenu.append(self.label_selection_menu)

    self.label_sidebar = LabelSidebar()

    self.preferences = Preferences()

    self.add_torrent_ext = AddTorrentExt()

    self.enable_dnd()

    self.initialized = True


  def disable(self):

    self.retries = MAX_RETRIES

    if self.initialized:
      self.initialized = False

      self._config.save()
      deluge.configmanager.close(self._config)

      self.disable_dnd()

      component.get("MenuBar").torrentmenu.remove(self.sep)
      component.get("MenuBar").torrentmenu.remove(self.label_selection_menu)
      self.label_selection_menu.destroy()
      del self.label_selection_menu

      self.label_sidebar.unload()
      del self.label_sidebar

      self.preferences.unload()

      self.add_torrent_ext.unload()

      component.get("TorrentView").remove_column(DISPLAY_NAME)


  def update(self):

    if self.initialized:
      client.labelplus.get_label_data(self.timestamp).addCallback(
        self.cb_update_data)


  def cb_update_data(self, data):

    if data is not None:
      self.timestamp = data[0]
      self.label_data = data[1]

      self.label_data[ID_ALL]["name"] = _(ID_ALL)
      self.label_data[ID_NONE]["name"] = _(ID_NONE)

      self.label_sidebar.update_counts(self.label_data)


  def get_labels(self):

    data = self.label_data
    labels = []
    for id in data:
      if id not in RESERVED_IDS:
        labels.append((id, data[id]["name"]))

    return labels


  def get_label_counts(self):

    return self.label_data


  def enable_dnd(self):


    def get_drag_icon(widget, x, y):

      num = widget.get_selection().count_selected_rows()

      if num > 1:
        pixbuf = self.icon_multiple
      else:
        pixbuf = self.icon_single

      return (pixbuf, 0, 0)


    def get_ids(widget, path, col, selection, *args):

      selection.set("TEXT", 8, "OK")

      return True


    def receive_ids(widget, path, col, pos, selection, *args):

      if selection.data == "OK":
        model = widget.get_model()
        id = model[path][0]

        if id == ID_NONE:
          id = None

        if id not in RESERVED_IDS:
          torrents = component.get("TorrentView").get_selected_torrents()
          client.labelplus.set_torrent_labels(id, torrents)

          return True


    def peek_ids(widget, path, col, pos, selection, *args):

      if selection.data == "OK":
        model = widget.get_model()
        id = model[path][0]

        if id == ID_NONE:
          id = None

        if id not in RESERVED_IDS:
          return True


    class ModuleFilter(object):


      def filter(self, record):

        record.msg = "[%s] %s" % (PLUGIN_NAME, record.msg)

        return True


    dnd.log.setLevel(logging.INFO)
    dnd.log.addFilter(ModuleFilter())

    src_target = dnd.DragTarget(
      name="torrent_ids",
      scope=gtk.TARGET_SAME_APP,
      action=gtk.gdk.ACTION_MOVE,
      data_func=get_ids,
    )

    src_treeview = component.get("TorrentView").treeview

    self.icon_single = \
        src_treeview.render_icon(gtk.STOCK_DND, gtk.ICON_SIZE_DND)
    self.icon_multiple = \
        src_treeview.render_icon(gtk.STOCK_DND_MULTIPLE, gtk.ICON_SIZE_DND)

    self.src_proxy = dnd.TreeViewDragSourceProxy(src_treeview, get_drag_icon)
    self.src_proxy.add_target(src_target)

    dest_target = dnd.DragTarget(
      name="torrent_ids",
      scope=gtk.TARGET_SAME_APP,
      action=gtk.gdk.ACTION_MOVE,
      pos=gtk.TREE_VIEW_DROP_INTO_OR_BEFORE,
      data_func=receive_ids,
      aux_func=peek_ids,
    )

    dest_treeview = self.label_sidebar.label_tree
    self.dest_proxy = dnd.TreeViewDragDestProxy(dest_treeview)
    self.dest_proxy.add_target(dest_target)


  def disable_dnd(self):

    self.dest_proxy.unload()
    self.src_proxy.unload()
class IndicatorSysmonitor(object):
    SENSORS_DISABLED = False

    def __init__(self):
        self._preferences_dialog = None
        self._help_dialog = None

        #fn, self.tindicator = tempfile.mkstemp(suffix=".svg")

        #with open(self.tindicator, "w") as f:
        #    svg = '<?xml version="1.0" encoding="UTF-8" \
        #                standalone="no"?><svg id="empty" xmlns="http://www.w3.org/2000/svg" \
        #                height="22" width="1" version="1.0" \
        #                xmlns:xlink="http://www.w3.org/1999/xlink"></svg>'
        #    f.write(svg)
        #    f.close()

        #self.ind = appindicator.Indicator.new("indicator-sysmonitor", self.tindicator, \
        #                                      appindicator.IndicatorCategory.SYSTEM_SERVICES)
        self.ind = Gtk.Button.new()
        #self.ind.set_ordering_index(0)

        #self.ind.set_status(appindicator.IndicatorStatus.ACTIVE)
        self.ind.set_label("Init...")

        self._create_menu()

        self.alive = Event()
        self.alive.set()

        self.sensor_mgr = SensorManager()
        self.load_settings()

    def _create_menu(self):
        """Creates the main menu and shows it."""
        # create menu {{{
        menu = Gtk.Menu()
        # add System Monitor menu item
        full_sysmon = Gtk.MenuItem(_('System Monitor'))
        full_sysmon.connect('activate', self.on_full_sysmon_activated)
        menu.add(full_sysmon)
        menu.add(Gtk.SeparatorMenuItem())

        # add preferences menu item
        pref_menu = Gtk.MenuItem(_('Preferences'))
        pref_menu.connect('activate', self.on_preferences_activated)
        menu.add(pref_menu)

        # add help menu item
        help_menu = Gtk.MenuItem(_('Help'))
        help_menu.connect('activate', self._on_help)
        menu.add(help_menu)

        # add preference menu item
        #exit_menu = Gtk.MenuItem(_('Quit'))
        #exit_menu.connect('activate', self.on_exit)
        #menu.add(exit_menu)

        menu.show_all()

        self.popup = menu
        self.ind.connect('clicked', self.popup_menu)
        logging.info("Menu shown")
        # }}} menu done!

    def popup_menu(self, *args):
        self.popup.popup(None, None, None, None, 0,
                         Gtk.get_current_event_time())

    def update_indicator_guide(self):

        guide = self.sensor_mgr.get_guide()

        #self.ind.set_property("label-guide", guide)

    def update(self, data):
        # data is the dict of all sensors and their values
        # { name, label }

        # look through data and find out if there are any icons to be set
        for sensor in data:
            test_str = data[sensor].lower()
            if "use_icon" in test_str:
                path = data[sensor].split(":")[1]
                print(path)
                self.ind.set_icon_full(path, "")
                # now strip the icon output from data so that it is not displayed
                remaining = test_str.split("use_icon")[0].strip()
                if not remaining:
                    remaining = " "

                data[sensor] = remaining

            if "clear_icon" in test_str:
                self.ind.set_icon_full(self.tindicator, "")

                remaining = test_str.split("clear_icon")[0].strip()
                if not remaining:
                    remaining = " "

                data[sensor] = remaining

        label = self.sensor_mgr.get_label(data)

        Gdk.threads_enter()
        self.ind.set_label(label.strip())
        Gdk.threads_leave()

        #self.ind.set_title(label.strip())

    def load_settings(self):

        self.sensor_mgr.load_settings()
        self.sensor_mgr.initiate_fetcher(self)
        self.update_indicator_guide()

    # @staticmethod
    def save_settings(self):
        self.sensor_mgr.save_settings()

    # actions raised from menu
    def on_preferences_activated(self, event=None):
        """Raises the preferences dialog. If it's already open, it's
        focused"""
        if self._preferences_dialog is not None:
            self._preferences_dialog.present()
            return

        self._preferences_dialog = Preferences(self)
        self._preferences_dialog.run()
        self._preferences_dialog = None

    def on_full_sysmon_activated(self, event=None):
        os.system('gnome-system-monitor &')

    def on_exit(self, event=None, data=None):
        """Action call when the main programs is closed."""
        # cleanup temporary indicator icon
        os.remove(self.tindicator)
        # close the open dialogs
        if self._help_dialog is not None:
            self._help_dialog.destroy()

        if self._preferences_dialog is not None:
            self._preferences_dialog.destroy()

        logging.info("Terminated")
        self.alive.clear()  # DM: why bother with Event() ???

        try:
            Gtk.main_quit()
        except RuntimeError:
            pass

    def _on_help(self, event=None, data=None):
        """Raise a dialog with info about the app."""
        if self._help_dialog is not None:
            self._help_dialog.present()
            return

        self._help_dialog = Gtk.MessageDialog(
            None, Gtk.DialogFlags.DESTROY_WITH_PARENT, Gtk.MessageType.INFO,
            Gtk.ButtonsType.OK, None)

        self._help_dialog.set_title(_("Help"))
        self._help_dialog.set_markup(HELP_MSG)
        self._help_dialog.run()
        self._help_dialog.destroy()
        self._help_dialog = None
Ejemplo n.º 53
0
 def initialize_with_dict(self):
     self.defaults_with_dict = {"x1": 1, "x2": 2, "x3": 3}
     P = Preferences(defaults=self.defaults_with_dict,
                     filename=self.filename)
     return P
Ejemplo n.º 54
0
 def initialize_with_keywords(self):
     P = Preferences(filename=self.filename, x1=1, x2=2, x3=3)
     return P
Ejemplo n.º 55
0
class GtkUI(GtkPluginBase):


  def __init__(self, plugin_name):

    super(GtkUI, self).__init__(plugin_name)
    self.initialized = False


  def enable(self):

    client.labelplus.is_initialized().addCallback(self.cb_check)


  def cb_check(self, result):

    if result == True:
      client.labelplus.get_label_data(None).addCallback(self.cb_data_init)
    else:
      reactor.callLater(1, self.enable)


  def cb_data_init(self, data):

    self.dialog = None
    self._config = None

    info = client.connection_info()
    self._daemon = "%s@%s:%s" % (info[2], info[0], info[1])

    self.timestamp = data[0]
    self.label_data = data[1]

    self.label_data[ID_ALL]["name"] = _(ID_ALL)
    self.label_data[ID_NONE]["name"] = _(ID_NONE)

    self._do_load()


  def _do_load(self):

    self.load_config()

    component.get("TorrentView").add_text_column(DISPLAY_NAME,
        col_type=[str, str], status_field=[STATUS_NAME, STATUS_ID])

    component.get("TorrentView").treeview.connect(
      "button-press-event", self.on_tv_button_press)

    self.menu = self._create_context_menu()
    self.sep = component.get("MenuBar").add_torrentmenu_separator()
    component.get("MenuBar").torrentmenu.append(self.menu)

    self.label_sidebar = LabelSidebar()

    self.preferences = Preferences()

    self.add_torrent_ext = AddTorrentExt()

    self.enable_dnd()

    self.status_item = None

    self.initialized = True


  def on_tv_button_press(self, widget, event):

    x, y = event.get_coords()
    path_info = widget.get_path_at_pos(int(x), int(y))
    if not path_info:
      if event.button == 3:
        self._popup_jump_menu(widget, event)
      else:
        return

    if event.button == 1 and event.type == gtk.gdk._2BUTTON_PRESS:
      if path_info[1] and path_info[1].get_title() == DISPLAY_NAME:
        id = self.get_selected_torrent_label()
        if (self.label_sidebar.page_selected() and
           id == self.label_sidebar.get_selected_label()):
          self._do_open_label_options(widget, event)
        else:
          self._do_go_to_label(widget)


  def disable(self):

    if self.initialized:
      self.initialized = False

      self._config.save()
      deluge.configmanager.close(GTKUI_CONFIG)

      self._remove_status_bar_item()

      self.disable_dnd()

      component.get("MenuBar").torrentmenu.remove(self.sep)
      component.get("MenuBar").torrentmenu.remove(self.menu)
      self._destroy_menu()

      self.label_sidebar.unload()
      del self.label_sidebar

      self.preferences.unload()

      self.add_torrent_ext.unload()

      component.get("TorrentView").remove_column(DISPLAY_NAME)


  def _create_context_menu(self):

    menu = gtk.MenuItem(DISPLAY_NAME)
    submenu = gtk.Menu()

    jump_menu = self._create_jump_menu()
    submenu.append(jump_menu)

    set_label_menu = self._create_set_label_menu()
    submenu.append(set_label_menu)

    label_options_item = self._create_label_options_item()
    submenu.append(label_options_item)


    def on_activate(widget):

      id = self.get_selected_torrent_label()
      if id not in RESERVED_IDS and id in self.label_data:
        label_options_item.show()
      else:
        label_options_item.hide()


    menu.connect("activate", on_activate)

    menu.set_submenu(submenu)
    menu.show_all()

    return menu


  def _create_label_options_item(self):


    def on_activate(widget):

      id = self.get_selected_torrent_label()
      if id not in RESERVED_IDS and id in self.label_data:
        name = self.label_data[id]["name"]
        self.label_sidebar.menu.dialog = LabelOptionsDialog(id, name)
        self.label_sidebar.menu.dialog.register_close_func(
          self.label_sidebar.menu.close_func)


    item = gtk.MenuItem(_("Label Options"))
    item.connect("activate", on_activate)

    return item


  def _create_set_label_menu(self):


    def on_select_label(widget, label_id):

      torrents = component.get("TorrentView").get_selected_torrents()
      client.labelplus.set_torrent_labels(label_id, torrents)


    def hide_unavailable(widget):

      parent_item.hide()

      id = self.get_selected_torrent_label()
      if id:
        parent = get_parent(id)
        if parent and parent not in RESERVED_IDS:
          if getattr(parent_item, "handler", None):
            parent_item.disconnect(parent_item.handler)

          handler = parent_item.connect("activate", on_select_label, parent)
          parent_item.handler = handler
          parent_item.show()


    items = []

    menu_item = gtk.MenuItem(_(ID_NONE))
    menu_item.connect("activate", on_select_label, ID_NONE)
    items.append(menu_item)

    parent_item = gtk.MenuItem(_("Parent"))
    items.append(parent_item)

    menu_item = gtk.SeparatorMenuItem()
    items.append(menu_item)

    menu = LabelSelectionMenu(_("Set Label"), on_select_label, items)
    menu.connect("activate", hide_unavailable)

    return menu


  def _create_jump_menu(self):


    def on_select_label(widget, label_id):

      self._do_go_to_label(widget, label_id)


    def hide_unavailable(widget):

      selected_item.hide()
      parent_item.hide()

      id = self.get_selected_torrent_label()
      if id:
        if getattr(selected_item, "handler", None):
          selected_item.disconnect(selected_item.handler)

        handler = selected_item.connect("activate", on_select_label, id)
        selected_item.handler = handler
        selected_item.show()

      elif self.label_sidebar.page_selected():
        id = self.label_sidebar.get_selected_label()

      if id:
        parent = get_parent(id)
        if parent and parent not in RESERVED_IDS:
          if getattr(parent_item, "handler", None):
            parent_item.disconnect(parent_item.handler)

          handler = parent_item.connect("activate", on_select_label, parent)
          parent_item.handler = handler
          parent_item.show()


    items = []

    menu_item = gtk.MenuItem(_(ID_ALL))
    menu_item.connect("activate", on_select_label, ID_ALL)
    items.append(menu_item)

    menu_item = gtk.MenuItem(_(ID_NONE))
    menu_item.connect("activate", on_select_label, ID_NONE)
    items.append(menu_item)

    selected_item = gtk.MenuItem(_("Selected"))
    items.append(selected_item)

    parent_item = gtk.MenuItem(_("Parent"))
    items.append(parent_item)

    menu_item = gtk.SeparatorMenuItem()
    items.append(menu_item)

    menu = LabelSelectionMenu(_("Jump To"), on_select_label, items)
    menu.connect("activate", hide_unavailable)

    return menu


  def _popup_jump_menu(self, widget, event):

    top = gtk.Menu()
    menu = gtk.MenuItem(DISPLAY_NAME)
    submenu = gtk.Menu()

    submenu.append(self._create_jump_menu())
    menu.set_submenu(submenu)
    top.append(menu)

    top.show_all()
    top.popup(None, None, None, event.button, event.time)


  def _destroy_menu(self):

    self.menu.destroy()
    del self.menu


  def _do_go_to_label(self, widget, id=None):

    if not id:
      id = self.get_selected_torrent_label()

    if id is not None:
      self.label_sidebar.select_label(id)


  def load_config(self):

    self._config = deluge.configmanager.ConfigManager(GTKUI_CONFIG)

    source = get_version(self._config.config)
    target = get_version(GTKUI_DEFAULTS)

    if len(self._config.config) == 0:
      self._config._Config__config = copy.deepcopy(GTKUI_DEFAULTS)
    else:
      if source != target:
        map = GTKUI_MAPS.get((source, target), None)
        if map:
          self._config._Config__config = convert(self._config.config, map)
        else:
          self._config._Config__config = copy.deepcopy(GTKUI_DEFAULTS)
      else:
        self.normalize_config()

    if target >= 2:
      daemons = self._config["daemon"]
      if self._daemon not in daemons:
        daemons[self._daemon] = copy.deepcopy(DAEMON_DEFAULTS)


  def normalize_config(self):

    commons = dict(GTKUI_DEFAULTS["common"])
    commons.update(self._config.config["common"])
    self._config.config["common"] = commons

    saved_daemons = component.get("ConnectionManager").config["hosts"]
    if not saved_daemons:
      self._config["daemon"] = {}
    else:
      daemons = ["%s@%s:%s" % (x[3], x[1], x[2]) for x in saved_daemons]

      for daemon in self._config["daemon"].keys():
        if "@localhost:" in daemon or "@127.0.0.1:" in daemon:
          continue

        if daemon != self._daemon and daemon not in daemons:
          del self._config["daemon"][daemon]


  def update(self):

    if self.initialized:
      client.labelplus.get_label_data(self.timestamp).addCallback(
        self.cb_update_data)

      if self._config["common"]["show_label_bandwidth"]:
        if not self.status_item:
          self._add_status_bar_item()
          reactor.callLater(1, self._status_bar_update)
      else:
        self._remove_status_bar_item()


  def cb_update_data(self, data):

    if data is not None:
      self.timestamp = data[0]
      self.label_data = data[1]

      self.label_data[ID_ALL]["name"] = _(ID_ALL)
      self.label_data[ID_NONE]["name"] = _(ID_NONE)

      self.label_sidebar.update_counts(self.label_data)


  def get_labels(self):

    data = self.label_data
    labels = []
    for id in data:
      if id not in RESERVED_IDS:
        labels.append((id, data[id]["name"]))

    return labels


  def get_label_counts(self):

    return self.label_data


  def enable_dnd(self):


    def get_drag_icon(widget, x, y):

      num = widget.get_selection().count_selected_rows()

      if num > 1:
        pixbuf = self.icon_multiple
      else:
        pixbuf = self.icon_single

      return (pixbuf, 0, 0)


    def on_drag_end(widget, context):

      if self.label_sidebar.page_selected():
        self.label_sidebar.label_tree.get_selection().emit("changed")


    def get_ids(widget, path, col, selection, *args):

      selection.set("TEXT", 8, "OK")

      return True


    def receive_ids(widget, path, col, pos, selection, *args):

      if selection.data == "OK":
        model = widget.get_model()
        id = model[path][0]

        if id == ID_NONE:
          id = None

        if id not in RESERVED_IDS:
          torrents = component.get("TorrentView").get_selected_torrents()
          client.labelplus.set_torrent_labels(id, torrents)

          return True


    def peek_ids(widget, path, col, pos, selection, *args):

      if selection.data == "OK":
        model = widget.get_model()
        id = model[path][0]

        if id == ID_NONE:
          id = None

        if id not in RESERVED_IDS:
          return True


    class ModuleFilter(object):


      def filter(self, record):

        record.msg = "[%s] %s" % (PLUGIN_NAME, record.msg)

        return True


    dnd.log.setLevel(logging.INFO)
    dnd.log.addFilter(ModuleFilter())

    src_target = dnd.DragTarget(
      name="torrent_ids",
      scope=gtk.TARGET_SAME_APP,
      action=gtk.gdk.ACTION_MOVE,
      data_func=get_ids,
    )

    src_treeview = component.get("TorrentView").treeview

    self.icon_single = \
        src_treeview.render_icon(gtk.STOCK_DND, gtk.ICON_SIZE_DND)
    self.icon_multiple = \
        src_treeview.render_icon(gtk.STOCK_DND_MULTIPLE, gtk.ICON_SIZE_DND)

    self.src_proxy = dnd.TreeViewDragSourceProxy(src_treeview,
      get_drag_icon, on_drag_end)
    self.src_proxy.add_target(src_target)

    dest_target = dnd.DragTarget(
      name="torrent_ids",
      scope=gtk.TARGET_SAME_APP,
      action=gtk.gdk.ACTION_MOVE,
      pos=gtk.TREE_VIEW_DROP_INTO_OR_BEFORE,
      data_func=receive_ids,
      aux_func=peek_ids,
    )

    dest_treeview = self.label_sidebar.label_tree
    self.dest_proxy = dnd.TreeViewDragDestProxy(dest_treeview)
    self.dest_proxy.add_target(dest_target)


  def disable_dnd(self):

    self.dest_proxy.unload()
    self.src_proxy.unload()


  def _add_status_bar_item(self):

    self.status_item = component.get("StatusBar").add_item(
      image=get_resource("labelplus_icon.png"),
      text="",
      callback=self._do_open_label_options_bandwidth,
      tooltip="")

    self.status_item._ebox.hide_all()


  def _remove_status_bar_item(self):

    if self.status_item:
      component.get("StatusBar").remove_item(self.status_item)
      self.status_item = None


  def get_selected_torrent_label(self):

    label_id = None
    tv = component.get("TorrentView")
    torrents = tv.get_selected_torrents()

    if len(torrents) > 0:
      id = torrents[0]
      status = tv.get_torrent_status(id)

      if STATUS_ID in status:
        label_id = status[STATUS_ID] or ID_NONE

        for t in torrents:
          status = tv.get_torrent_status(t)
          t_label_id = status[STATUS_ID] or ID_NONE

          if t_label_id != label_id:
            label_id = None
            break

    return label_id


  def _do_open_label_options_bandwidth(self, widget, event):

    self._do_open_label_options(widget, event, 1)


  def _do_open_label_options(self, widget, event, page=0):


    def on_close(widget):

      self.dialog = None


    if self.dialog == None:
      id = self.label_sidebar.get_selected_label()

      if id == ID_ALL or not self.label_sidebar.page_selected():
        id = self.get_selected_torrent_label()

      if id not in RESERVED_IDS and id in self.label_data:
        name = self.label_data[id]["full_name"]
        self.dialog = LabelOptionsDialog(id, name, page)
        self.dialog.register_close_func(on_close)


  def _status_bar_update(self):

    if self.status_item:
      id = self.get_selected_torrent_label()
      if not id and self.label_sidebar.page_selected():
        id = self.label_sidebar.get_selected_label()

      if id == ID_NONE or (id not in RESERVED_IDS and id in self.label_data):
        self.status_item._ebox.show_all()

        tooltip = "Bandwidth Used By: %s" % self.label_data[id]["full_name"]
        include_sublabels = self._config["common"]["status_include_sublabel"]
        if include_sublabels and id != ID_NONE:
          tooltip += "/*"

        self.status_item.set_tooltip(tooltip)

        client.labelplus.get_label_bandwidth_usage(
          id, include_sublabels).addCallbacks(
            self._do_status_bar_update, self._err_status_bar_update)
      else:
        self.status_item._ebox.hide_all()
        reactor.callLater(STATUS_UPDATE_INTERVAL, self._status_bar_update)


  def _err_status_bar_update(self, result):

    reactor.callLater(STATUS_UPDATE_INTERVAL, self._status_bar_update)


  def _do_status_bar_update(self, result):

    if self.status_item:
      download_rate = result[0]
      download_unit = "B"

      upload_rate = result[1]
      upload_unit = "B"

      for (unit, bytes) in UNITS:
        if download_rate >= bytes:
          download_rate /= bytes
          download_unit = unit
          break

      for (unit, bytes) in UNITS:
        if upload_rate >= bytes:
          upload_rate /= bytes
          upload_unit = unit
          break

      self.status_item.set_text(
        "%.1f %s/s | %.1f %s/s" % (
          download_rate, download_unit, upload_rate, upload_unit))

      reactor.callLater(STATUS_UPDATE_INTERVAL, self._status_bar_update)
Ejemplo n.º 56
0
 def initialize_with_absolute_path(self):
     absolute_path = os.path.join(CURRENT_PATH, self.filename)
     P = Preferences(defaults=self.defaults_with_dict,
                     filename=absolute_path)
     return P
Ejemplo n.º 57
0
 def open_preferences(self, widget):
     ConfigManager.disable_losefocus_temporary = True
     prefs = Preferences()
     prefs.show()
Ejemplo n.º 58
0
    def __init__(self, player):

        # apparently appindicator will not quit on Ctrl-C by default. fix
        # bellow allows it to do so in Ctrl-C run the default action kernel
        # action which allows indicator to exit
        signal.signal(signal.SIGINT, signal.SIG_DFL)

        # expose the passing player to tht class
        self._player = player

        # remove registration to dbus, disabling MPRIS integration, mainly this
        # is done because current anoise MPRIS integration does not notify the
        # GUI element of play/pause/next/forward changes internally an attempt
        # at dbus manager that listens for anoise mpris notification fails due
        # to double signaling and handling of multiple MPRIS subscribed clients
        # and inability to distinguish which come from anoise
        self._player.sound_menu.remove_from_connection()

        #: DEBUG SETTING, used during development
        #: hide window ui, if it's the GUI class (rather then Indicator class)
        # if self._player.window.__class__.__name__ == 'GUI':
        #     self._player.window.window.hide()

        # build the preferences window
        self._preferences_window = Preferences(self)

        # expose the default gtk settings
        self._gtk_settings = Gtk.Settings.get_default()

        # expose the default icon theme
        self._default_icon_theme = Gtk.IconTheme.get_default()

        # expose "hicolor" theme as fallback theme
        self._fallback_icon_theme = Gtk.IconTheme()
        self._fallback_icon_theme.set_custom_theme('hicolor')

        # expose found appindicator and appindicator-pause icons
        self._appindicator_icon, self._appindicator_icon_pause = \
            self._get_indicator_icons()

        # build the appindicator
        self._appindicator, builder = self._make_appindicator()

        # expose the play/pause menu item to the class
        self._menuitem_play = builder.get_object('play_pause_toggle')
        # expose now playing menu item
        self._menuitem_now_playing = builder.get_object('now_playing')

        # expose now playing image
        self._image_now_playing = builder.get_object('image_now_playing')
        # expose play image
        self._image_play = builder.get_object('image_play')
        # expose pause image
        self._image_pause = builder.get_object('image_pause')

        # disable startup autoplay (ugh, terrible approach)
        # runs before indicator is made visible to show the "paused" icon
        self._disable_startup_autoplay()

        # set the indicator status to active
        self._appindicator.set_status(AppIndicator3.IndicatorStatus.ACTIVE)

        # update the noise icon in the ui and the appindicator
        self._update_now_playing()
Ejemplo n.º 59
0
## 'reset_to_default(*args)'.
##
## It is also possible to incorporate automatic checks, that for example
## can check the instance or format of the saved value automatically.
## This requires overriding the method 'check_before_setting_attribute".
##
## For more information on all the methods and/or examples see the
## docstring [help(Preferences)].
##
##
## Simple example:

from preferences import Preferences

prefs_defaults = {"X": 1, "Y": 2}
prefs = Preferences(defaults=prefs_defaults, filename="preferences_test.txt")

# At first use, attributes are initialized to default
# If previous uses set them at different values, the default value will
# not override the 'different value'.
assert prefs.X == 1 and prefs.Y == 2  # True

# By setting the following attributes, their new values are
# automatically stored into the file.
prefs.X = 3
prefs.Y = 4

# attributes can be defined without default values.
prefs.Z = 5

# RESTART program (re-initializing 'prefs' gives the same results as
Ejemplo n.º 60
0
    def __init__(self):
        self.preferences = Preferences()

        parser = argparse.ArgumentParser(
            description="Manipulate Tabletop Simulator files")
        parser.add_argument("-d",
                            "--directory",
                            help="Override TTS cache directory")
        parser.add_argument("-l",
                            "--loglevel",
                            help="Set logging level",
                            choices=['debug', 'info', 'warn', 'error'])
        subparsers = parser.add_subparsers(dest='parser',
                                           title='command',
                                           description='Valid commands.')
        subparsers.required = True

        # add list command
        parser_list = subparsers.add_parser('list',
                                            help="List installed mods.",
                                            description='''
    List installed mods.
    If no id is provided, then this will return a list of all installed modules.
    If an id is provided, then this will list the contents of that modules.
    ''')
        group_list = parser_list.add_mutually_exclusive_group()
        group_list.add_argument("-w",
                                "--workshop",
                                action="store_const",
                                metavar='save_type',
                                dest='save_type',
                                const=SaveType.workshop,
                                help="List workshop files (the default).")
        group_list.add_argument("-s",
                                "--save",
                                action="store_const",
                                metavar='save_type',
                                dest='save_type',
                                const=SaveType.save,
                                help="List saves.")
        group_list.add_argument("-c",
                                "--chest",
                                action="store_const",
                                metavar='save_type',
                                dest='save_type',
                                const=SaveType.chest,
                                help="List chest files.")

        parser_list.add_argument("id",
                                 nargs='?',
                                 help="ID of specific mod to list details of.")
        parser_list.set_defaults(func=self.do_list)

        # export command
        parser_export = subparsers.add_parser(
            'export',
            help="Export a mod.",
            description='Export a mod in a format suitible for later import.')
        group_export = parser_export.add_mutually_exclusive_group()
        group_export.add_argument("-w",
                                  "--workshop",
                                  action="store_const",
                                  dest='save_type',
                                  metavar='save_type',
                                  const=SaveType.workshop,
                                  help="ID is of workshop file (the default).")
        group_export.add_argument("-s",
                                  "--save",
                                  action="store_const",
                                  dest='save_type',
                                  metavar='save_type',
                                  const=SaveType.save,
                                  help="ID is of savegame file.")
        group_export.add_argument("-c",
                                  "--chest",
                                  action="store_const",
                                  dest='save_type',
                                  metavar='save_type',
                                  const=SaveType.chest,
                                  help="ID is of chest file.")
        parser_export.add_argument(
            "id", help="ID of mod/name of savegame to export.")
        parser_export.add_argument("-o",
                                   "--output",
                                   help="Location/file to export to.")
        parser_export.add_argument("-f",
                                   "--force",
                                   action="store_true",
                                   help="Force creation of export file.")
        parser_export.add_argument(
            "-d",
            "--download",
            action="store_true",
            help="Attempt to download missing cache files. (EXPERIMENTAL)")
        parser_export.set_defaults(func=self.do_export)

        # import command
        parser_import = subparsers.add_parser(
            'import',
            help="Import a mod.",
            description="Import an previously exported mod.")
        parser_import.add_argument("file", help="Mod pak file to import.")
        parser_import.set_defaults(func=self.do_import)

        # download command
        parser_download = subparsers.add_parser(
            'download',
            help='Download mod files.',
            description=
            'Attempt to download any missing files for an installed mod.')
        group_download = parser_download.add_mutually_exclusive_group()
        group_download.add_argument("-w",
                                    "--workshop",
                                    action="store_const",
                                    dest='save_type',
                                    metavar='save_type',
                                    const=SaveType.workshop,
                                    help="ID is of workshop file.")
        group_download.add_argument("-s",
                                    "--save",
                                    action="store_const",
                                    dest='save_type',
                                    metavar='save_type',
                                    const=SaveType.save,
                                    help="ID is of savegame file.")
        group_download.add_argument("-c",
                                    "--chest",
                                    action="store_const",
                                    dest='save_type',
                                    metavar='save_type',
                                    const=SaveType.chest,
                                    help="ID is of chest file.")
        group_download_target = parser_download.add_mutually_exclusive_group(
            required=True)
        group_download_target.add_argument("-a",
                                           "--all",
                                           action="store_true",
                                           help="Download all.")
        group_download_target.add_argument(
            "id", nargs='?', help="ID of mod/name of savegame to download.")
        parser_download.set_defaults(func=self.do_download)

        # cache command
        parser_cache = subparsers.add_parser('cache',
                                             help='Work with the cache.')
        subparsers_cache = parser_cache.add_subparsers(
            dest='parser_cache',
            title='cache_command',
            description='Valid sub-commands.')
        subparsers_cache.required = True
        parser_cache_create = subparsers_cache.add_parser(
            'create', help='(re)create cache directory')
        parser_cache_create.set_defaults(func=self.do_cache_create)

        # config command
        parser_config = subparsers.add_parser('config',
                                              help='Configure tts manager.')
        subparsers_config = parser_config.add_subparsers(
            dest='parser_config',
            title='config_command',
            description='Valid sub-commands.')
        subparsers_config.required = True
        parser_config_list = subparsers_config.add_parser(
            'list', help='List configuration.')
        parser_config_list.set_defaults(func=self.do_config_list)
        parser_config_validate = subparsers_config.add_parser(
            'validate', help='Validate configuration.')
        parser_config_validate.set_defaults(func=self.do_config_validate)
        parser_config_reset = subparsers_config.add_parser(
            'reset', help='Reset configuration.')
        parser_config_reset.set_defaults(func=self.do_config_reset)
        parser_config_set = subparsers_config.add_parser(
            'set', help='Set configuration parameters.')
        parser_config_set.set_defaults(func=self.do_config_set)
        parser_config_set.add_argument("-m",
                                       "--mod_location",
                                       choices=['documents', 'gamedata'],
                                       help="Where mods are stored.")
        parser_config_set.add_argument("-t",
                                       "--tts_location",
                                       help="TTS Install directory")

        args = parser.parse_args()

        # set logging
        if args.loglevel:
            logmap = {
                'debug': logging.DEBUG,
                'info': logging.INFO,
                'warn': logging.WARN,
                'error': logging.ERROR
            }
            logger().setLevel(logmap[args.loglevel])
        else:
            logger().setLevel(logging.WARN)

        # load filesystem values
        if args.directory:
            self.filesystem = FileSystem(os.path.abspath(args.directory))
        else:
            self.filesystem = self.preferences.get_filesystem()

        if (args.parser == 'list'
                or args.parser == 'export') and not args.save_type:
            # set default
            args.save_type = SaveType.workshop

        if (args.parser == 'config' and args.parser_config == 'set'
                and not args.mod_location and not args.tts_location):
            parser_config_set.error("At least one of -m or -t is required.")

        rc, message = args.func(args)
        if message:
            print(message)
        sys.exit(rc)