mirror of
https://github.com/arsenetar/dupeguru-cocoa.git
synced 2026-01-22 14:41:40 +00:00
Convert cocoalib submodule to be in place.
This commit is contained in:
34
cocoalib/cocoa/CocoaProxy.h
Normal file
34
cocoalib/cocoa/CocoaProxy.h
Normal file
@@ -0,0 +1,34 @@
|
||||
#import <Cocoa/Cocoa.h>
|
||||
|
||||
@interface CocoaProxy : NSObject
|
||||
{
|
||||
NSAutoreleasePool *currentPool;
|
||||
}
|
||||
- (void)openPath:(NSString *)path;
|
||||
- (void)openURL:(NSString *)url;
|
||||
- (void)revealPath:(NSString *)path;
|
||||
- (NSString *)getUTI:(NSString *)path;
|
||||
- (BOOL)type:(NSString *)type conformsToType:(NSString *)refType;
|
||||
- (NSString *)getAppdataPath;
|
||||
- (NSString *)getCachePath;
|
||||
- (NSString *)getResourcePath;
|
||||
- (NSString *)systemLang;
|
||||
- (NSString *)systemShortDateFormat;
|
||||
- (NSString *)systemNumberDecimalSeparator;
|
||||
- (NSString *)systemNumberGroupingSeparator;
|
||||
- (NSString *)systemCurrency;
|
||||
- (NSString *)bundleIdentifier;
|
||||
- (NSString *)appVersion;
|
||||
- (NSString *)osxVersion;
|
||||
- (NSString *)bundleInfo:(NSString *)key;
|
||||
- (void)postNotification:(NSString *)name userInfo:(NSDictionary *)userInfo;
|
||||
- (id)prefValue:(NSString *)prefname;
|
||||
- (void)setPrefValue:(NSString *)prefname value:(id)value;
|
||||
- (id)prefValue:(NSString *)prefname inDomain:(NSString *)domain;
|
||||
- (NSString *)url2path:(NSString *)url;
|
||||
- (void)createPool;
|
||||
- (void)destroyPool;
|
||||
- (void)reportCrash:(NSString *)crashReport withGithubUrl:(NSString *)githubUrl;
|
||||
- (void)log:(NSString *)s;
|
||||
- (NSDictionary *)readExifData:(NSString *)imagePath;
|
||||
@end
|
||||
171
cocoalib/cocoa/CocoaProxy.m
Normal file
171
cocoalib/cocoa/CocoaProxy.m
Normal file
@@ -0,0 +1,171 @@
|
||||
#import "CocoaProxy.h"
|
||||
#import "HSErrorReportWindow.h"
|
||||
|
||||
@implementation CocoaProxy
|
||||
- (void)openPath:(NSString *)path
|
||||
{
|
||||
[[NSWorkspace sharedWorkspace] openURL:[NSURL fileURLWithPath:path isDirectory:NO]];
|
||||
}
|
||||
|
||||
- (void)openURL:(NSString *)url
|
||||
{
|
||||
[[NSWorkspace sharedWorkspace] openURL:[NSURL URLWithString:url]];
|
||||
}
|
||||
|
||||
- (void)revealPath:(NSString *)path
|
||||
{
|
||||
[[NSWorkspace sharedWorkspace] selectFile:path inFileViewerRootedAtPath:@""];
|
||||
}
|
||||
|
||||
- (NSString *)getUTI:(NSString *)path
|
||||
{
|
||||
NSError *error;
|
||||
return [[NSWorkspace sharedWorkspace] typeOfFile:path error:&error];
|
||||
}
|
||||
|
||||
- (BOOL)type:(NSString *)type conformsToType:(NSString *)refType
|
||||
{
|
||||
return [[NSWorkspace sharedWorkspace] type:type conformsToType:refType];
|
||||
}
|
||||
|
||||
- (NSString *)getAppdataPath
|
||||
{
|
||||
return [NSSearchPathForDirectoriesInDomains(NSApplicationSupportDirectory, NSUserDomainMask, YES) objectAtIndex:0];
|
||||
}
|
||||
- (NSString *)getCachePath
|
||||
{
|
||||
return [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) objectAtIndex:0];
|
||||
}
|
||||
|
||||
- (NSString *)getResourcePath
|
||||
{
|
||||
return [[[NSBundle mainBundle] resourceURL] path];
|
||||
}
|
||||
|
||||
- (NSString *)systemLang
|
||||
{
|
||||
return [[NSBundle preferredLocalizationsFromArray:[[NSBundle mainBundle] localizations]] objectAtIndex:0];
|
||||
}
|
||||
|
||||
- (NSString *)systemShortDateFormat
|
||||
{
|
||||
[NSDateFormatter setDefaultFormatterBehavior:NSDateFormatterBehavior10_4];
|
||||
NSDateFormatter *f = [[NSDateFormatter alloc] init];
|
||||
[f setDateStyle:NSDateFormatterShortStyle];
|
||||
[f setTimeStyle:NSDateFormatterNoStyle];
|
||||
NSString *result = [[f dateFormat] retain];
|
||||
[f release];
|
||||
return [result autorelease];
|
||||
}
|
||||
|
||||
- (NSString *)systemNumberDecimalSeparator
|
||||
{
|
||||
[NSNumberFormatter setDefaultFormatterBehavior:NSNumberFormatterBehavior10_4];
|
||||
NSNumberFormatter *f = [[NSNumberFormatter alloc] init];
|
||||
NSString *result = [[f decimalSeparator] retain];
|
||||
[f release];
|
||||
return [result autorelease];
|
||||
}
|
||||
|
||||
- (NSString *)systemNumberGroupingSeparator
|
||||
{
|
||||
[NSNumberFormatter setDefaultFormatterBehavior:NSNumberFormatterBehavior10_4];
|
||||
NSNumberFormatter *f = [[NSNumberFormatter alloc] init];
|
||||
NSString *result = [[f groupingSeparator] retain];
|
||||
[f release];
|
||||
return [result autorelease];
|
||||
}
|
||||
|
||||
- (NSString *)systemCurrency
|
||||
{
|
||||
return [[NSLocale currentLocale] objectForKey:NSLocaleCurrencyCode];
|
||||
}
|
||||
|
||||
- (NSString *)bundleIdentifier
|
||||
{
|
||||
return [[NSBundle mainBundle] bundleIdentifier];
|
||||
}
|
||||
|
||||
- (NSString *)appVersion
|
||||
{
|
||||
return [[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleVersion"];
|
||||
}
|
||||
|
||||
- (NSString *)bundleInfo:(NSString *)key
|
||||
{
|
||||
return [[NSBundle mainBundle] objectForInfoDictionaryKey:key];
|
||||
}
|
||||
|
||||
- (NSString *)osxVersion
|
||||
{
|
||||
return [[NSProcessInfo processInfo] operatingSystemVersionString];
|
||||
}
|
||||
|
||||
- (void)postNotification:(NSString *)name userInfo:(NSDictionary *)userInfo
|
||||
{
|
||||
[[NSNotificationCenter defaultCenter] postNotificationName:name object:nil userInfo:userInfo];
|
||||
}
|
||||
|
||||
- (id)prefValue:(NSString *)prefname
|
||||
{
|
||||
return [[NSUserDefaults standardUserDefaults] objectForKey:prefname];
|
||||
}
|
||||
|
||||
- (void)setPrefValue:(NSString *)prefname value:(id)value
|
||||
{
|
||||
[[NSUserDefaults standardUserDefaults] setObject:value forKey:prefname];
|
||||
}
|
||||
|
||||
- (id)prefValue:(NSString *)prefname inDomain:(NSString *)domain
|
||||
{
|
||||
NSDictionary *dict = [[NSUserDefaults standardUserDefaults] persistentDomainForName:domain];
|
||||
return [dict objectForKey:prefname];
|
||||
}
|
||||
|
||||
// Changes a file:/// path into a normal path
|
||||
- (NSString *)url2path:(NSString *)url
|
||||
{
|
||||
NSURL *u = [NSURL URLWithString:url];
|
||||
return [u path];
|
||||
}
|
||||
|
||||
// Create a pool for use into a separate thread.
|
||||
- (void)createPool
|
||||
{
|
||||
[self destroyPool];
|
||||
currentPool = [[NSAutoreleasePool alloc] init];
|
||||
}
|
||||
- (void)destroyPool
|
||||
{
|
||||
if (currentPool != nil) {
|
||||
[currentPool release];
|
||||
currentPool = nil;
|
||||
}
|
||||
}
|
||||
|
||||
- (void)reportCrash:(NSString *)crashReport withGithubUrl:(NSString *)githubUrl
|
||||
{
|
||||
return [HSErrorReportWindow showErrorReportWithContent:crashReport githubUrl:githubUrl];
|
||||
}
|
||||
|
||||
- (void)log:(NSString *)s
|
||||
{
|
||||
NSLog(@"%@", s);
|
||||
}
|
||||
|
||||
- (NSDictionary *)readExifData:(NSString *)imagePath
|
||||
{
|
||||
NSDictionary *result = nil;
|
||||
NSURL* url = [NSURL fileURLWithPath:imagePath];
|
||||
CGImageSourceRef source = CGImageSourceCreateWithURL((CFURLRef)url, nil);
|
||||
if (source != nil) {
|
||||
CFDictionaryRef metadataRef = CGImageSourceCopyPropertiesAtIndex (source, 0, nil);
|
||||
if (metadataRef != nil) {
|
||||
result = [NSDictionary dictionaryWithDictionary:(NSDictionary *)metadataRef];
|
||||
CFRelease(metadataRef);
|
||||
}
|
||||
CFRelease(source);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@end
|
||||
118
cocoalib/cocoa/__init__.py
Normal file
118
cocoalib/cocoa/__init__.py
Normal file
@@ -0,0 +1,118 @@
|
||||
# Created By: Virgil Dupras
|
||||
# Created On: 2007-10-06
|
||||
# Copyright 2015 Hardcoded Software (http://www.hardcoded.net)
|
||||
|
||||
# This software is licensed under the "GPLv3" License as described in the "LICENSE" file,
|
||||
# which should be included with this package. The terms are also available at
|
||||
# http://www.gnu.org/licenses/gpl-3.0.html
|
||||
|
||||
import logging
|
||||
import time
|
||||
import traceback
|
||||
import sys
|
||||
|
||||
from .CocoaProxy import CocoaProxy
|
||||
|
||||
proxy = CocoaProxy()
|
||||
|
||||
def autoreleasepool(func):
|
||||
def wrapper(*args, **kwargs):
|
||||
proxy.createPool()
|
||||
try:
|
||||
func(*args, **kwargs)
|
||||
finally:
|
||||
proxy.destroyPool()
|
||||
return wrapper
|
||||
|
||||
def as_fetch(as_list, as_type, step_size=1000):
|
||||
"""When fetching items from a very big list through applescript, the connection with the app
|
||||
will timeout. This function is to circumvent that. 'as_type' is the type of the items in the
|
||||
list (found in appscript.k). If we don't pass it to the 'each' arg of 'count()', it doesn't work.
|
||||
applescript is rather stupid..."""
|
||||
result = []
|
||||
# no timeout. default timeout is 60 secs, and it is reached for libs > 30k songs
|
||||
item_count = as_list.count(each=as_type, timeout=0)
|
||||
steps = item_count // step_size
|
||||
if item_count % step_size:
|
||||
steps += 1
|
||||
logging.info('Fetching %d items in %d steps' % (item_count, steps))
|
||||
# Don't forget that the indexes are 1-based and that the upper limit is included
|
||||
for step in range(steps):
|
||||
begin = step * step_size + 1
|
||||
end = min(item_count, begin + step_size - 1)
|
||||
if end > begin:
|
||||
result += as_list[begin:end](timeout=0)
|
||||
else: # When there is only one item, the stupid fuck gives it directly instead of putting it in a list.
|
||||
result.append(as_list[begin:end](timeout=0))
|
||||
time.sleep(.1)
|
||||
logging.info('%d items fetched' % len(result))
|
||||
return result
|
||||
|
||||
def extract_tb_noline(tb):
|
||||
# Same as traceback.extract_tb(), but without line fetching
|
||||
limit = 100
|
||||
list = []
|
||||
n = 0
|
||||
while tb is not None and (limit is None or n < limit):
|
||||
f = tb.tb_frame
|
||||
lineno = tb.tb_lineno
|
||||
co = f.f_code
|
||||
filename = co.co_filename
|
||||
name = co.co_name
|
||||
list.append((filename, lineno, name, None))
|
||||
tb = tb.tb_next
|
||||
n = n+1
|
||||
return list
|
||||
|
||||
def safe_format_exception(type, value, tb):
|
||||
"""Format exception from type, value and tb and fallback if there's a problem.
|
||||
|
||||
In some cases in threaded exceptions under Cocoa, I get tracebacks targeting pyc files instead
|
||||
of py files, which results in traceback.format_exception() trying to print lines from pyc files
|
||||
and then crashing when trying to interpret that binary data as utf-8. We want a fallback in
|
||||
these cases.
|
||||
"""
|
||||
try:
|
||||
return traceback.format_exception(type, value, tb)
|
||||
except Exception:
|
||||
result = ['Traceback (most recent call last):\n']
|
||||
result.extend(traceback.format_list(extract_tb_noline(tb)))
|
||||
result.extend(traceback.format_exception_only(type, value))
|
||||
return result
|
||||
|
||||
def install_exception_hook(github_url):
|
||||
def report_crash(type, value, tb):
|
||||
app_identifier = proxy.bundleIdentifier()
|
||||
app_version = proxy.appVersion()
|
||||
osx_version = proxy.osxVersion()
|
||||
s = "Application Identifier: {}\n".format(app_identifier)
|
||||
s += "Application Version: {}\n".format(app_version)
|
||||
s += "Mac OS X Version: {}\n\n".format(osx_version)
|
||||
s += ''.join(safe_format_exception(type, value, tb))
|
||||
if LOG_BUFFER:
|
||||
s += '\nRelevant Console logs:\n\n'
|
||||
s += '\n'.join(LOG_BUFFER)
|
||||
proxy.reportCrash_withGithubUrl_(s, github_url)
|
||||
|
||||
sys.excepthook = report_crash
|
||||
|
||||
# A global log buffer to use for error reports
|
||||
LOG_BUFFER = []
|
||||
|
||||
class CocoaHandler(logging.Handler):
|
||||
def emit(self, record):
|
||||
msg = record.getMessage()
|
||||
proxy.log_(msg)
|
||||
LOG_BUFFER.append(msg)
|
||||
del LOG_BUFFER[:-20]
|
||||
|
||||
def install_cocoa_logger():
|
||||
logging.getLogger().addHandler(CocoaHandler())
|
||||
|
||||
def patch_threaded_job_performer():
|
||||
# _async_run, under cocoa, has to be run within an autorelease pool to prevent leaks.
|
||||
# You only need this patch is you use one of CocoaProxy's function (which allocate objc
|
||||
# structures) inside a threaded job.
|
||||
from hscommon.jobprogress.performer import ThreadedJobPerformer
|
||||
ThreadedJobPerformer._async_run = autoreleasepool(ThreadedJobPerformer._async_run)
|
||||
|
||||
300
cocoalib/cocoa/inter.py
Normal file
300
cocoalib/cocoa/inter.py
Normal file
@@ -0,0 +1,300 @@
|
||||
import logging
|
||||
from objp.util import pyref, dontwrap
|
||||
from . import proxy
|
||||
|
||||
class GUIObjectView:
|
||||
def refresh(self): pass
|
||||
|
||||
class PyGUIObject:
|
||||
def __init__(self, model: pyref):
|
||||
self.model = model
|
||||
self.callback = None
|
||||
|
||||
# This *has* to be called right after initialization.
|
||||
def bindCallback_(self, callback: pyref):
|
||||
self.callback = callback
|
||||
self.model.view = self
|
||||
|
||||
# Call this before the ObjC callback is deallocated to avoid calls to that deallocated instance.
|
||||
def free(self):
|
||||
self.model.view = None
|
||||
self.callback = None
|
||||
|
||||
def modelRef(self) -> pyref:
|
||||
return self.model
|
||||
|
||||
#--- Python -> Cocoa
|
||||
@dontwrap
|
||||
def refresh(self):
|
||||
self.callback.refresh()
|
||||
|
||||
class PyTextField(PyGUIObject):
|
||||
def text(self) -> str:
|
||||
return self.model.text
|
||||
|
||||
def setText_(self, newtext: str):
|
||||
self.model.text = newtext
|
||||
|
||||
|
||||
class SelectableListView(GUIObjectView):
|
||||
def updateSelection(self): pass
|
||||
|
||||
class PySelectableList(PyGUIObject):
|
||||
def items(self) -> list:
|
||||
# Should normally always return strings
|
||||
return self.model[:]
|
||||
|
||||
def selectIndex_(self, index: int):
|
||||
self.model.select(index)
|
||||
|
||||
def selectedIndex(self) -> int:
|
||||
result = self.model.selected_index
|
||||
if result is None:
|
||||
result = -1
|
||||
return result
|
||||
|
||||
def selectedIndexes(self) -> list:
|
||||
return self.model.selected_indexes
|
||||
|
||||
def selectIndexes_(self, indexes: list):
|
||||
self.model.select(indexes)
|
||||
|
||||
def searchByPrefix_(self, prefix: str) -> int:
|
||||
return self.model.search_by_prefix(prefix)
|
||||
|
||||
#--- model --> view
|
||||
@dontwrap
|
||||
def update_selection(self):
|
||||
self.callback.updateSelection()
|
||||
|
||||
class ColumnsView:
|
||||
def restoreColumns(self): pass
|
||||
def setColumn_visible_(self, colname: str, visible: bool): pass
|
||||
|
||||
class PyColumns(PyGUIObject):
|
||||
def columnNamesInOrder(self) -> list:
|
||||
return self.model.colnames
|
||||
|
||||
def columnDisplay_(self, colname: str) -> str:
|
||||
return self.model.column_display(colname)
|
||||
|
||||
def columnIsVisible_(self, colname: str) -> bool:
|
||||
return self.model.column_is_visible(colname)
|
||||
|
||||
def columnWidth_(self, colname: str) -> int:
|
||||
return self.model.column_width(colname)
|
||||
|
||||
def moveColumn_toIndex_(self, colname: str, index: int):
|
||||
self.model.move_column(colname, index)
|
||||
|
||||
def resizeColumn_toWidth_(self, colname: str, newwidth: int):
|
||||
self.model.resize_column(colname, newwidth)
|
||||
|
||||
def setColumn_defaultWidth_(self, colname: str, width: int):
|
||||
self.model.set_default_width(colname, width)
|
||||
|
||||
def menuItems(self) -> list:
|
||||
return self.model.menu_items()
|
||||
|
||||
def toggleMenuItem_(self, index: int) -> bool:
|
||||
return self.model.toggle_menu_item(index)
|
||||
|
||||
def resetToDefaults(self):
|
||||
self.model.reset_to_defaults()
|
||||
|
||||
#--- Python --> Cocoa
|
||||
@dontwrap
|
||||
def restore_columns(self):
|
||||
self.callback.restoreColumns()
|
||||
|
||||
@dontwrap
|
||||
def set_column_visible(self, colname: str, visible):
|
||||
self.callback.setColumn_visible_(colname, visible)
|
||||
|
||||
class OutlineView(GUIObjectView):
|
||||
def startEditing(self): pass
|
||||
def stopEditing(self): pass
|
||||
def updateSelection(self): pass
|
||||
|
||||
class PyOutline(PyGUIObject):
|
||||
def cancelEdits(self):
|
||||
self.model.cancel_edits()
|
||||
|
||||
def canEditProperty_atPath_(self, property: str, path: list) -> bool:
|
||||
node = self.model.get_node(path)
|
||||
assert node is self.model.selected_node
|
||||
return getattr(node, 'can_edit_' + property, False)
|
||||
|
||||
def saveEdits(self):
|
||||
self.model.save_edits()
|
||||
|
||||
def selectedPath(self) -> list:
|
||||
return self.model.selected_path
|
||||
|
||||
def setSelectedPath_(self, path: list):
|
||||
self.model.selected_path = path
|
||||
|
||||
def selectedPaths(self) -> list:
|
||||
return self.model.selected_paths
|
||||
|
||||
def setSelectedPaths_(self, paths: list):
|
||||
self.model.selected_paths = paths
|
||||
|
||||
def property_valueAtPath_(self, property: str, path: list) -> object:
|
||||
try:
|
||||
return getattr(self.model.get_node(path), property)
|
||||
except IndexError:
|
||||
logging.warning("%r doesn't have a node at path %r", self.model, path)
|
||||
return ''
|
||||
|
||||
def setProperty_value_atPath_(self, property: str, value: object, path: list):
|
||||
setattr(self.model.get_node(path), property, value)
|
||||
|
||||
#--- Python -> Cocoa
|
||||
@dontwrap
|
||||
def start_editing(self):
|
||||
self.callback.startEditing()
|
||||
|
||||
@dontwrap
|
||||
def stop_editing(self):
|
||||
self.callback.stopEditing()
|
||||
|
||||
@dontwrap
|
||||
def update_selection(self):
|
||||
self.callback.updateSelection()
|
||||
|
||||
class TableView(GUIObjectView):
|
||||
def showSelectedRow(self): pass
|
||||
def startEditing(self): pass
|
||||
def stopEditing(self): pass
|
||||
def updateSelection(self): pass
|
||||
|
||||
class PyTable(PyGUIObject):
|
||||
#--- Helpers
|
||||
@dontwrap
|
||||
def _getrow(self, row):
|
||||
try:
|
||||
return self.model[row]
|
||||
except IndexError:
|
||||
msg = "Trying to get an out of bounds row ({} / {}) on table {}"
|
||||
logging.warning(msg.format(row, len(self.model), self.model.__class__.__name__))
|
||||
|
||||
#--- Cocoa --> Python
|
||||
def columns(self) -> pyref:
|
||||
return self.model.columns
|
||||
|
||||
def add(self):
|
||||
self.model.add()
|
||||
|
||||
def cancelEdits(self):
|
||||
self.model.cancel_edits()
|
||||
|
||||
def canEditColumn_atRow_(self, column: str, row: int) -> object:
|
||||
return self.model.can_edit_cell(column, row)
|
||||
|
||||
def deleteSelectedRows(self):
|
||||
self.model.delete()
|
||||
|
||||
def numberOfRows(self) -> int:
|
||||
return len(self.model)
|
||||
|
||||
def saveEdits(self):
|
||||
self.model.save_edits()
|
||||
|
||||
def selectRows_(self, rows: list):
|
||||
self.model.select(list(rows))
|
||||
|
||||
def selectedRows(self) -> list:
|
||||
return self.model.selected_indexes
|
||||
|
||||
def selectionAsCSV(self) -> str:
|
||||
return self.model.selection_as_csv()
|
||||
|
||||
def setValue_forColumn_row_(self, value: object, column: str, row: int):
|
||||
# this try except is important for the case while a row is in edition mode and the delete
|
||||
# button is clicked.
|
||||
try:
|
||||
self._getrow(row).set_cell_value(column, value)
|
||||
except AttributeError:
|
||||
msg = "Trying to set an attribute that can't: {} with value {} at row {} on table {}"
|
||||
logging.warning(msg.format(column, value, row, self.model.__class__.__name__))
|
||||
raise
|
||||
|
||||
def sortByColumn_desc_(self, column: str, desc: bool):
|
||||
self.model.sort_by(column, desc=desc)
|
||||
|
||||
def valueForColumn_row_(self, column: str, row: int) -> object:
|
||||
return self._getrow(row).get_cell_value(column)
|
||||
|
||||
#--- Python -> Cocoa
|
||||
@dontwrap
|
||||
def show_selected_row(self):
|
||||
self.callback.showSelectedRow()
|
||||
|
||||
@dontwrap
|
||||
def start_editing(self):
|
||||
self.callback.startEditing()
|
||||
|
||||
@dontwrap
|
||||
def stop_editing(self):
|
||||
self.callback.stopEditing()
|
||||
|
||||
@dontwrap
|
||||
def update_selection(self):
|
||||
self.callback.updateSelection()
|
||||
|
||||
class ProgressWindowView(GUIObjectView):
|
||||
def setProgress_(self, progress: int): pass
|
||||
def showWindow(self): pass
|
||||
def closeWindow(self): pass
|
||||
|
||||
class PyProgressWindow(PyGUIObject):
|
||||
def jobdescTextField(self) -> pyref:
|
||||
return self.model.jobdesc_textfield
|
||||
|
||||
def progressdescTextField(self) -> pyref:
|
||||
return self.model.progressdesc_textfield
|
||||
|
||||
def pulse(self):
|
||||
self.model.pulse()
|
||||
|
||||
def cancel(self):
|
||||
self.model.cancel()
|
||||
|
||||
#--- Python -> Cocoa
|
||||
@dontwrap
|
||||
def set_progress(self, last_progress):
|
||||
self.callback.setProgress_(last_progress)
|
||||
|
||||
@dontwrap
|
||||
def show(self):
|
||||
self.callback.showWindow()
|
||||
|
||||
@dontwrap
|
||||
def close(self):
|
||||
self.callback.closeWindow()
|
||||
|
||||
|
||||
class BaseAppView:
|
||||
def showMessage_(self, msg: str): pass
|
||||
|
||||
class PyBaseApp(PyGUIObject):
|
||||
def appName(self) -> str:
|
||||
return self.model.PROMPT_NAME
|
||||
|
||||
def appLongName(self) -> str:
|
||||
return self.model.NAME
|
||||
|
||||
#--- Python --> Cocoa
|
||||
@dontwrap
|
||||
def get_default(self, key_name):
|
||||
return proxy.prefValue_(key_name)
|
||||
|
||||
@dontwrap
|
||||
def set_default(self, key_name, value):
|
||||
proxy.setPrefValue_value_(key_name, value)
|
||||
|
||||
@dontwrap
|
||||
def show_message(self, msg):
|
||||
self.callback.showMessage_(msg)
|
||||
|
||||
Reference in New Issue
Block a user