def filter(self, layer, inEditView, customParameters): # Called on font export, get value from customParameters if "coordinates" in customParameters: coordinates = customParameters['coordinates'] # Called through UI, use stored value else: coordinates = Glyphs.defaults['com.mekkablue.Fade.coordinates'] pathOperator = NSClassFromString("GSPathOperator") for coordinateCode in coordinates.split(","): # remove all whitespace: coordinateCode = self.cleanSyntax(coordinateCode) # check if syntax valid: if coordinateCode and coordinateCode[0] in "xy" and coordinateCode[ 1] in "<>": # bounding rect coordinates: minX, minY = layer.bounds.origin maxX, maxY = minX + layer.bounds.size.width, minY + layer.bounds.size.height # pad rectangle coordinates: minX -= 1 minY -= 1 maxX += 1 maxY += 1 # cut value cut = float(coordinateCode[2:]) # cut rectangle value: if coordinateCode[0] == "x": if coordinateCode[1] == ">": minX = cut elif coordinateCode[1] == "<": maxX = cut elif coordinateCode[0] == "y": if coordinateCode[1] == ">": minY = cut elif coordinateCode[1] == "<": maxY = cut # calculate GSPath subtracting: subtractRect = self.rectPath(minX, minY, maxX, maxY) subtractPaths = NSMutableArray.alloc().initWithObject_( subtractRect) layerPaths = NSMutableArray.alloc().init( ) # should work with simply ...layer.shapes for p in layer.copyDecomposedLayer().shapes: layerPaths.addObject_(p) if pathOperator.subtractPaths_from_error_( subtractPaths, layerPaths, None): layer.shapes = layerPaths
def append_key(path, key, nstype, value): ''' Append an item to an array within a property list file. path An absolute path to a property list (.plist) file, including the extension key The specification of the key to append an element to. A list of keys separated by a colon. .. code-block:: bash salt '*' plist.append_key <path> <key> <nstype> <value> ''' log.debug('Reading original plist for modification at path: %s' % path) root = _read_plist(path) log.debug('Deriving key hierarchy from colon separated string') keys = key.split(':') if type(keys) is str: keys = list(keys) if root is None: raise salt.exceptions.SaltInvocationError( 'Tried to append to non existing file, not currently supported.') log.debug('Performing string to NSObject conversion') nsval = _value_to_nsobject(value, nstype) log.debug('Setting object value in hierarchy') if len(keys) > 1: parent = _object_for_key_list(root, keys[:-1]) else: parent = root log.debug('Updating or creating object at key: {}'.format(keys[-1])) collection = parent.objectForKey_(keys[-1]) # This is destructive if the key value is already another type if collection is None or type(collection) is not NSMutableArray: collection = NSMutableArray() parent.setObject_forKey_(collection, keys[-1]) collection.addObject_(nsval) log.debug('Writing out plist to original path') from pprint import pprint pprint(root) xml_plist = _generate_plist_string(root, NSPropertyListXMLFormat_v1_0) log.debug(xml_plist) _write_plist(root, path)
def __init__(self): self.app_dirs = [os.path.join("/Applications", app_dir) for app_dir in os.listdir('/Applications') if not app_dir.startswith(".") and not app_dir.endswith(".app")] self.app_dirs += ( '/Applications', '/System/Library/CoreServices/', '/System/Library/CoreServices/Applications/' ) self.sections = ('persistent-apps', 'persistent-others') self.tiles = ('file-tile', 'directory-tile', 'url-tile') self.id = "com.apple.dock" self.apps = NSMutableArray.alloc().initWithArray_(CoreFoundation.CFPreferencesCopyAppValue("persistent-apps", self.id)) self.others = NSMutableArray.alloc().initWithArray_(CoreFoundation.CFPreferencesCopyAppValue("persistent-others", self.id)) self.labels = self.getLabels()
def append_key(path, key, nstype, value): ''' Append an item to an array within a property list file. path An absolute path to a property list (.plist) file, including the extension key The specification of the key to append an element to. A list of keys separated by a colon. .. code-block:: bash salt '*' plist.append_key <path> <key> <nstype> <value> ''' log.debug('Reading original plist for modification at path: %s' % path) root = _read_plist(path) log.debug('Deriving key hierarchy from colon separated string') keys = key.split(':') if type(keys) is str: keys = list(keys) if root is None: raise salt.exceptions.SaltInvocationError('Tried to append to non existing file, not currently supported.') log.debug('Performing string to NSObject conversion') nsval = _value_to_nsobject(value, nstype) log.debug('Setting object value in hierarchy') if len(keys) > 1: parent = _object_for_key_list(root, keys[:-1]) else: parent = root log.debug('Updating or creating object at key: {}'.format(keys[-1])) collection = parent.objectForKey_(keys[-1]) # This is destructive if the key value is already another type if collection is None or type(collection) is not NSMutableArray: collection = NSMutableArray() parent.setObject_forKey_(collection, keys[-1]) collection.addObject_(nsval) log.debug('Writing out plist to original path') from pprint import pprint pprint(root) xml_plist = _generate_plist_string(root, NSPropertyListXMLFormat_v1_0) log.debug(xml_plist) _write_plist(root, path)
def getPasswords(): a = NSMutableArray() for pw in pwd.getpwall(): a.append({ 'name': pw.pw_name, 'password': pw.pw_passwd, 'uid': str(pw.pw_uid), 'gid': str(pw.pw_gid), 'gecos': pw.pw_gecos, 'home_dir': pw.pw_dir, 'shell': pw.pw_shell, }) return a
def getPasswords(): a = NSMutableArray() for pw in pwd.getpwall(): a.append({ "name": pw.pw_name, "password": pw.pw_passwd, "uid": str(pw.pw_uid), "gid": str(pw.pw_gid), "gecos": pw.pw_gecos, "home_dir": pw.pw_dir, "shell": pw.pw_shell, }) return a
def renderDailyEntries(self, results): getFirstContactMatchingURI = NSApp.delegate().contactsWindowController.getFirstContactMatchingURI self.dayly_entries = NSMutableArray.array() for result in results: display_name = None try: found_contact = self.contact_cache[result[2]] except KeyError: found_contact = getFirstContactMatchingURI(result[2], exact_match=True) self.contact_cache[result[2]] = found_contact if found_contact: display_name = found_contact.name remote_uri = '%s <%s>' % (display_name, result[2]) if '@' in result[2] else display_name else: try: display_name = self.display_name_cache[result[2]] except KeyError: remote_uri = result[2] else: remote_uri = '%s <%s>' % (display_name, result[2]) if '@' in result[2] else display_name entry = NSMutableDictionary.dictionaryWithObjectsAndKeys_(result[1], "local_uri", remote_uri, "remote_uri", result[2], "remote_uri_sql", result[0], 'date', result[3], 'type', display_name, "display_name") self.dayly_entries.addObject_(entry) self.dayly_entries.sortUsingDescriptors_(self.indexTable.sortDescriptors()) self.indexTable.reloadData() if self.search_uris and not self.dayly_entries: self.contactTable.deselectAll_(True)
def load_dictionaries(context_ref, language_list): # The function is a bit picky about making sure we pass a clean NSArray with NSStrings langs = NSMutableArray.array() for x in language_list: langs.addObject_(NSString.stringWithString_(x)) # The True argument is for whether the language string objects are already retained SFPWAContextLoadDictionaries(context_ref, langs, True)
def fixSpotlight (): DISABLED_ITEMS=set(["MENU_WEBSEARCH", "MENU_SPOTLIGHT_SUGGESTIONS", "OTHER", "BOOKMARKS", "MESSAGES"]) REQUIRED_ITEM_KEYS=set(["enabled", "name"]) BUNDLE_ID="com.apple.Spotlight" PREF_NAME="orderedItems" DEFAULT_VALUE=[ {'enabled' : True, 'name' : 'APPLICATIONS'}, {'enabled' : False, 'name' : 'MENU_SPOTLIGHT_SUGGESTIONS'}, {'enabled' : True, 'name' : 'MENU_CONVERSION'}, {'enabled' : True, 'name' : 'MENU_EXPRESSION'}, {'enabled' : True, 'name' : 'MENU_DEFINITION'}, {'enabled' : True, 'name' : 'SYSTEM_PREFS'}, {'enabled' : True, 'name' : 'DOCUMENTS'}, {'enabled' : True, 'name' : 'DIRECTORIES'}, {'enabled' : True, 'name' : 'PRESENTATIONS'}, {'enabled' : True, 'name' : 'SPREADSHEETS'}, {'enabled' : True, 'name' : 'PDF'}, {'enabled' : False, 'name' : 'MESSAGES'}, {'enabled' : True, 'name' : 'CONTACT'}, {'enabled' : True, 'name' : 'EVENT_TODO'}, {'enabled' : True, 'name' : 'IMAGES'}, {'enabled' : False, 'name' : 'BOOKMARKS'}, {'enabled' : True, 'name' : 'MUSIC'}, {'enabled' : True, 'name' : 'MOVIES'}, {'enabled' : True, 'name' : 'FONTS'}, {'enabled' : False, 'name' : 'MENU_OTHER'}, {'enabled' : False, 'name' : 'MENU_WEBSEARCH'} ] items = CFPreferencesCopyValue(PREF_NAME, BUNDLE_ID, kCFPreferencesCurrentUser, kCFPreferencesAnyHost) newItems = None if items is None or len(items) is 0: # Actual preference values are populated on demand; if the user # hasn't previously configured Spotlight, the preference value # will be unavailable newItems = DEFAULT_VALUE else: newItems = NSMutableArray.new() for item in items: print item['name'] missing_keys = [] for key in REQUIRED_ITEM_KEYS: if not item.has_key(key): missing_keys.append(key) if len(missing_keys) != 0: print "Preference item %s is missing expected keys (%s), skipping" % (item, missing_keys) newItems.append(item) continue if item["name"] not in DISABLED_ITEMS: newItems.append(item) continue newItem = NSMutableDictionary.dictionaryWithDictionary_(item) newItem.setObject_forKey_(0, "enabled") newItems.append(newItem) CFPreferencesSetValue(PREF_NAME, newItems, BUNDLE_ID, kCFPreferencesCurrentUser, kCFPreferencesAnyHost) CFPreferencesSynchronize(BUNDLE_ID, kCFPreferencesCurrentUser, kCFPreferencesAnyHost)
def getPasswords(): return NSMutableArray.arrayWithArray_([ dict(zip(FIELDS, line.rstrip().split(':'))) for line in os.popen('/usr/bin/nidump passwd .') if not line.startswith('#') ])
def __init__(self): self.app_dirs = [ os.path.join("/Applications", app_dir) for app_dir in os.listdir('/Applications') if not app_dir.startswith(".") and not app_dir.endswith(".app") ] self.app_dirs += ('/Applications', '/System/Library/CoreServices/', '/System/Library/CoreServices/Applications/') self.sections = ('persistent-apps', 'persistent-others') self.tiles = ('file-tile', 'directory-tile', 'url-tile') self.id = "com.apple.dock" self.apps = NSMutableArray.alloc().initWithArray_( CoreFoundation.CFPreferencesCopyAppValue("persistent-apps", self.id)) self.others = NSMutableArray.alloc().initWithArray_( CoreFoundation.CFPreferencesCopyAppValue("persistent-others", self.id)) self.labels = self.getLabels()
def refreshLibrary(self): if not self.history: return settings = SIPSimpleSettings() own_icon_path = settings.presence_state.icon selected_icon = None def md5sum(filename): md5 = hashlib.md5() with open(filename, 'rb') as f: for chunk in iter(lambda: f.read(128 * md5.block_size), b''): md5.update(chunk) return md5.hexdigest() if os.path.exists(self.storage_folder): files = os.listdir(self.storage_folder) else: files = [] array = NSMutableArray.array() knownFiles = set() for item in self.contentArrayController.arrangedObjects(): knownFiles.add(str(item.objectForKey_("path"))) seen_md5sum = {} i = 0 for f in files: if not f.startswith('user_icon') and not f.startswith( 'photo') and f != 'default_user_icon.tiff': continue p = os.path.normpath(self.storage_folder + "/" + f) if p not in knownFiles: photos_folder = unicodedata.normalize('NFC', self.storage_folder) filename = os.path.join(photos_folder, f) checksum = md5sum(filename) try: seen_md5sum[filename] except KeyError: seen_md5sum[filename] = checksum image = NSImage.alloc().initWithContentsOfFile_(p) if not image: continue item = NSDictionary.dictionaryWithObjectsAndKeys_( image, "picture", p, "path") array.addObject_(item) if own_icon_path is not None and filename == str( own_icon_path): selected_icon = i i += 1 if array.count() > 0: self.contentArrayController.addObjects_(array) if selected_icon is not None: self.libraryCollectionView.setSelectionIndexes_( NSIndexSet.indexSetWithIndex_(selected_icon))
def volume_list(folders, delegate): volumes = NSMutableArray.alloc().init() volumes.addObject_(NSString.alloc().initWithString_(os.path.expanduser('~/Ubuntu One'))) volumes.addObject_(NSString.alloc().initWithString_(os.path.expanduser('/Users/jose/Library/Application Support/ubuntuone'))) for folder in folders: if (bool(folder['subscribed'])): volumes.addObject_(NSString.alloc().initWithString_(folder['path'])) delegate.returnedVolumeList_(volumes)
def testSortValues(self): array = NSMutableArray.arrayWithArray_([4,2,1,3,0,5]) self.assertArgIsFunction(CFArraySortValues, 2, b'l@@@', False) self.assertArgHasType(CFArraySortValues, 3, b'@') def compare(l, r, context): return cmp(l, r) CFArraySortValues(array, (0, 6), compare, None) self.assertEqual(array, [0, 1, 2, 3, 4, 5])
def testSortValues(self): array = NSMutableArray.arrayWithArray_([4, 2, 1, 3, 0, 5]) self.assertArgIsFunction(CFArraySortValues, 2, b'l@@@', False) self.assertArgHasType(CFArraySortValues, 3, b'@') def compare(l, r, context): return cmp(l, r) CFArraySortValues(array, (0, 6), compare, None) self.assertEqual(array, [0, 1, 2, 3, 4, 5])
def modify_ncprefs_plist(key, value, item_index): # make an immutuble copy of the 'apps' array in ncprefs new_apps_array = NSMutableArray.alloc().initWithArray_(pl) # make a mutable copy of the target dict within the array new_dict = NSMutableDictionary.alloc().initWithDictionary_copyItems_( new_apps_array[item_index], True) # set the value new_dict[key] = value # replace the mutible dict within the mutable array new_apps_array.replaceObjectAtIndex_withObject_(item_index, new_dict) # replace the array in the ncprefs plist CFPreferencesSetAppValue("apps", new_apps_array, NCPREFS_PLIST)
def realignLayer(thisLayer): countOfHandlesOnLayer = 0 for thisPath in thisLayer.paths: for thisNode in thisPath.nodes: if thisNode.type == GSOFFCURVE: countOfHandlesOnLayer += 1 selectedNode = NSMutableArray.arrayWithObject_(thisNode) thisLayer.setSelection_( selectedNode ) Tool.moveSelectionLayer_shadowLayer_withPoint_withModifier_( thisLayer, thisLayer, moveForward, noModifier ) Tool.moveSelectionLayer_shadowLayer_withPoint_withModifier_( thisLayer, thisLayer, moveBackward, noModifier ) thisLayer.setSelection_( () ) return countOfHandlesOnLayer
def getItemView(self): array = NSMutableArray.array() context = NSMutableDictionary.dictionary() context.setObject_forKey_(self, NSNibOwner) context.setObject_forKey_(array, NSNibTopLevelObjects) path = NSBundle.mainBundle().pathForResource_ofType_("AlertPanelView", "nib") if not NSBundle.loadNibFile_externalNameTable_withZone_(path, context, self.zone()): raise RuntimeError("Internal Error. Could not find AlertPanelView.nib") for obj in array: if isinstance(obj, NSBox): return obj else: raise RuntimeError("Internal Error. Could not find NSBox in AlertPanelView.nib")
def writePlist(timestamp, writePlistPath): sippysip = [] if os.path.isfile(writePlistPath): sippysip = CFPreferencesCopyAppValue('Events', writePlistPath) if sippysip: sippysip = NSMutableArray.alloc().initWithArray_(sippysip) else: sippysip = [] sippysip.append(timestamp) CFPreferencesSetAppValue('Events', sippysip, writePlistPath) else: sippysip.append(timestamp) CFPreferencesSetAppValue('Events', sippysip, writePlistPath)
def refreshLibrary(self): if not self.history: return settings = SIPSimpleSettings() own_icon_path = settings.presence_state.icon selected_icon = None def md5sum(filename): md5 = hashlib.md5() with open(filename,'rb') as f: for chunk in iter(lambda: f.read(128*md5.block_size), b''): md5.update(chunk) return md5.hexdigest() if os.path.exists(self.storage_folder): files = os.listdir(self.storage_folder) else: files = [] array = NSMutableArray.array() knownFiles = set() for item in self.contentArrayController.arrangedObjects(): knownFiles.add(unicode(item.objectForKey_("path"))) seen_md5sum = {} i = 0 for f in files: if not f.startswith('user_icon') and not f.startswith('photo') and f != 'default_user_icon.tiff': continue p = os.path.normpath(self.storage_folder + "/" + f) if p not in knownFiles: photos_folder = unicodedata.normalize('NFC', self.storage_folder) filename = os.path.join(photos_folder, f) checksum = md5sum(filename) try: seen_md5sum[filename] except KeyError: seen_md5sum[filename] = checksum image = NSImage.alloc().initWithContentsOfFile_(p) if not image: continue item = NSDictionary.dictionaryWithObjectsAndKeys_(image, "picture", p, "path") array.addObject_(item) if own_icon_path is not None and filename == unicode(own_icon_path): selected_icon = i i += 1 if array.count() > 0: self.contentArrayController.addObjects_(array) if selected_icon is not None: self.libraryCollectionView.setSelectionIndexes_(NSIndexSet.indexSetWithIndex_(selected_icon))
def volume_list(folders, delegate): volumes = NSMutableArray.alloc().init() volumes.addObject_(NSString.alloc().initWithString_( os.path.expanduser('~/Ubuntu One'))) volumes.addObject_(NSString.alloc().initWithString_( os.path.expanduser( '/Users/jose/Library/Application Support/ubuntuone'))) for folder in folders: if (bool(folder['subscribed'])): volumes.addObject_(NSString.alloc().initWithString_( folder['path'])) delegate.returnedVolumeList_(volumes)
def realignLayer(self, thisLayer, shouldRealign=False, shouldReport=False, shouldVerbose=False): moveForward = NSPoint(1, 0) moveBackward = NSPoint(-1, 0) noModifier = NSNumber.numberWithUnsignedInteger_(0) layerCount = 0 if thisLayer: for thisPath in thisLayer.paths: oldPathCoordinates = [n.position for n in thisPath.nodes] for thisNode in thisPath.nodes: if thisNode.type == GSOFFCURVE: oldPosition = NSPoint(thisNode.position.x, thisNode.position.y) selectedNode = NSMutableArray.arrayWithObject_( thisNode) thisLayer.setSelection_(selectedNode) self.Tool.moveSelectionLayer_shadowLayer_withPoint_withModifier_( thisLayer, thisLayer, moveForward, noModifier) self.Tool.moveSelectionLayer_shadowLayer_withPoint_withModifier_( thisLayer, thisLayer, moveBackward, noModifier) for i, coordinate in enumerate(oldPathCoordinates): if thisPath.nodes[i].position != coordinate: layerCount += 1 # put handle back if not desired by user: if not shouldRealign: thisPath.nodes[i].position = coordinate thisLayer.setSelection_(()) if shouldVerbose: if layerCount: if shouldRealign: print(u" ⚠️ Realigned %i handle%s." % (layerCount, "" if layerCount == 1 else "s")) else: print(u" ❌ %i handle%s are unaligned." % (layerCount, "" if layerCount == 1 else "s")) else: print(u" ✅ All BCPs OK.") return layerCount
def process_(self, sender): """ This method gets called when the user invokes the Dialog. """ try: # Create Preview in Edit View, and save & show original in ShadowLayers: ShadowLayers = self.valueForKey_("shadowLayers") Layers = self.valueForKey_("layers") checkSelection = True for k in range(len(ShadowLayers)): ShadowLayer = ShadowLayers[k] Layer = Layers[k] Layer.setPaths_(NSMutableArray.alloc().initWithArray_copyItems_(ShadowLayer.pyobjc_instanceMethods.paths(), True)) Layer.setSelection_(None) try: # Glyphs 2.1 and earlier: if len(ShadowLayer.selection()) > 0 and checkSelection: for i in range(len(ShadowLayer.paths)): currShadowPath = ShadowLayer.paths[i] currLayerPath = Layer.paths[i] for j in range(len(currShadowPath.nodes)): currShadowNode = currShadowPath.nodes[j] if ShadowLayer.selection().containsObject_(currShadowNode): Layer.addSelection_(currLayerPath.nodes[j]) except: # Glyphs 2.2 and later: if len(ShadowLayer.selection) > 0 and checkSelection: for i in range(len(ShadowLayer.paths)): currShadowPath = ShadowLayer.paths[i] currLayerPath = Layer.paths[i] for j in range(len(currShadowPath.nodes)): currShadowNode = currShadowPath.nodes[j] if currShadowNode in ShadowLayer.selection: Layer.addSelection_(currLayerPath.nodes[j]) self.filter(Layer, Glyphs.font.currentTab != None, {}) # add your class variables here Layer.clearSelection() # Safe the values in the FontMaster. But could be saved in UserDefaults, too. # FontMaster = self.valueForKey_("fontMaster") # FontMaster.userData[ "____myValue____" ] = NSNumber.numberWithInteger_(self.____myValue____) # call the superclass to trigger the immediate redraw: objc.super(FilterWithDialog, self).process_(sender) except: self.logError(traceback.format_exc())
def process_(self, sender): """ This method gets called when the user invokes the Dialog. """ try: # Create Preview in Edit View, and save & show original in ShadowLayers: ShadowLayers = self.valueForKey_("shadowLayers") Layers = self.valueForKey_("layers") checkSelection = True for k in range(len(ShadowLayers)): ShadowLayer = ShadowLayers[k] Layer = Layers[k] Layer.setPaths_(NSMutableArray.alloc().initWithArray_copyItems_(ShadowLayer.pyobjc_instanceMethods.paths(), True)) Layer.setSelection_(None) try: # Glyphs 2.1 and earlier: if len(ShadowLayer.selection()) > 0 and checkSelection: for i in range(len(ShadowLayer.paths)): currShadowPath = ShadowLayer.paths[i] currLayerPath = Layer.paths[i] for j in range(len(currShadowPath.nodes)): currShadowNode = currShadowPath.nodes[j] if ShadowLayer.selection().containsObject_(currShadowNode): Layer.addSelection_(currLayerPath.nodes[j]) except: # Glyphs 2.2 and later: if len(ShadowLayer.selection) > 0 and checkSelection: for i in range(len(ShadowLayer.paths)): currShadowPath = ShadowLayer.paths[i] currLayerPath = Layer.paths[i] for j in range(len(currShadowPath.nodes)): currShadowNode = currShadowPath.nodes[j] if currShadowNode in ShadowLayer.selection: Layer.addSelection_(currLayerPath.nodes[j]) self.filter(Layer, Glyphs.font.currentTab is not None, {}) # add your class variables here Layer.clearSelection() # Safe the values in the FontMaster. But could be saved in UserDefaults, too. # FontMaster = self.valueForKey_("fontMaster") # FontMaster.userData["____myValue____"] = NSNumber.numberWithInteger_(self.____myValue____) # call the superclass to trigger the immediate redraw: objc.super(FilterWithDialog, self).process_(sender) except: self.logError(traceback.format_exc())
def renderDailyEntries(self, results): getFirstContactMatchingURI = NSApp.delegate().contactsWindowController.getFirstContactMatchingURI self.dayly_entries = NSMutableArray.array() for result in results: contact = getFirstContactMatchingURI(result[2], exact_match=True) if contact: remote_uri = '%s <%s>' % (contact.name, result[2]) else: remote_uri = result[2] entry = NSDictionary.dictionaryWithObjectsAndKeys_(result[1], "local_uri", remote_uri, "remote_uri", result[2], "remote_uri_sql", result[0], 'date', result[3], 'type') self.dayly_entries.addObject_(entry) self.dayly_entries.sortUsingDescriptors_(self.indexTable.sortDescriptors()) self.indexTable.reloadData() if self.search_uris and not self.dayly_entries: self.contactTable.deselectAll_(True)
def saveSettings(self): ''' Save the path setting to setting file ''' jsonData = NSMutableDictionary.dictionaryWithDictionary_(self.data) paths = NSMutableArray.array() for directory in self.data['paths']: paths.addObject_(directory.directoryToDict()) jsonData['paths'] = paths data = NSJSONSerialization.dataWithJSONObject_options_error_( jsonData, 0, None) if len(data) > 0 and not data[0].writeToFile_atomically_( self.settingPath, True): alert = NSAlert.alertWithMessageText_defaultButton_alternateButton_otherButton_informativeTextWithFormat_( "Error", "Confirm", None, None, "Save setting failed.") alert.runModal() else: # Notify the app to reload settings self.callback(*self.args)
def load(cls): ''' Load the all paths from setting file :return An array which contain all the directory model ''' settingPath = cls.settingPath() fm = NSFileManager.defaultManager() paths = NSMutableArray.array() settings = NSMutableDictionary.dictionary() if fm.fileExistsAtPath_isDirectory_(settingPath, None)[0]: settingFile = NSData.dataWithContentsOfFile_(settingPath) jsonData = NSJSONSerialization.JSONObjectWithData_options_error_( settingFile, 0, None)[0] settings['startup'] = jsonData['startup'] settings['api_key'] = jsonData['api_key'] for item in jsonData['paths']: directory = Directory.alloc().initWithDict_(item) paths.addObject_(directory) settings['paths'] = paths else: settings['startup'] = True settings['api_key'] = '' settings['paths'] = paths return settings
def resetDailyEntries(self): self.dayly_entries = NSMutableArray.array() self.indexTable.reloadData()
def clearComponents(self): """clear all components""" self._layer.setComponents_(NSMutableArray.array())
def get_uploads(uploads, delegate): returnUploads = NSMutableArray.alloc().initWithCapacity_(len(uploads)) for upload in uploads: returnUploads.addObject_(NSString.alloc().initWithString_(upload['path'])) delegate.returnedUploads_(returnUploads)
def fixSpotlight(): DISABLED_ITEMS = set(["MENU_WEBSEARCH", "MENU_SPOTLIGHT_SUGGESTIONS"]) REQUIRED_ITEM_KEYS = set(["enabled", "name"]) BUNDLE_ID = "com.apple.Spotlight" PREF_NAME = "orderedItems" DEFAULT_VALUE = [{ 'enabled': True, 'name': 'APPLICATIONS' }, { 'enabled': False, 'name': 'MENU_SPOTLIGHT_SUGGESTIONS' }, { 'enabled': True, 'name': 'MENU_CONVERSION' }, { 'enabled': True, 'name': 'MENU_EXPRESSION' }, { 'enabled': True, 'name': 'MENU_DEFINITION' }, { 'enabled': True, 'name': 'SYSTEM_PREFS' }, { 'enabled': True, 'name': 'DOCUMENTS' }, { 'enabled': True, 'name': 'DIRECTORIES' }, { 'enabled': True, 'name': 'PRESENTATIONS' }, { 'enabled': True, 'name': 'SPREADSHEETS' }, { 'enabled': True, 'name': 'PDF' }, { 'enabled': True, 'name': 'MESSAGES' }, { 'enabled': True, 'name': 'CONTACT' }, { 'enabled': True, 'name': 'EVENT_TODO' }, { 'enabled': True, 'name': 'IMAGES' }, { 'enabled': True, 'name': 'BOOKMARKS' }, { 'enabled': True, 'name': 'MUSIC' }, { 'enabled': True, 'name': 'MOVIES' }, { 'enabled': True, 'name': 'FONTS' }, { 'enabled': True, 'name': 'MENU_OTHER' }, { 'enabled': False, 'name': 'MENU_WEBSEARCH' }] items = CFPreferencesCopyValue(PREF_NAME, BUNDLE_ID, kCFPreferencesCurrentUser, kCFPreferencesAnyHost) newItems = None if items is None or len(items) is 0: # Actual preference values are populated on demand; if the user # hasn't previously configured Spotlight, the preference value # will be unavailable newItems = DEFAULT_VALUE else: newItems = NSMutableArray.new() for item in items: missing_keys = [] for key in REQUIRED_ITEM_KEYS: if not item.has_key(key): missing_keys.append(key) if len(missing_keys) != 0: print "Preference item %s is missing expected keys (%s), skipping" % ( item, missing_keys) newItems.append(item) continue if item["name"] not in DISABLED_ITEMS: newItems.append(item) continue newItem = NSMutableDictionary.dictionaryWithDictionary_(item) newItem.setObject_forKey_(0, "enabled") newItems.append(newItem) CFPreferencesSetValue(PREF_NAME, newItems, BUNDLE_ID, kCFPreferencesCurrentUser, kCFPreferencesAnyHost) CFPreferencesSynchronize(BUNDLE_ID, kCFPreferencesCurrentUser, kCFPreferencesAnyHost)
ls_prefs = os.path.join( NSHomeDirectory(), u'Library/Preferences/com.apple.LaunchServices/com.apple.LaunchServices') ls_prefs_plist = ls_prefs + u'.plist' if os.path.isfile(ls_prefs_plist): # read it in current_prefs = CFPreferencesCopyMultiple(None, ls_prefs, kCFPreferencesAnyUser, kCFPreferencesCurrentHost) else: # make a new dictionary current_prefs = NSMutableDictionary() # Get any existing key or a new blank dict if not present magnified = current_prefs.get(u'LSHighResolutionModeIsMagnified', NSMutableDictionary()) magnified_editable = NSMutableDictionary.dictionaryWithDictionary_(magnified) # Build our values options = NSMutableArray.alloc().init() options.append(bookmark) # A value of 3 = enabled, value of 2 = disabled options.append(3) magnified_editable[lowres_app_id] = options # Update the setting update_dict = NSMutableDictionary() update_dict[u'LSHighResolutionModeIsMagnified'] = magnified_editable result = CFPreferencesSetMultiple(update_dict, None, ls_prefs, kCFPreferencesAnyUser, kCFPreferencesCurrentHost)
def get_downloads(downloads, delegate): returnDownloads = NSMutableArray.alloc().initWithCapacity_(len(downloads)) for download in downloads: returnDownloads.addObject_(NSString.alloc().initWithString_( download['path'])) delegate.returnedDownloads_(returnDownloads)
def __setattr__(self, attr, value): # check to see if the attribute has been # deprecated. if so, warn the caller and # update the attribute and value. if attr in self._deprecatedAttributes: newAttr, newValue = ufoLib.convertFontInfoValueForAttributeFromVersion1ToVersion2(attr, value) note = "The %s attribute has been deprecated. Use the new %s attribute." % (attr, newAttr) warn(note, DeprecationWarning) attr = newAttr value = newValue _baseAttributes = ["_object", "changed", "selected", "getParent"] _renameAttributes = {"openTypeNameManufacturer": "manufacturer", "openTypeNameManufacturerURL": "manufacturerURL", "openTypeNameDesigner": "designer", "openTypeNameDesignerURL": "designerURL", # "openTypeNameLicense": "license", # "openTypeNameLicenseURL": "licenseURL", "fontName": "postscriptFontName", "vendorURL": "manufacturerURL", "uniqueID": "postscriptUniqueID", "otMacName": "openTypeNameCompatibleFullName" }; _masterAttributes = ["postscriptUnderlinePosition", "postscriptUnderlineThickness", "openTypeOS2StrikeoutSize", "openTypeOS2StrikeoutPosition"] # setting a known attribute if attr in _masterAttributes: if type(value) == type([]): value = NSMutableArray.arrayWithArray_(value) elif type(value) == type(1): value = NSNumber.numberWithInt_(value) elif type(value) == type(1.2): value = NSNumber.numberWithFloat_(value) if attr in _renameAttributes: attr = _renameAttributes[attr] self._object._font.fontMasterAtIndex_(self._object._masterIndex).setValue_forKey_(value, attr) return if attr not in _baseAttributes: try: if type(value) == type([]): value = NSMutableArray.arrayWithArray_(value) elif type(value) == type(1): value = NSNumber.numberWithInt_(value) elif type(value) == type(1.2): value = NSNumber.numberWithFloat_(value) if attr in _renameAttributes: attr = _renameAttributes[attr] self._object._font.setValue_forKey_(value, attr) except: raise AttributeError("Unknown attribute %s." % attr) return elif attr in self.__dict__ or attr in self._baseAttributes: super(BaseInfo, self).__setattr__(attr, value) else: raise AttributeError("Unknown attribute %s." % attr)
def clearGuides(self): """clear all horizontal guides""" self._layer.setGuideLines_(NSMutableArray.array())
def __init__(self): self.id = "com.apple.sidebarlists" self.favoriteservers = NSMutableDictionary.alloc().initWithDictionary_copyItems_(CoreFoundation.CFPreferencesCopyAppValue("favoriteservers", self.id), True) self.items = NSMutableArray.alloc().initWithArray_(self.favoriteservers["CustomListItems"] if self.favoriteservers.get("CustomListItems") else list()) self.labels = [item["Name"] for item in self.items]
from Foundation import NSMutableDictionary from Foundation import NSMutableArray if not PLIST_APPLICATION_INFO_LOCATION: print '[ERROR] Cannot find plist file %(PLIST_APPLICATION_INFO_LOCATION)' sys.exit(1) application_info = NSMutableDictionary.dictionaryWithContentsOfFile_(PLIST_APPLICATION_INFO_LOCATION) PLIST_BUNDLE_IDENTIFIER = application_info.objectForKey_('CFBundleIdentifier') if PLIST_BUNDLE_IDENTIFIER_SUFFIX != '': PLIST_BUNDLE_IDENTIFIER = PLIST_BUNDLE_IDENTIFIER + PLIST_BUNDLE_IDENTIFIER_SUFFIX PLIST_BUNDLE_VERSION = application_info.objectForKey_('CFBundleVersion') print '[DEBUG] Bundle identifier = %(PLIST_BUNDLE_IDENTIFIER)s' % vars() print '[DEBUG] Bundle version = %(PLIST_BUNDLE_VERSION)s' % vars() root = NSMutableDictionary.dictionary() items = NSMutableArray.array() root.setObject_forKey_(items,'items') main_item = NSMutableDictionary.dictionary() items.addObject_(main_item) assets = NSMutableArray.array() main_item['assets'] = assets asset_item = NSMutableDictionary.dictionary() assets.addObject_(asset_item) asset_item['kind'] = 'software-package' asset_item['url'] = IPA_URL metadata = NSMutableDictionary.dictionary() main_item['metadata'] = metadata
def get_downloads(downloads, delegate): returnDownloads = NSMutableArray.alloc().initWithCapacity_(len(downloads)) for download in downloads: returnDownloads.addObject_(NSString.alloc().initWithString_(download['path'])) delegate.returnedDownloads_(returnDownloads)
def get_uploads(uploads, delegate): returnUploads = NSMutableArray.alloc().initWithCapacity_(len(uploads)) for upload in uploads: returnUploads.addObject_(NSString.alloc().initWithString_( upload['path'])) delegate.returnedUploads_(returnUploads)
class HistoryViewer(NSWindowController): chatViewController = objc.IBOutlet() indexTable = objc.IBOutlet() contactTable = objc.IBOutlet() toolbar = objc.IBOutlet() entriesView = objc.IBOutlet() period = objc.IBOutlet() searchText = objc.IBOutlet() searchMedia = objc.IBOutlet() searchContactBox = objc.IBOutlet() paginationButton = objc.IBOutlet() foundMessagesLabel = objc.IBOutlet() queryDatabaseLabel = objc.IBOutlet() busyIndicator = objc.IBOutlet() contactMenu = objc.IBOutlet() # viewer sections contacts = [] dayly_entries = NSMutableArray.array() messages = [] # database handler history = None # search filters start = 0 search_text = None search_uris = None search_local = None search_media = None after_date = None before_date = None refresh_contacts_counter = 1 contact_cache = {} display_name_cache = {} refresh_in_progress = False daily_order_fields = {'date': 'DESC', 'local_uri': 'ASC', 'remote_uri': 'ASC'} media_type_array = {0: None, 1: ('audio', 'video'), 2: ('chat', 'sms'), 3: 'file-transfer', 4: 'audio-recording', 5: 'availability', 6: 'voicemail', 7: 'video-recording'} period_array = {0: None, 1: datetime.datetime.now()-datetime.timedelta(days=1), 2: datetime.datetime.now()-datetime.timedelta(days=7), 3: datetime.datetime.now()-datetime.timedelta(days=31), 4: datetime.datetime.now()-datetime.timedelta(days=90), 5: datetime.datetime.now()-datetime.timedelta(days=180), 6: datetime.datetime.now()-datetime.timedelta(days=365), -1: datetime.datetime.now()-datetime.timedelta(days=1), -2: datetime.datetime.now()-datetime.timedelta(days=7), -3: datetime.datetime.now()-datetime.timedelta(days=31), -4: datetime.datetime.now()-datetime.timedelta(days=90), -5: datetime.datetime.now()-datetime.timedelta(days=180), -6: datetime.datetime.now()-datetime.timedelta(days=365) } @objc.python_method def format_media_type(self, media_type): if media_type == 'sms': media_type_formated = NSLocalizedString("Short Messages", "Label") elif media_type == 'chat': media_type_formated = NSLocalizedString("Chat Sessions", "Label") elif media_type == 'audio': media_type_formated = NSLocalizedString("Audio Calls", "Label") elif media_type == 'file-transfer': media_type_formated = NSLocalizedString("File Transfers", "Label") elif media_type == 'availability': media_type_formated = NSLocalizedString("Availability", "Label") elif media_type == 'missed-call': media_type_formated = NSLocalizedString("Missed Call", "Label") elif media_type == 'voicemail': media_type_formated = NSLocalizedString("Voicemail", "Label") else: media_type_formated = media_type.title() return media_type_formated def __new__(cls, *args, **kwargs): return cls.alloc().init() def __init__(self): if self: BlinkLogger().log_debug('Starting History Viewer') NSBundle.loadNibNamed_owner_("HistoryViewer", self) self.all_contacts = BlinkHistoryViewerContact('Any Address', name='All Contacts') self.bonjour_contact = BlinkHistoryViewerContact('bonjour.local', name='Bonjour Neighbours', icon=NSImage.imageNamed_("NSBonjour")) self.notification_center = NotificationCenter() self.notification_center.add_observer(self, name='ChatViewControllerDidDisplayMessage') self.notification_center.add_observer(self, name='AudioCallLoggedToHistory') self.notification_center.add_observer(self, name='BlinkContactsHaveChanged') self.notification_center.add_observer(self, name='BlinkTableViewSelectionChaged') self.notification_center.add_observer(self, name='BlinkConferenceContactPresenceHasChanged') self.notification_center.add_observer(self, name='BlinkShouldTerminate') self.searchText.cell().setSendsSearchStringImmediately_(True) self.searchText.cell().setPlaceholderString_(NSLocalizedString("Type text and press Enter", "Placeholder text")) self.chatViewController.setContentFile_(NSBundle.mainBundle().pathForResource_ofType_("ChatView", "html")) self.chatViewController.setHandleScrolling_(False) self.entriesView.setShouldCloseWithWindow_(False) for c in ('remote_uri', 'local_uri', 'date', 'type'): col = self.indexTable.tableColumnWithIdentifier_(c) descriptor = NSSortDescriptor.alloc().initWithKey_ascending_(c, True) col.setSortDescriptorPrototype_(descriptor) self.chat_history = ChatHistory() self.session_history = SessionHistory() self.setPeriod(1) self.selectedTableView = self.contactTable @objc.python_method def setPeriod(self, days): if days <= -365: tag = -6 elif days <= -180: tag = -5 elif days <= -90: tag = -4 elif days <= -31: tag = -3 elif days <= -7: tag = -2 elif days <= -1: tag = -1 elif days <= 1: tag = 1 elif days <= 7: tag = 2 elif days <= 31: tag = 3 elif days <= 90: tag = 4 elif days <= 180: tag = 5 elif days <= 365: tag = 6 else: tag = 0 if tag == 0: self.before_date = None self.after_date = None elif tag < 0: try: date = self.period_array[tag] except KeyError: date = None self.before_date = date self.after_date = None else: try: date = self.period_array[tag] except KeyError: date = None self.after_date = date self.before_date = None self.period.selectItemWithTag_(tag) def awakeFromNib(self): NSNotificationCenter.defaultCenter().addObserver_selector_name_object_(self, "contactSelectionChanged:", NSTableViewSelectionDidChangeNotification, self.contactTable) timer = NSTimer.timerWithTimeInterval_target_selector_userInfo_repeats_(1, self, "refreshContactsTimer:", None, True) NSRunLoop.currentRunLoop().addTimer_forMode_(timer, NSModalPanelRunLoopMode) NSRunLoop.currentRunLoop().addTimer_forMode_(timer, NSDefaultRunLoopMode) self.contactTable.setDoubleAction_("doubleClick:") def close_(self, sender): self.window().close() @objc.python_method @run_in_green_thread def delete_messages(self, local_uri=None, remote_uri=None, date=None, after_date=None, before_date=None, media_type=None): block_on(self.chat_history.delete_messages(local_uri=local_uri, remote_uri=remote_uri, date=date, after_date=after_date, before_date=before_date, media_type=media_type)) block_on(self.session_history.delete_entries(local_uri=local_uri, remote_uri=remote_uri, after_date=after_date, before_date=before_date)) self.search_text = None self.search_uris = None self.search_local = None self.refreshViewer() @objc.python_method def refreshViewer(self): self.refreshContacts() self.refreshDailyEntries() self.refreshMessages() @objc.python_method @run_in_green_thread def refreshContacts(self): if self.refresh_in_progress: return self.refresh_in_progress = True self.refresh_contacts_counter = 0 if self.chat_history: self.updateBusyIndicator(True) remote_uri = self.search_uris if self.search_uris else None media_type = self.search_media if self.search_media else None search_text = self.search_text if self.search_text else None after_date = self.after_date if self.after_date else None before_date = self.before_date if self.before_date else None results = self.chat_history.get_contacts(remote_uri=remote_uri, media_type=media_type, search_text=search_text, after_date=after_date, before_date=before_date) self.renderContacts(results) self.updateBusyIndicator(False) @objc.python_method @run_in_gui_thread def renderContacts(self, results): index = 0 found_uris = [] uris_without_display_name = [] for item in self.contacts: item.destroy() getFirstContactMatchingURI = NSApp.delegate().contactsWindowController.getFirstContactMatchingURI self.contacts = [self.all_contacts, self.bonjour_contact] if self.search_uris: for uri in self.search_uris: try: found_contact = self.contact_cache[uri] except KeyError: found_contact = getFirstContactMatchingURI(uri, exact_match=True) self.contact_cache[uri] = found_contact if found_contact: contact_exist = False for contact_uri in found_contact.uris: if contact_uri.uri in found_uris: contact_exist = True break if contact_exist: continue contact = BlinkHistoryViewerContact(found_contact.uri, name=found_contact.name, icon=found_contact.icon) for contact_uri in found_contact.uris: found_uris.append(contact_uri.uri) self.contacts.append(contact) if isinstance(found_contact, BlinkPresenceContact): contact.setPresenceContact_(found_contact) else: if uri in found_uris: continue found_uris.append(uri) contact = BlinkHistoryViewerContact(str(uri), name=str(uri)) try: index = self.contacts.index(contact) except ValueError: pass if results: for row in results: try: found_contact = self.contact_cache[row[0]] except KeyError: found_contact = getFirstContactMatchingURI(row[0], exact_match=True) self.contact_cache[row[0]] = found_contact if found_contact: contact_exist = False for contact_uri in found_contact.uris: if contact_uri.uri in found_uris: contact_exist = True break if contact_exist: continue contact = BlinkHistoryViewerContact(found_contact.uri, name=found_contact.name, icon=found_contact.icon, presence_contact=found_contact if isinstance(found_contact, BlinkPresenceContact) else None) for contact_uri in found_contact.uris: found_uris.append(contact_uri.uri) else: if row[0] in found_uris: continue found_uris.append(row[0]) try: display_name = self.display_name_cache[row[0]] except KeyError: display_name = str(row[0]) uris_without_display_name.append(row[0]) contact = BlinkHistoryViewerContact(str(row[0]), name=display_name) self.contacts.append(contact) self.update_display_names(uris_without_display_name) self.contactTable.reloadData() self.contactTable.selectRowIndexes_byExtendingSelection_(NSIndexSet.indexSetWithIndex_(index), False) self.contactTable.scrollRowToVisible_(index) self.updateContactsColumnHeader() self.refresh_in_progress = False @objc.python_method @run_in_green_thread def update_display_names(self, uris_without_display_name): results = self.session_history.get_display_names(uris_without_display_name) self.updateDisplayNames(results) @objc.python_method @run_in_gui_thread def updateDisplayNames(self, results): must_reload = False for result in results: self.display_name_cache[result[0]]=result[1] for contact in self.contacts: if contact.uri == result[0] and contact.name != result[1]: contact.name = result[1] must_reload = True if must_reload: self.contactTable.reloadData() must_reload = False for entry in self.dayly_entries: if entry['remote_uri_sql'] == entry['remote_uri']: try: display_name = self.display_name_cache[entry['remote_uri_sql']] except KeyError: pass else: entry['display_name'] = display_name entry['remote_uri'] = '%s <%s>' % (display_name, entry['remote_uri_sql']) if '@' in entry['remote_uri_sql'] else display_name must_reload = True self.dayly_entries.sortUsingDescriptors_(self.indexTable.sortDescriptors()) self.indexTable.reloadData() @objc.python_method @run_in_green_thread def refreshDailyEntries(self, order_text=None): if self.chat_history: self.resetDailyEntries() self.updateBusyIndicator(True) search_text = self.search_text if self.search_text else None remote_uri = self.search_uris if self.search_uris else None local_uri = self.search_local if self.search_local else None media_type = self.search_media if self.search_media else None after_date = self.after_date if self.after_date else None before_date = self.before_date if self.before_date else None results = self.chat_history.get_daily_entries(local_uri=local_uri, remote_uri=remote_uri, media_type=media_type, search_text=search_text, order_text=order_text, after_date=after_date, before_date=before_date) self.renderDailyEntries(results) self.updateBusyIndicator(False) @objc.python_method @run_in_gui_thread def resetDailyEntries(self): self.dayly_entries = NSMutableArray.array() self.indexTable.reloadData() @objc.python_method @run_in_gui_thread def renderDailyEntries(self, results): getFirstContactMatchingURI = NSApp.delegate().contactsWindowController.getFirstContactMatchingURI self.dayly_entries = NSMutableArray.array() for result in results: display_name = None try: found_contact = self.contact_cache[result[2]] except KeyError: found_contact = getFirstContactMatchingURI(result[2], exact_match=True) self.contact_cache[result[2]] = found_contact if found_contact: display_name = found_contact.name remote_uri = '%s <%s>' % (display_name, result[2]) if '@' in result[2] else display_name else: try: display_name = self.display_name_cache[result[2]] except KeyError: remote_uri = result[2] else: remote_uri = '%s <%s>' % (display_name, result[2]) if '@' in result[2] else display_name entry = NSMutableDictionary.dictionaryWithObjectsAndKeys_(result[1], "local_uri", remote_uri, "remote_uri", result[2], "remote_uri_sql", result[0], 'date', result[3], 'type', display_name, "display_name") self.dayly_entries.addObject_(entry) self.dayly_entries.sortUsingDescriptors_(self.indexTable.sortDescriptors()) self.indexTable.reloadData() if self.search_uris and not self.dayly_entries: self.contactTable.deselectAll_(True) @objc.python_method @run_in_green_thread def refreshMessages(self, count=SQL_LIMIT, remote_uri=None, local_uri=None, media_type=None, date=None, after_date=None, before_date=None): if self.chat_history: self.updateBusyIndicator(True) search_text = self.search_text if self.search_text else None if not remote_uri: remote_uri = self.search_uris if self.search_uris else None if not local_uri: local_uri = self.search_local if self.search_local else None if not media_type: media_type = self.search_media if self.search_media else None if not after_date: after_date = self.after_date if self.after_date else None if not before_date: before_date = self.before_date if self.before_date else None results = self.chat_history.get_messages(count=count, local_uri=local_uri, remote_uri=remote_uri, media_type=media_type, date=date, search_text=search_text, after_date=after_date, before_date=before_date) self.renderMessages(results) self.updateBusyIndicator(False) @objc.python_method @run_in_gui_thread def renderMessages(self, messages=None): self.chatViewController.clear() self.chatViewController.resetRenderedMessages() self.chatViewController.last_sender = None if messages is not None: # new message list. cache for pagination and reset pagination to the last page self.messages = list(reversed(messages)) message_count = len(messages) start = message_count // MAX_MESSAGES_PER_PAGE * MAX_MESSAGES_PER_PAGE end = message_count else: message_count = len(self.messages) start = self.start end = min(start + MAX_MESSAGES_PER_PAGE, message_count) for row in self.messages[start:end]: self.renderMessage(row) self.paginationButton.setEnabled_forSegment_(start > MAX_MESSAGES_PER_PAGE, 0) self.paginationButton.setEnabled_forSegment_(start > 0, 1) self.paginationButton.setEnabled_forSegment_(start + MAX_MESSAGES_PER_PAGE + 1 < message_count, 2) self.paginationButton.setEnabled_forSegment_(start + MAX_MESSAGES_PER_PAGE * 2 < message_count, 3) if message_count == 0: text = NSLocalizedString("No entry found", "Label") elif message_count == 1: text = NSLocalizedString("Displaying 1 entry", "Label") elif message_count < MAX_MESSAGES_PER_PAGE: text = NSLocalizedString("Displaying {} entries".format(end), "Label") else: text = NSLocalizedString("Displaying {} to {} out of {} entries", "Label").format(start+1, end, message_count) self.foundMessagesLabel.setStringValue_(text) @objc.python_method @run_in_gui_thread def renderMessage(self, message): if message.direction == 'outgoing': icon = NSApp.delegate().contactsWindowController.iconPathForSelf() else: sender_uri = sipuri_components_from_string(message.cpim_from)[0] # TODO: How to render the icons from Address Book? Especially in sandbox mode we do not have access to other folders icon = NSApp.delegate().contactsWindowController.iconPathForURI(sender_uri) try: timestamp=ISOTimestamp(message.cpim_timestamp) except Exception: pass else: is_html = False if message.content_type == 'text' else True private = True if message.private == "1" else False self.chatViewController.showMessage(message.sip_callid, message.msgid, message.direction, message.cpim_from, icon, message.body, timestamp, is_private=private, recipient=message.cpim_to, state=message.status, is_html=is_html, history_entry=True, media_type=message.media_type, encryption=message.encryption if message.media_type == 'chat' else None) @objc.IBAction def paginateResults_(self, sender): if sender.selectedSegment() == 0: self.start = 0 elif sender.selectedSegment() == 1: next_start = self.start - MAX_MESSAGES_PER_PAGE self.start = next_start if next_start >= 0 else self.start elif sender.selectedSegment() == 2: next_start = self.start + MAX_MESSAGES_PER_PAGE self.start = next_start if next_start < len(self.messages)-1 else self.start elif sender.selectedSegment() == 3: self.start = len(self.messages) - len(self.messages)%MAX_MESSAGES_PER_PAGE if len(self.messages) > MAX_MESSAGES_PER_PAGE else 0 self.renderMessages() def tableView_deleteRow_(self, table, row): pass def tableView_sortDescriptorsDidChange_(self, table, odescr): self.dayly_entries.sortUsingDescriptors_(self.indexTable.sortDescriptors()) self.indexTable.reloadData() @objc.IBAction def printDocument_(self, sender): printInfo = NSPrintInfo.sharedPrintInfo() printInfo.setTopMargin_(30) printInfo.setBottomMargin_(30) printInfo.setLeftMargin_(10) printInfo.setRightMargin_(10) printInfo.setOrientation_(NSPortraitOrientation) printInfo.setHorizontallyCentered_(True) printInfo.setVerticallyCentered_(False) printInfo.setHorizontalPagination_(NSFitPagination) printInfo.setVerticalPagination_(NSFitPagination) NSPrintInfo.setSharedPrintInfo_(printInfo) # print the content of the web view self.entriesView.mainFrame().frameView().documentView().print_(self) @objc.IBAction def search_(self, sender): if self.chat_history: self.search_text = str(sender.stringValue()).lower() self.refreshContacts() row = self.indexTable.selectedRow() if row > 0: self.refreshDailyEntries() self.refreshMessages(local_uri=self.dayly_entries[row].objectForKey_("local_uri"), date=self.dayly_entries[row].objectForKey_("date"), media_type=self.dayly_entries[row].objectForKey_("type")) else: row = self.contactTable.selectedRow() if row > 0: self.refreshMessages() self.refreshDailyEntries() else: self.refreshDailyEntries() self.refreshMessages() @objc.IBAction def searchContacts_(self, sender): text = str(self.searchContactBox.stringValue().strip()) contacts = [contact for contact in self.contacts[2:] if text in contact] if text else self.contacts[2:] self.contacts = [self.all_contacts, self.bonjour_contact] + contacts self.contactTable.reloadData() self.contactTable.selectRowIndexes_byExtendingSelection_(NSIndexSet.indexSetWithIndex_(0), False) self.contactTable.scrollRowToVisible_(0) self.updateContactsColumnHeader() if not text: self.refreshContacts() @objc.python_method def updateContactsColumnHeader(self): found_contacts = len(self.contacts)-2 if found_contacts == 1: title = NSLocalizedString("1 contact found", "Label") elif found_contacts > 1: title = NSLocalizedString("%d contacts found", "Label") % found_contacts else: title = NSLocalizedString("Contacts", "Label") self.contactTable.tableColumnWithIdentifier_('contacts').headerCell().setStringValue_(title) def tableViewSelectionDidChange_(self, notification): if self.chat_history: if notification.object() == self.contactTable: row = self.contactTable.selectedRow() if row < 0: return elif row == 0: self.search_local = None self.search_uris = None self.searchContactBox.setStringValue_('') self.refreshContacts() elif row == 1: self.search_local = 'bonjour.local' self.search_uris = None elif row > 1: self.search_local = None if self.contacts[row].presence_contact is not None: self.search_uris = list(str(contact_uri.uri) for contact_uri in self.contacts[row].presence_contact.uris) self.chatViewController.expandSmileys = not self.contacts[row].presence_contact.contact.disable_smileys self.chatViewController.toggleSmileys(self.chatViewController.expandSmileys) try: item = next((item for item in self.toolbar.visibleItems() if item.itemIdentifier() == 'smileys')) except StopIteration: pass else: item.setImage_(NSImage.imageNamed_("smiley_on" if self.chatViewController.expandSmileys else "smiley_off")) else: self.search_uris = (self.contacts[row].uri,) self.refreshDailyEntries() self.refreshMessages() else: row = self.indexTable.selectedRow() if row >= 0: self.refreshMessages(remote_uri=(self.dayly_entries[row].objectForKey_("remote_uri_sql"),), local_uri=self.dayly_entries[row].objectForKey_("local_uri"), date=self.dayly_entries[row].objectForKey_("date"), media_type=self.dayly_entries[row].objectForKey_("type")) def numberOfRowsInTableView_(self, table): if table == self.indexTable: return self.dayly_entries.count() elif table == self.contactTable: return len(self.contacts) return 0 def tableView_objectValueForTableColumn_row_(self, table, column, row): if table == self.indexTable: ident = column.identifier() if ident == 'type': return self.format_media_type(self.dayly_entries[row].objectForKey_(ident)) try: return str(self.dayly_entries[row].objectForKey_(ident)) except IndexError: return None elif table == self.contactTable: try: if type(self.contacts[row]) in (str, str): return self.contacts[row] else: return self.contacts[row].name except IndexError: return None return None def tableView_willDisplayCell_forTableColumn_row_(self, table, cell, tableColumn, row): if table == self.contactTable: try: if row < len(self.contacts): if type(self.contacts[row]) in (str, str): cell.setContact_(None) else: cell.setContact_(self.contacts[row]) except: pass def showWindow_(self, sender): self.window().makeKeyAndOrderFront_(None) @objc.python_method @run_in_gui_thread def filterByURIs(self, uris=(), media_type=None): self.search_text = None self.search_local = None if media_type != self.search_media: for tag in list(self.media_type_array.keys()): if self.media_type_array[tag] == media_type: self.searchMedia.selectItemAtIndex_(tag) self.search_media = media_type self.search_uris = uris self.refreshContacts() self.refreshDailyEntries() self.refreshMessages() @objc.IBAction def filterByMediaChanged_(self, sender): tag = sender.selectedItem().tag() self.search_media = self.media_type_array[tag] self.refreshContacts() self.refreshDailyEntries() self.refreshMessages() @objc.IBAction def filterByPeriodChanged_(self, sender): tag = sender.selectedItem().tag() if tag == 0: self.before_date = None self.after_date = None elif tag < 0: try: date = self.period_array[tag] except KeyError: date = None self.before_date = date self.after_date = None else: try: date = self.period_array[tag] except KeyError: date = None self.after_date = date self.before_date = None self.refreshContacts() self.refreshDailyEntries() self.refreshMessages() def validateToolbarItem_(self, item): if item.itemIdentifier() == NSToolbarPrintItemIdentifier and not self.messages: return False return True def toolbarWillAddItem_(self, notification): item = notification.userInfo()["item"] if item.itemIdentifier() == NSToolbarPrintItemIdentifier: item.setToolTip_("Print Current Entries") item.setTarget_(self) item.setAutovalidates_(True) @objc.IBAction def userClickedToolbarItem_(self, sender): if sender.itemIdentifier() == 'smileys': self.chatViewController.expandSmileys = not self.chatViewController.expandSmileys sender.setImage_(NSImage.imageNamed_("smiley_on" if self.chatViewController.expandSmileys else "smiley_off")) self.chatViewController.toggleSmileys(self.chatViewController.expandSmileys) row = self.contactTable.selectedRow() if row and row > 1 and self.contacts[row].presence_contact is not None: self.contacts[row].presence_contact.contact.disable_smileys = not self.contacts[row].presence_contact.contact.disable_smileys self.contacts[row].presence_contact.contact.save() elif sender.itemIdentifier() == 'delete': if self.selectedTableView == self.contactTable: try: row = self.contactTable.selectedRow() self.showDeleteConfirmationDialog(row) except IndexError: pass elif self.selectedTableView == self.indexTable: try: row = self.indexTable.selectedRow() local_uri = self.dayly_entries[row].objectForKey_("local_uri") remote_uri = self.dayly_entries[row].objectForKey_("remote_uri") remote_uri_sql = self.dayly_entries[row].objectForKey_("remote_uri_sql") date = self.dayly_entries[row].objectForKey_("date") media_type = self.dayly_entries[row].objectForKey_("type") label = NSLocalizedString("Please confirm the deletion of %s history entries", "Label") % media_type + NSLocalizedString(" from %s", "SIP Address label") % remote_uri + NSLocalizedString(" on %s. ", "Date label") % date + NSLocalizedString("This operation cannot be undone. ", "Label") ret = NSRunAlertPanel(NSLocalizedString("Purge History Entries", "Window title"), label, NSLocalizedString("Confirm", "Button title"), NSLocalizedString("Cancel", "Button title"), None) if ret == NSAlertDefaultReturn: self.delete_messages(local_uri=local_uri, remote_uri=remote_uri_sql, media_type=media_type, date=date) except IndexError: pass @objc.python_method def showDeleteConfirmationDialog(self, row): media_print = self.search_media or NSLocalizedString("all", "Label") tag = self.period.selectedItem().tag() period = '%s %s' % (NSLocalizedString(" newer than", "Date label") if tag < 4 else NSLocalizedString(" older than", "Date label"), self.period_array[tag].strftime("%Y-%m-%d")) if tag else '' if row == 0: label = NSLocalizedString("Please confirm the deletion of %s history entries", "Label") % media_print + period + ". "+ NSLocalizedString("This operation cannot be undone. ", "Label") ret = NSRunAlertPanel(NSLocalizedString("Purge History Entries", "Window title"), label, NSLocalizedString("Confirm", "Button title"), NSLocalizedString("Cancel", "Button title"), None) if ret == NSAlertDefaultReturn: self.delete_messages(media_type=self.search_media, after_date=self.after_date, before_date=self.before_date) elif row == 1: remote_uri=self.contacts[row].uri label = NSLocalizedString("Please confirm the deletion of %s Bonjour history entries", "Label") % media_print + period + ". "+ NSLocalizedString("This operation cannot be undone. ", "Label") ret = NSRunAlertPanel(NSLocalizedString("Purge History Entries", "Window title"), label, NSLocalizedString("Confirm", "Button title"), NSLocalizedString("Cancel", "Button title"), None) if ret == NSAlertDefaultReturn: self.delete_messages(local_uri='bonjour.local', media_type=self.search_media, after_date=self.after_date, before_date=self.before_date) else: contact = self.contacts[row] if contact.presence_contact is not None: remote_uri = list(str(contact.uri) for contact in contact.presence_contact.uris) else: remote_uri = contact.uri label = NSLocalizedString("Please confirm the deletion of %s history entries", "Label") % media_print + NSLocalizedString(" from ", "Label") + contact.name + period + ". "+ NSLocalizedString("This operation cannot be undone. ", "Label") ret = NSRunAlertPanel(NSLocalizedString("Purge History Entries", "Window title"), label, NSLocalizedString("Confirm", "Button title"), NSLocalizedString("Cancel", "Button title"), None) if ret == NSAlertDefaultReturn: self.delete_messages(remote_uri=remote_uri, media_type=self.search_media, after_date=self.after_date, before_date=self.before_date) @objc.python_method @run_in_gui_thread def updateBusyIndicator(self, busy=False): if busy: self.queryDatabaseLabel.setHidden_(False) self.busyIndicator.setHidden_(False) self.busyIndicator.setIndeterminate_(True) self.busyIndicator.setStyle_(NSProgressIndicatorSpinningStyle) self.busyIndicator.startAnimation_(None) else: self.busyIndicator.stopAnimation_(None) self.busyIndicator.setHidden_(True) self.queryDatabaseLabel.setHidden_(True) @objc.python_method @run_in_gui_thread def handle_notification(self, notification): handler = getattr(self, '_NH_%s' % notification.name, Null) handler(notification) @objc.python_method def _NH_BlinkShouldTerminate(self, notification): if self.window(): self.window().orderOut_(self) @objc.python_method def _NH_ChatViewControllerDidDisplayMessage(self, notification): if notification.data.local_party != 'bonjour.local': exists = any(contact for contact in self.contacts if notification.data.remote_party == contact.uri) if not exists: self.refreshContacts() @objc.python_method def _NH_AudioCallLoggedToHistory(self, notification): if notification.data.local_party != 'bonjour.local': exists = any(contact for contact in self.contacts if notification.data.remote_party == contact.uri) if not exists: self.refreshContacts() @objc.python_method def _NH_BlinkContactsHaveChanged(self, notification): self.refresh_contacts_counter += 1 def refreshContactsTimer_(self, timer): if self.refresh_contacts_counter: self.refreshContacts() self.toolbar.validateVisibleItems() @objc.python_method def _NH_BlinkTableViewSelectionChaged(self, notification): self.selectedTableView = notification.sender self.toolbar.validateVisibleItems() @objc.python_method def _NH_BlinkConferenceContactPresenceHasChanged(self, notification): try: contact = next((contact for contact in self.contacts[2:] if contact == notification.sender)) except StopIteration: return else: try: idx = self.contacts.index(contact) self.contactTable.reloadDataForRowIndexes_columnIndexes_(NSIndexSet.indexSetWithIndex_(idx), NSIndexSet.indexSetWithIndex_(0)) except ValueError: pass def contactSelectionChanged_(self, notification): pass def menuWillOpen_(self, menu): if menu == self.contactMenu: self.contactMenu.itemWithTag_(2).setEnabled_(False) self.contactMenu.itemWithTag_(3).setEnabled_(False) self.contactMenu.itemWithTag_(4).setEnabled_(False) try: row = self.contactTable.selectedRow() except: return if row < 2: return try: contact = self.contacts[row] except IndexError: return contact_exists = bool(contact.presence_contact is not None) if '@' in contact.uri: self.contactMenu.itemWithTag_(2).setEnabled_(not is_anonymous(contact.uri)) self.contactMenu.itemWithTag_(3).setEnabled_(not contact_exists and not is_anonymous(contact.uri)) self.contactMenu.itemWithTag_(4).setEnabled_(contact_exists) else: bonjour_contact = NSApp.delegate().contactsWindowController.model.getBonjourContactMatchingDeviceId(contact.uri) self.contactMenu.itemWithTag_(2).setEnabled_(bool(bonjour_contact)) self.contactMenu.itemWithTag_(3).setEnabled_(False) self.contactMenu.itemWithTag_(4).setEnabled_(False) @objc.IBAction def doubleClick_(self, sender): row = self.contactTable.selectedRow() if row < 2: return try: contact = self.contacts[row] except IndexError: return if '@' in contact.uri: NSApp.delegate().contactsWindowController.startSessionWithTarget(contact.uri) else: bonjour_contact = NSApp.delegate().contactsWindowController.model.getBonjourContactMatchingDeviceId(contact.uri) if not bonjour_contact: BlinkLogger().log_info("Bonjour neighbour %s was not found on this network" % contact.name) message = NSLocalizedString("Bonjour neighbour %s was not found on this network. ", "label") % contact.name NSRunAlertPanel(NSLocalizedString("Error", "Window title"), message, NSLocalizedString("OK", "Button title"), None, None) return NSApp.delegate().contactsWindowController.startSessionWithTarget(bonjour_contact.uri) @objc.IBAction def userClickedContactMenu_(self, sender): row = self.contactTable.selectedRow() try: contact = self.contacts[row] except IndexError: return tag = sender.tag() if tag == 1: self.showDeleteConfirmationDialog(row) elif tag == 2: NSApp.delegate().contactsWindowController.searchBox.setStringValue_(contact.uri) NSApp.delegate().contactsWindowController.searchContacts() NSApp.delegate().contactsWindowController.window().makeFirstResponder_(NSApp.delegate().contactsWindowController.searchBox) NSApp.delegate().contactsWindowController.window().deminiaturize_(sender) NSApp.delegate().contactsWindowController.window().makeKeyWindow() elif tag == 3: NSApp.delegate().contactsWindowController.addContact(uris=[(contact.uri, 'sip')], name=contact.name) elif tag == 4 and contact.presence_contact is not None: NSApp.delegate().contactsWindowController.model.editContact(contact.presence_contact) @objc.IBAction def userClickedActionsButton_(self, sender): point = sender.window().convertScreenToBase_(NSEvent.mouseLocation()) event = NSEvent.mouseEventWithType_location_modifierFlags_timestamp_windowNumber_context_eventNumber_clickCount_pressure_( NSLeftMouseUp, point, 0, NSDate.timeIntervalSinceReferenceDate(), sender.window().windowNumber(), sender.window().graphicsContext(), 0, 1, 0) NSMenu.popUpContextMenu_withEvent_forView_(self.contactMenu, event, sender)
class AddContactController(NSObject): window = objc.IBOutlet() addButton = objc.IBOutlet() addressText = objc.IBOutlet() organizationText = objc.IBOutlet() nameText = objc.IBOutlet() groupPopUp = objc.IBOutlet() publicKey = objc.IBOutlet() defaultButton = objc.IBOutlet() subscribePopUp = objc.IBOutlet() photoImage = objc.IBOutlet() preferredMediaPopUpButton = objc.IBOutlet() addressTable = objc.IBOutlet() addressTypesPopUpButton = objc.IBOutlet() addressTableDatasource = NSMutableArray.array() defaultPhotoImage = None media_tags = {'audio': 1, 'chat': 2, 'audio+chat': 3, 'video': 4} autoanswerCheckbox = objc.IBOutlet() def __new__(cls, *args, **kwargs): from ContactListModel import DefaultUserAvatar cls.defaultPhotoImage = DefaultUserAvatar().icon return cls.alloc().init() def __init__(self, uris=[], name=None, group=None): NSBundle.loadNibNamed_owner_("Contact", self) self.window.setTitle_(NSLocalizedString("Add Contact", "Window title")) self.dealloc_timer = None self.default_uri = None self.preferred_media = 'audio' self.uris = [] for (uri, type) in uris: self.uris.append( ContactURI(uri=uri.strip(), type=format_uri_type(type))) self.update_default_uri() self.subscriptions = { 'presence': { 'subscribe': True, 'policy': 'allow' }, 'dialog': { 'subscribe': False, 'policy': 'block' } } self.all_groups = [ g for g in self.groupsList if g.group is not None and not isinstance(g.group, VirtualGroup) and g.add_contact_allowed ] self.belonging_groups = [] if group is not None: self.belonging_groups.append(group) self.nameText.setStringValue_(name or "") self.photoImage.setImage_(self.defaultPhotoImage) self.defaultButton.setEnabled_(False) self.updateSubscriptionMenus() self.loadGroupNames() self.addButton.setEnabled_(True if self.uris else False) @property def model(self): return NSApp.delegate().contactsWindowController.model @property def groupsList(self): return self.model.groupsList def startDeallocTimer(self): # workaround to keep the object alive as cocoa still sends delegate tableview messages after close self.dealloc_timer = NSTimer.timerWithTimeInterval_target_selector_userInfo_repeats_( 2.0, self, "deallocTimer:", None, False) NSRunLoop.currentRunLoop().addTimer_forMode_(self.dealloc_timer, NSRunLoopCommonModes) NSRunLoop.currentRunLoop().addTimer_forMode_( self.dealloc_timer, NSEventTrackingRunLoopMode) def deallocTimer_(self, timer): if self.dealloc_timer: self.dealloc_timer.invalidate() self.dealloc_timer = None self.all_groups = None self.belonging_groups = None self.uris = None self.subscriptions = None self.defaultPhotoImage = None @objc.python_method @run_in_gui_thread def handle_notification(self, notification): handler = getattr(self, '_NH_%s' % notification.name, Null) handler(notification) def awakeFromNib(self): NotificationCenter().add_observer(self, name="BlinkGroupsHaveChanged") self.addressTable.tableColumnWithIdentifier_( "0").dataCell().setPlaceholderString_( NSLocalizedString("Click to add a new address", "Text placeholder")) self.addressTable.setDraggingSourceOperationMask_forLocal_( NSDragOperationGeneric, True) self.addressTable.registerForDraggedTypes_( NSArray.arrayWithObject_("dragged-row")) @objc.python_method def _NH_BlinkGroupsHaveChanged(self, notification): self.all_groups = list( g for g in self.groupsList if g.group is not None and not isinstance(g.group, VirtualGroup) and g.add_contact_allowed) self.loadGroupNames() @objc.python_method def runModal(self): rc = NSApp.runModalForWindow_(self.window) self.window.orderOut_(self) if rc == NSOKButton: NotificationCenter().remove_observer(self, name="BlinkGroupsHaveChanged") # TODO: how to handle xmmp: uris? #for uri in self.uris: # if uri.type is not None and uri.type.lower() == 'xmpp' and ';xmpp' not in uri.uri: # uri.uri = uri.uri + ';xmpp' i = 0 for uri in self.uris: uri.position = i i += 1 contact = { 'default_uri': self.default_uri, 'uris': self.uris, 'auto_answer': True if self.autoanswerCheckbox.state() == NSOnState else False, 'name': str(self.nameText.stringValue()), 'organization': str(self.organizationText.stringValue()), 'groups': self.belonging_groups, 'icon': None if self.photoImage.image() == self.defaultPhotoImage else self.photoImage.image(), 'preferred_media': self.preferred_media, 'subscriptions': self.subscriptions } return contact return False @objc.python_method def checkURI(self, uri): if checkValidPhoneNumber(uri): return True if uri.startswith(('https:', 'http:')): url = urllib.parse.urlparse(uri) if url.scheme not in ('http', 'https'): return False return True if not uri.startswith(('sip:', 'sips:')): uri = "sip:%s" % uri try: SIPURI.parse(str(uri)) except SIPCoreError: return False return True @objc.python_method def update_default_uri(self): if self.default_uri: self.addressText.setStringValue_(self.default_uri.uri) else: if self.uris: self.addressText.setStringValue_(self.uris[0].uri) else: self.addressText.setStringValue_('') self.addButton.setEnabled_(True if self.uris else False) def windowShouldClose_(self, sender): self.startDeallocTimer() NSApp.stopModalWithCode_(NSCancelButton) return True @objc.python_method def loadGroupNames(self): if self.belonging_groups is None: return self.groupPopUp.removeAllItems() nr_groups = len(self.belonging_groups) if nr_groups == 0: title = NSLocalizedString("No Selected Groups", "Menu item") elif nr_groups == 1: title = NSLocalizedString("One Selected Group", "Menu item") else: title = NSLocalizedString("%d Selected Groups", "Menu item") % nr_groups self.groupPopUp.addItemWithTitle_(title) menu_item = self.groupPopUp.lastItem() menu_item.setState_(NSOffState) self.groupPopUp.menu().addItem_(NSMenuItem.separatorItem()) for grp in self.all_groups: self.groupPopUp.addItemWithTitle_(grp.name) item = self.groupPopUp.lastItem() item.setRepresentedObject_(grp) menu_item = self.groupPopUp.lastItem() if grp in self.belonging_groups: menu_item.setState_(NSOnState) else: menu_item.setState_(NSOffState) self.groupPopUp.menu().addItem_(NSMenuItem.separatorItem()) self.groupPopUp.addItemWithTitle_( NSLocalizedString("Select All", "Menu item")) self.groupPopUp.addItemWithTitle_( NSLocalizedString("Deselect All", "Menu item")) self.groupPopUp.addItemWithTitle_( NSLocalizedString("Add Group...", "Menu item")) @objc.IBAction def subscribePopUpClicked_(self, sender): index = self.subscribePopUp.indexOfSelectedItem() if index == 3: self.subscriptions['presence'][ 'subscribe'] = not self.subscriptions['presence']['subscribe'] elif index == 4: self.subscriptions['presence'][ 'policy'] = 'allow' if self.subscriptions['presence'][ 'policy'] == 'block' else 'block' elif index == 7: self.subscriptions['dialog'][ 'subscribe'] = not self.subscriptions['dialog']['subscribe'] elif index == 8: self.subscriptions['dialog'][ 'policy'] = 'allow' if self.subscriptions['dialog'][ 'policy'] == 'block' else 'block' self.updateSubscriptionMenus() @objc.IBAction def preferredMediaPopUpClicked_(self, sender): item = self.preferredMediaPopUpButton.selectedItem() try: self.preferred_media = next( (media for media in list(self.media_tags.keys()) if self.media_tags[media] == item.tag())) except StopIteration: self.preferred_media == 'audio' self.updatePreferredMediaMenus() @objc.python_method def updatePreferredMediaMenus(self): items = self.preferredMediaPopUpButton.itemArray() for menu_item in items: if menu_item.tag() == 1: menu_item.setState_(NSOnState if self.preferred_media == 'audio' else NSOffState) elif menu_item.tag() == 2: menu_item.setState_(NSOnState if self.preferred_media == 'chat' else NSOffState) elif menu_item.tag() == 3: menu_item.setState_(NSOnState if self.preferred_media in ( 'audio+chat', 'chat+audio') else NSOffState) elif menu_item.tag() == 4: menu_item.setState_(NSOnState if self.preferred_media == 'video' else NSOffState) try: tag = self.media_tags[self.preferred_media] except KeyError: tag = 1 self.preferredMediaPopUpButton.selectItemWithTag_(tag) @objc.python_method def updateSubscriptionMenus(self): self.subscribePopUp.selectItemAtIndex_(0) menu_item = self.subscribePopUp.itemAtIndex_(0) menu_item.setState_(NSOffState) menu_item = self.subscribePopUp.itemAtIndex_(3) menu_item.setState_(NSOnState if self.subscriptions['presence'] ['subscribe'] else NSOffState) menu_item = self.subscribePopUp.itemAtIndex_(4) menu_item.setState_(NSOnState if self.subscriptions['presence'] ['policy'] == 'allow' else NSOffState) menu_item = self.subscribePopUp.itemAtIndex_(7) menu_item.setState_(NSOnState if self.subscriptions['dialog'] ['subscribe'] else NSOffState) menu_item = self.subscribePopUp.itemAtIndex_(8) menu_item.setState_(NSOnState if self.subscriptions['dialog']['policy'] == 'allow' else NSOffState) @objc.IBAction def groupPopUpButtonClicked_(self, sender): item = sender.selectedItem() index = self.groupPopUp.indexOfSelectedItem() if index < 2: return grp = item.representedObject() if grp: if grp in self.belonging_groups: self.belonging_groups.remove(grp) else: self.belonging_groups.append(grp) else: menu_item = self.groupPopUp.itemAtIndex_(index) if menu_item.title() == NSLocalizedString("Select All", "Menu item"): self.belonging_groups = self.all_groups elif menu_item.title() == NSLocalizedString( "Deselect All", "Menu item"): self.belonging_groups = [] elif menu_item.title() == NSLocalizedString( "Add Group...", "Menu item"): self.model.addGroup() self.loadGroupNames() @objc.IBAction def buttonClicked_(self, sender): if sender.tag() == 20: # ch icon panel = NSOpenPanel.openPanel() panel.setTitle_( NSLocalizedString("Select Contact Icon", "Window title")) if panel.runModalForTypes_( NSArray.arrayWithObjects_( "tiff", "png", "jpeg", "jpg")) == NSFileHandlingPanelOKButton: path = panel.filename() image = NSImage.alloc().initWithContentsOfFile_(path) self.photoImage.setImage_(image) elif sender.tag() == 21: # clear icon self.photoImage.setImage_(self.defaultPhotoImage) elif sender.tag() == 10: self.startDeallocTimer() NSApp.stopModalWithCode_(NSOKButton) else: self.startDeallocTimer() NSApp.stopModalWithCode_(NSCancelButton) @objc.IBAction def defaultClicked_(self, sender): if sender.selectedSegment() == 0: # Set default URI contact_uri = self.selectedContactURI() self.default_uri = contact_uri self.update_default_uri() elif sender.selectedSegment() == 1: # Delete URI row = self.addressTable.selectedRow() del self.uris[row] self.update_default_uri() self.addressTable.reloadData() row = self.addressTable.selectedRow() self.defaultButton.setEnabled_(row < len(self.uris)) @objc.python_method def selectedContactURI(self): row = self.addressTable.selectedRow() try: return self.uris[row] except IndexError: return None def numberOfRowsInTableView_(self, table): return len(self.uris) + 1 def tableViewSelectionDidChange_(self, notification): row = self.addressTable.selectedRow() self.defaultButton.setEnabled_(row < len(self.uris)) def tableView_sortDescriptorsDidChange_(self, table, odescr): return def tableView_objectValueForTableColumn_row_(self, table, column, row): if row >= len(self.uris): return "" cell = column.dataCell() column = int(column.identifier()) contact_uri = self.uris[row] if column == 0: return contact_uri.uri elif column == 1: return cell.indexOfItemWithTitle_(contact_uri.type or 'SIP') def tableView_setObjectValue_forTableColumn_row_(self, table, object, column, row): cell = column.dataCell() column = int(column.identifier()) if not object: if column == 0: # delete row if row < len(self.uris): try: del self.uris[row] except IndexError: pass self.update_default_uri() table.reloadData() return else: return if row >= len(self.uris): if column == 0: has_empty_cell = any(value for value in self.uris if not value) if not has_empty_cell: self.uris.append(ContactURI(uri="", type="SIP")) try: contact_uri = self.uris[row] except IndexError: pass else: if column == 0: uri = str(object).strip().lower().replace(" ", "") if not self.checkURI(uri): NSRunAlertPanel( NSLocalizedString("Invalid Address", "Window title"), NSLocalizedString( "Please enter an address containing alpha numeric characters", "Label"), NSLocalizedString("OK", "Button title"), None, None) return contact_uri.uri = uri if uri.startswith(('https:', 'http:')): contact_uri.type = 'URL' elif '@' in uri: domain = uri.partition("@")[-1] domain = domain if ':' not in domain else domain.partition( ":")[0] if domain in ( 'jit.si', 'gmail.com', 'comm.unicate.me' ) or 'jabb' in domain or 'xmpp' in domain or domain.endswith( '.im') or domain.startswith('im.'): contact_uri.type = 'XMPP' if len(self.uris) == 1: self.preferred_media = 'chat' self.updateSubscriptionMenus() elif column == 1: contact_uri.type = str(cell.itemAtIndex_(object).title()) self.update_default_uri() table.reloadData() row = self.addressTable.selectedRow() self.defaultButton.setEnabled_(row < len(self.uris)) def tableView_validateDrop_proposedRow_proposedDropOperation_( self, table, info, row, oper): if oper == NSTableViewDropOn: table.setDropRow_dropOperation_(row, NSTableViewDropAbove) return NSDragOperationGeneric def tableView_acceptDrop_row_dropOperation_(self, table, info, row, oper): if info.draggingSource() != self.addressTable: return False pboard = info.draggingPasteboard() draggedRow = int(pboard.stringForType_("dragged-row")) if draggedRow >= len(self.uris): return False if draggedRow != row + 1 or oper != 0: item = self.uris[draggedRow] del self.uris[draggedRow] if draggedRow < row: row -= 1 self.uris.insert(row, item) self.update_default_uri() table.reloadData() return True return False def tableView_writeRows_toPasteboard_(self, table, rows, pboard): index = rows[0] pboard.declareTypes_owner_(NSArray.arrayWithObject_("dragged-row"), self) pboard.setString_forType_(NSString.stringWithString_(str(index)), "dragged-row") return True
def realignLayer(self, thisLayer, shouldRealign=False, shouldReport=False, shouldVerbose=False): moveForward = NSPoint(1, 0) moveBackward = NSPoint(-1, 0) noModifier = NSNumber.numberWithUnsignedInteger_(0) layerCount = 0 if thisLayer: for thisPath in thisLayer.paths: oldPathCoordinates = [n.position for n in thisPath.nodes] for i, thisNode in enumerate(thisPath.nodes): if thisNode.type == GSOFFCURVE: # oldPosition = NSPoint(thisNode.position.x, thisNode.position.y) oncurve = None if thisNode.prevNode.type != GSOFFCURVE: oncurve = thisNode.prevNode opposingPoint = oncurve.prevNode elif thisNode.nextNode.type != GSOFFCURVE: oncurve = thisNode.nextNode opposingPoint = oncurve.nextNode handleStraight = (oncurve.x - thisNode.x) * ( oncurve.y - thisNode.y) == 0.0 if oncurve and oncurve.smooth and not handleStraight: # thisNode = angled handle, straighten it thisPath.setSmooth_withCenterPoint_oppositePoint_( thisNode, oncurve.position, opposingPoint.position, ) elif oncurve and opposingPoint and oncurve.smooth and handleStraight and opposingPoint.type == GSOFFCURVE: # thisNode = straight handle: align opposite handle thisPath.setSmooth_withCenterPoint_oppositePoint_( opposingPoint, oncurve.position, thisNode.position, ) else: selectedNode = NSMutableArray.arrayWithObject_( thisNode) thisLayer.setSelection_(selectedNode) self.Tool.moveSelectionLayer_shadowLayer_withPoint_withModifier_( thisLayer, thisLayer, moveForward, noModifier) self.Tool.moveSelectionLayer_shadowLayer_withPoint_withModifier_( thisLayer, thisLayer, moveBackward, noModifier) # TODO: # recode with GSPath.setSmooth_withCenterNode_oppositeNode_() for i, coordinate in enumerate(oldPathCoordinates): if thisPath.nodes[i].position != coordinate: layerCount += 1 # put handle back if not desired by user: if not shouldRealign: thisPath.nodes[i].position = coordinate thisLayer.setSelection_(()) if shouldReport and shouldVerbose: if layerCount: if shouldRealign: print(u" ⚠️ Realigned %i handle%s." % (layerCount, "" if layerCount == 1 else "s")) else: print(u" ❌ %i handle%s are unaligned." % (layerCount, "" if layerCount == 1 else "s")) else: print(u" ✅ All BCPs OK.") return layerCount
# # newParam = GSCustomParameter.alloc().init() # # font.addCustomParameter_(newParam) # # font.addCustomParameter_("Axes") # # add them to the font # font.setCustomParameter_forKey_(fontAxes, "Axes") # print(font.customParameterForKey_("Axes")) from Foundation import NSMutableDictionary, NSMutableArray fontAxes = NSMutableArray.arrayWithArray_([ NSMutableDictionary.dictionaryWithDictionary_({ "Name": "Weight", "Tag": "wght" }), NSMutableDictionary.dictionaryWithDictionary_({ "Name": "Negative", "Tag": "NEGA" }) ]) font.setCustomParameter_forKey_(fontAxes, "Axes") # ============================================================================ # remove old masters ========================================================= # just do it twice for now to delete original two – would need more flexibility to be abstracted to other fonts font.removeFontMasterAtIndex_(0) font.removeFontMasterAtIndex_(0) # ============================================================================ # set axis values of new masters =============================================
def __init__(self, eventTypes, pathMode, pathString, whitelist, blacklist, ignoreSysFiles, ignoreDirEvents, proxy): """ Set-up Monitor thread. After initialising the superclass and some instance variables try to create an FSEventStream. Throw an exeption if this fails. :Parameters: eventTypes : A list of the event types to be monitored. pathMode : The mode of directory monitoring: flat, recursive or following. pathString : string A string representing a path to be monitored. whitelist : list<string> A list of files and extensions of interest. blacklist : list<string> A list of subdirectories to be excluded. ignoreSysFiles : If true platform dependent sys files should be ignored. monitorId : Unique id for the monitor included in callbacks. proxy : A proxy to be informed of events """ AbstractPlatformMonitor.__init__(self, eventTypes, pathMode, pathString, whitelist, blacklist, ignoreSysFiles, ignoreDirEvents, proxy) self.log = logging.getLogger("fsserver."+__name__) #: an FSEvents.FSEventStream StreamRef object reference. self.streamRef = None #: FSEvents.CFRunLoop object reference. self.runLoopRef = None self.clientInfo = str(uuid.uuid1()) # # Without using the mutable array, ie using the Python list directly, # the code works but throws up a couple of horrible warnings: # "Oject of class OC_PythonArray autoreleased with no pool in place # - just leaking" # With the array there are still warnings about the strings whether # Python native strings are used or NSStrings. # # All of these warnings are eliminated by using a pool for the lifetime # of the NSMutableArray. # pool = NSAutoreleasePool.alloc().init() pathsToMonitor = NSMutableArray.alloc().init() ms = NSString.stringWithString_(self.pathsToMonitor) pathsToMonitor.insertObject_atIndex_(ms, 0) self.directory = fsDirectory.Directory(pathString=self.pathsToMonitor, whitelist=self.whitelist, pathMode=self.pathMode) self.streamRef = FSEvents.FSEventStreamCreate(FSEvents.kCFAllocatorDefault, self.callback, self.clientInfo, pathsToMonitor, FSEvents.kFSEventStreamEventIdSinceNow, 1, FSEvents.kFSEventStreamCreateFlagWatchRoot) # # Release the pool now that the NSMutableArray has been used. # del pool if self.streamRef == None: raise Exception('Failed to create FSEvent Stream') self.log.info('Monitor set-up on %s', str(self.pathsToMonitor)) self.log.info('Monitoring %s events', str(self.eTypes))
if 'com.oracle.java.JavaAppletPlugin' in my_policy: # make a mutable copy of the dict current_dict = my_policy['com.oracle.java.JavaAppletPlugin'] my_policy['com.oracle.java.JavaAppletPlugin'] = NSMutableDictionary.alloc( ).initWithDictionary_copyItems_(current_dict, True) else: # create an empty dict my_policy['com.oracle.java.JavaAppletPlugin'] = {} if 'PlugInHostnamePolicies' in my_policy['com.oracle.java.JavaAppletPlugin']: # make a mutable copy of the array current_array = my_policy['com.oracle.java.JavaAppletPlugin'][ 'PlugInHostnamePolicies'] my_policy['com.oracle.java.JavaAppletPlugin'][ 'PlugInHostnamePolicies'] = NSMutableArray.alloc().initWithArray_( current_array) else: # create an empty array my_policy['com.oracle.java.JavaAppletPlugin'][ 'PlugInHostnamePolicies'] = [] found_foocorp_vpn = False # iterate through dicts in com.oracle.java.JavaAppletPlugin:PlugInHostnamePolicies for dict_item in my_policy['com.oracle.java.JavaAppletPlugin'][ 'PlugInHostnamePolicies']: if dict_item.get('PlugInHostname') == 'vpn.foocorp.com': found_foocorp_vpn = True if not found_foocorp_vpn: foocorp_vpn = { 'PlugInPageURL': 'https://vpn.foocorp.com/index.cgi',