Thread: Re: [Pyobjc-dev] pyobjc on 2.2.1 & non-framework builds
Brought to you by:
ronaldoussoren
From: Bill B. <bb...@co...> - 2002-09-23 17:13:16
|
I'll have to revisit Jack's PythonLauncher when I have more time-- it has some serious issues/bugs. It also requires a framework build of python. This is completely unnecessary and incurs an arbitrary limitation [user has to have Python.framework around as opposed to using the standard out-of-the-box Python included with 10.2]. b.bum On Monday, September 23, 2002, at 12:48 PM, Tony Lownds wrote: >> Also -- I believe that we can make standalone scripts work fine even >> if they launch UI sessions. I built a little app called >> PythonLauncher that can be used to springboard the launching of a >> script that uses the UI. It provides a full blown "bundle" >> environment, as required by the X environment, but allows multiple >> copies to be launched. I'll have to hack on it... > > Jack Jansen has made a little app called PythonLauncher as well, see > the Python CVS... > > -Tony |
From: Ronald O. <ous...@ci...> - 2002-09-24 16:32:09
|
On Monday, Sep 23, 2002, at 19:13 Europe/Amsterdam, Bill Bumgarner wrote: > I'll have to revisit Jack's PythonLauncher when I have more time-- it > has some serious issues/bugs. Such as? IMHO it would be better not to fork python, the situation is hazy enough. I'd like to see a python-based PythonLauncher in the future, but that is a completely different story. > > It also requires a framework build of python. This is completely > unnecessary and incurs an arbitrary limitation [user has to have > Python.framework around as opposed to using the standard > out-of-the-box Python included with 10.2]. Is the framework really necessary or is it only required because of the current build procedure? BTW. I'd prefer to have a framework install of python as the standard python sometime in the future. Maybe in MacOSX 10.4........ Ronald |
From: Bill B. <bb...@co...> - 2002-09-24 17:48:28
|
On Tuesday, September 24, 2002, at 12:32 PM, Ronald Oussoren wrote: > On Monday, Sep 23, 2002, at 19:13 Europe/Amsterdam, Bill Bumgarner > wrote: > >> I'll have to revisit Jack's PythonLauncher when I have more time-- it >> has some serious issues/bugs. > > Such as? IMHO it would be better not to fork python, the situation is > hazy enough. I'd like to see a python-based PythonLauncher in the > future, but that is a completely different story. In general, the application appears to have been created by someone who doesn't have an understanding of how to leverage the Cocoa APIs in a pattern that is consistent with the API's design. This is not a criticism of Jack -- he is obviously a brilliant developer. The application could use to be rewritten. Also, the application uses the system() call to pass control into the Python interpreter. This effectively leaves the PythonLauncher as the parent process of the underlying "real" application. In all, it solves a different problem than the problem presented by the goal of creating standalone fully Cocoa compliant applications. Namely, PythonLauncher is much more about invoking a particular script and much less about distributing a standalone ".app" that a user can simply double-click to use. I'm going to focus on solving the specific problems related to standalone Py-Cocoa based applications first, then revisit PythonLauncher. > >> >> It also requires a framework build of python. This is completely >> unnecessary and incurs an arbitrary limitation [user has to have >> Python.framework around as opposed to using the standard >> out-of-the-box Python included with 10.2]. > > Is the framework really necessary or is it only required because of > the current build procedure? The framework isn't necessary at all. Everything pyobjc related works fine with the "out of the box" install included with OS X 10.2. > > BTW. I'd prefer to have a framework install of python as the standard > python sometime in the future. Maybe in MacOSX 10.4........ I would rather see Python remain as open and cross platform compatible as possible. In that context, a framework (or bundle) might be an appropriate means of encapsulating resources specific to the Macintosh extension modules. I.e. the mac specific (OS X, really) resources would be shoved into PyMac.framework down in site-packages (assuming the macintosh support were to remain as a module). However, encapsulating all of python into a framework doesn't really add anything to the environment in terms of features and definitely makes for a weird twist when using the Mac platform. b.bum |
From: Ronald O. <ous...@ci...> - 2002-09-25 17:51:06
|
On Tuesday, Sep 24, 2002, at 19:48 Europe/Amsterdam, Bill Bumgarner wrote: > > In all, it solves a different problem than the problem presented by > the goal of creating standalone fully Cocoa compliant applications. > Namely, PythonLauncher is much more about invoking a particular script > and much less about distributing a standalone ".app" that a user can > simply double-click to use. Could you please rename your PythonLauncher, two applications with the same name is pretty confusing. To illustrate this: The 'PythonLauncher' you mention above is probably Jack's version, not yours but I'm not entirely sure... Just to make things clear: Is your PythonLauncher meant to be a binary that can be dropped in a '.app' directory to create a python-based application? > >> >>> >>> It also requires a framework build of python. This is completely >>> unnecessary and incurs an arbitrary limitation [user has to have >>> Python.framework around as opposed to using the standard >>> out-of-the-box Python included with 10.2]. >> >> Is the framework really necessary or is it only required because of >> the current build procedure? > > The framework isn't necessary at all. Everything pyobjc related > works fine with the "out of the box" install included with OS X 10.2. I was refering to your remark about (Jack's) PythonLauncher requiring a framework python, but given the completely different goals of yours and Jack's PythonLauncher that is not really relevant. > >> >> BTW. I'd prefer to have a framework install of python as the standard >> python sometime in the future. Maybe in MacOSX 10.4........ > > I would rather see Python remain as open and cross platform compatible > as possible. In that context, a framework (or bundle) might be an > appropriate means of encapsulating resources specific to the Macintosh > extension modules. I.e. the mac specific (OS X, really) resources > would be shoved into PyMac.framework down in site-packages (assuming > the macintosh support were to remain as a module). > > However, encapsulating all of python into a framework doesn't really > add anything to the environment in terms of features and definitely > makes for a weird twist when using the Mac platform. This is probably something that should be discussed on the Python-on-Mac SIG, but what the heck... I definitely do not like a partial framework (the unix install containing a PyMac.framework for Mac specific stuff). That would be both confusing and reduce cross-platform compatibility (e.g. how should distutils cope with that?). Like you said, the framework install doesn't really add new features. However, I also feel that it doesn't hamper cross-platform compatibility and openess. If you replace /usr/bin/python by a symlink to the python inside a framework install the resulting situation is completely compatible with the current situation. The reasons I like the framework approach are twofold. First of all frameworks are the method Apple is pushing for publishing library-type stuff (and I like to think of the python interpreter as a complicated type of dynamic loader :-)). But more importantly, a framework install makes it more clear that Python is not just tool for 'unix weenies' but something you can use for real work. BTW. I'm a Unix weenie myself and most (Python) code I write at the moment has to do with either command-line scripts or webbased stuff. The framework install of Python I have at my machine is perfectly useable for this. Back to making Python the best development tool on MacOS X, Ronald P.S. Don't let this keep you from improving PyObjC for users of the Apple-distributed Python ;-) ;-) |
From: Bill B. <bb...@co...> - 2002-09-25 19:31:12
|
On Wednesday, September 25, 2002, at 01:51 PM, Ronald Oussoren wrote: > On Tuesday, Sep 24, 2002, at 19:48 Europe/Amsterdam, Bill Bumgarner > wrote: >> In all, it solves a different problem than the problem presented by >> the goal of creating standalone fully Cocoa compliant applications. >> Namely, PythonLauncher is much more about invoking a particular >> script and much less about distributing a standalone ".app" that a >> user can simply double-click to use. > > Could you please rename your PythonLauncher, two applications with the > same name is pretty confusing. To illustrate this: The > 'PythonLauncher' you mention above is probably Jack's version, not > yours but I'm not entirely sure... Oh, I suppose -- I mean, my PythonLauncher was actually a quickie hack posted to python-mac to answer some questions about how to write a PythonLauncher type thing. I even cc'd Jack on the original... But, he beat me into the repository, so the name is his. :-) The above referred to Jack's app. (In all seriousness, yes-- the name should and will be changed if I get around to writing a replacement for the existing [Jack's] PythonLauncher). > Just to make things clear: Is your PythonLauncher meant to be a binary > that can be dropped in a '.app' directory to create a python-based > application? Nope -- that is a completely different app/problem. More info later today. >>> BTW. I'd prefer to have a framework install of python as the >>> standard python sometime in the future. Maybe in MacOSX 10.4........ >> >> I would rather see Python remain as open and cross platform >> compatible as possible. In that context, a framework (or bundle) >> might be an appropriate means of encapsulating resources specific to >> the Macintosh extension modules. I.e. the mac specific (OS X, >> really) resources would be shoved into PyMac.framework down in >> site-packages (assuming the macintosh support were to remain as a >> module). >> >> However, encapsulating all of python into a framework doesn't >> really add anything to the environment in terms of features and >> definitely makes for a weird twist when using the Mac platform. > > This is probably something that should be discussed on the > Python-on-Mac SIG, but what the heck... We can go there once we have hashed through it a bit here... > I definitely do not like a partial framework (the unix install > containing a PyMac.framework for Mac specific stuff). That would be > both confusing and reduce cross-platform compatibility (e.g. how > should distutils cope with that?). > > Like you said, the framework install doesn't really add new features. > However, I also feel that it doesn't hamper cross-platform > compatibility and openess. If you replace /usr/bin/python by a symlink > to the python inside a framework install the resulting situation is > completely compatible with the current situation. If it doesn't add any features, then why add all of the administrative/maintenance overhead to the core python project that is necessary to support it? Looking at the piles and piles of patches required in configure, the various makefiles, and an entire subdirectory full of gunk that is special cased into the framework build, it seems that the framework build is already hampering cross-platform compatibility in that it requires so much extra effort to make python work on the Mac platform [assuming a framework build is a part of supporting the Mac platform]. Anything that unnecessarily makes the Macintosh support behave differently than, say, bsd/sun/linux hampers cross platform compatibility. > > The reasons I like the framework approach are twofold. First of all > frameworks are the method Apple is pushing for publishing library-type > stuff (and I like to think of the python interpreter as a complicated > type of dynamic loader :-)). But more importantly, a framework install > makes it more clear that Python is not just tool for 'unix weenies' > but something you can use for real work. Apple pushes framework based encapsulation of things that are libraries for reusable code specific to the platform, not for reusable/libary code that is made available across many platforms. Looking at the system (and Darwin), the only exception is the readline framework. Looking /usr/lib/ reveals that Apple is very much pushing for a build model for portable code -- libz, termcap, ruby, perl, python, tcl, crypto, pthreads, etc... -- that requires as few changes as possible between OS X/Darwin and any other Unix derived platform. IMO, this is a wise decision -- it reduces the amount of maintenance necessary on the part of Apple and third party developers to achieve continued first class support for these tools on the platform. Whether Python is in a framework or as a regular "command line" tool will do little to attract or deter non "unix weenies" from using it. We will be able to attract many more developers by supporting and providing examples for doing Python development in PBX using the out-of-the-box python on OS X. Certainly, having a Python IDE and the ability to run individual scripts from, say, the Finder will help, but having to rebuild/reinstall Python to gain access to that capability will deter many. Given the rather crufty implementation of said solutions-- Carbon is legacy and at a completely different granularity than Python or Cooca-- quite a few more developers will be deterred. > > BTW. I'm a Unix weenie myself and most (Python) code I write at the > moment has to do with either command-line scripts or webbased stuff. > The framework install of Python I have at my machine is perfectly > useable for this. Perfectly usable, yes, but it adds a boatload of additional maintenance cost and installation headache to the core python codebase. The framework based build of Python has existed since the NeXT days along with a number of unnecessary, platform specific, modifications to the core codebase to support NeXT and it has been a constant source of headaches. The end result is that the version of Python on NeXT and, now, OS X has typically lagged behind the version available on other-- more mainstream-- platforms by anywhere from days to months. Certainly, OS X's popularity will reduce that gap, but why have a gap if it can be avoided entirely and comfortably? Furthermore, the chances of Apple shipping a framework build of python as a part of the system are pretty slim as the framework build of python doesn't add much to the capabilities of the language and incurs a bunch of additional maintenance/support headaches for Apple (i.e. do they have to ship a separate version for, say, Darwin??). Not that Carbon support in Python does not require the framework build -- it is just the extended Mac Python IDE / Dev environment that requires the framework (mostly because the build of it is currently quite broken). > > Back to making Python the best development tool on MacOS X, > > Ronald > > P.S. Don't let this keep you from improving PyObjC for users of the > Apple-distributed Python ;-) ;-) I think of Python + Cocoa via PyObjC as being at the same level as, say, AppleScript Studio. Python provides the high level, easy to author, development language similar to AppleScript (though easier) while PyObjC provides the glue into the Cocoa frameworks. Frankly, given the comparative cleanliness with which Python interacts with ObjC across the PyObjC bridge, the Python solution is a hell of a lot simpler and easier to deal with than AppleScript Studio -- not a criticism of Studio, just the realities of building AppleScript based development tools. The proof is in the code -- I'm going to stop blathering now and actually put together a proper / easy recipe for creating Python based Cocoa apps and commit that into the repository... b.bum |
From: Jack J. <Jac...@or...> - 2002-10-24 20:47:55
|
On maandag, september 23, 2002, at 07:13 , Bill Bumgarner wrote: > I'll have to revisit Jack's PythonLauncher when I have more > time-- it has some serious issues/bugs. Bill, could you explain, please? PythonLauncher is my first "real" ObjC program, so I'm not surprised there's bug in it (let alone ideosyncracies: I couldn't find any example of how to mould the per-file settings based on preference settings in the Document paradigm, so I just came up with something). If you can give me some hints as to what I did wrong I'd love to hear it... -- - Jack Jansen <Jac...@or...> http://www.cwi.nl/~jack - - If I can't dance I don't want to be part of your revolution -- Emma Goldman - |
From: Bill B. <bb...@co...> - 2002-10-25 01:34:17
|
On Thursday, October 24, 2002, at 04:47 PM, Jack Jansen wrote: > On maandag, september 23, 2002, at 07:13 , Bill Bumgarner wrote: > >> I'll have to revisit Jack's PythonLauncher when I have more time-- it >> has some serious issues/bugs. > > Bill, > could you explain, please? PythonLauncher is my first "real" ObjC > program, so I'm not surprised there's bug in it (let alone > ideosyncracies: I couldn't find any example of how to mould the > per-file settings based on preference settings in the Document > paradigm, so I just came up with something). If you can give me some > hints as to what I did wrong I'd love to hear it... Jack, It works -- which is more than can be said for a lot of first programs written by developers working against an unfamiliar API! A lot of the problems have to do with not following the patterns as set forth in "traditional" ObjC/Cocoa programming -- not something that someone new to the environment would necessarily find natural to their development environment. Your skin is thick, you know you're a damned good at this stuff, and I don't have a lot of time -- as such, I'm not going to candy coat anything... just try to stick with terse [hopefully] constructive criticism in the form of a basic code /architecture review. Low level code review (syntax, naming, etc -- i.e. nit picking): The methods ... - (IBAction)do_run:(id)sender; - (IBAction)do_cancel:(id)sender; - (IBAction)do_reset:(id)sender; - (IBAction)do_apply:(id)sender; ... would be traditionally declared as (keeping the names the same, but in the ObjC style) ... - (IBAction)doRun:(id)sender; - (IBAction)doCancel:(id)sender; - (IBAction)doReset:(id)sender; - (IBAction)doApply:(id)sender; ... the 'do' prefix is a useful distinction. It is equally as common to see no prefix/suffix or to see 'Action:' as a suffix on each action method (redundant in the declarations, damned handy -- like do* -- in the code): - (IBAction)runAction: sender; - (IBAction)cancelAction: sender; - (IBAction)resetAction: sender; - (IBAction)applyAction: sender; - In the init method ... - (id)init { [super init]; if (self) { script = @"<no script>.py"; filetype = @"Python Script"; } return self; } ... the two instance variables need to be retained and the test for (self) being defined will never fail even if super's init did fail. Try... - (id)init { self = [super init]; if (self) { script = [@"<no script>.py" retain]; filetype = [@"Python Script" retain]; } return self; } ... or, alternatively, simply set script and filetype to nil (or, if feeling particularly terse, don't set 'em at all because ObjC initializes all variables to nil upon allocation -- personally, I like to set it to nil simply as an acknowledgment that that is what I expect the value to be). - The methods ... - (void)load_defaults - (void)update_display - (void)update_settings ... would typically be declared as ... - (void)loadDefaults - (void)updateDisplay - (void)updateSettings ... etc ... - In general, you should use -UTF8String to retrieve character buffers from NSString objects to be passed off to the BSD layer. The BSD layer should be able to handle UTF-8 encoded unicode for paths, etc, throughout -- by doing this, the app will work on systems where the app, python or the scripts are installed on a path that has unicode characters in it. - In -readFromFile:.... script = [fileName retain]; filetype = [type retain]; Assuming the previous values of the iVar have been retained (the bug in init has been fixed), this will leak the two string objects. Release 'em first. - FileSettings Lots of hardcoded stuff throughout -- need to be able to support a framework build of python in ~/Library/Frameworks/ or a command line in /usr/bin/python, /usr/local/bin/ or /sw/bin (or wherever). - The interaction between -init, -initWithFileSettings: and -factorySettingsForFileType: is a bit odd. If anything, factorySettingsForFileType: should return void and -init should simply invoke the method before returning self. -factorySettingsForFileType: should probably be -applyFactorySettingsForFileType: since it is more about changing the instance and less about finding a settings set for a particular file type (which would be the role of a class method). - -initWithFileSettings: That style of indirection into the object (i.e. source->debug) is extremely uncommon in ObjC. It breaks encapsulation. Any method prefixed with -init is generally considered to be an initializer and, as such, is likely going to be used in the pattern of [[... alloc] init...] -- as such, the method should invoke [self init] or [super init]... --- In interacting with user defaults, I typically create a property list file that contains the registration defaults for the application. This file is added to the project's resources. To load the defaults is a matter of... ... typically done in applicationDidFinishLaunching: or applicationWillFinishLaunching: ... NSDictionary *registrationDefaults = [NSDictionary dictionaryWithContentsOfFile: [[NSBundle mainBundle] pathForResource: @"RegistrationDefaults" ofType: @"plist"]]; [[NSUserDefaults standardUserDefaults] registerDefaults: registrationDefaults]; This also makes it quite easy to restore all the way back to factory settings without hardwiring the factory settings into the code -- simply grab the registration defaults from the file and set them into the app's domain. --- Bugs & Architecture: - there should be a way in the GUI to open a file into the settings -- i.e. the Open... command should be "Run script..." and "Open..." should truly open the script as a document. Or maybe have an accessory view with an "edit settings before running" checkbox? - the 'run in terminal' button doesn't update the field contents and, as such, the contents can get out of sync... - NSTask would be a better candidate than system() to subshell out the command. It would allow the app to monitor the output and display a console. If motivated, you could even have a field via which to interact with the interpreter (the current interactive mode doesn't do much good if, say, the app were launched from the Finder). - If the multi-doc architecture is going to be used, there should be something to save! How about saving the current settings out to a file such that the user can double-click the file to not only run the script but run it with their custom set of settings? - If I use the new menu item, it doesn't seem possible to set the script to be executed by the document. - +getDefaultsForFileType: should use a dictionary to store the file settings. - [[FileSettings new] init] == [[[FileSettings alloc] init] init] - Since both the preferences window and the documents have the same interior UI, the NIB file for that UI should be split out and the preferences and document window should share that single NIB. The preferences window should likely move to a tabbed view with the different file types in the tabs -- that seems to be the HIG way these days. Finally, the app really isn't a multiple-document type app. The comment above would move it in that direction, but there still wouldn't be a concept of "documents" given the current implementation. As it is, the app's name is indicative of it's role -- it launches Python scripts and provides a bit of control over how they are executed. The first step in moving to a true multi-doc style app is for the app to give the user control over when documents are closed -- that is, if a user opens a python script [as opposed to Running... a script without opening a visible document at all], the associated window should remain open until the user tells it to go away. The document should have a notion of 'currently running, do you want to launch another instance of the same thing?' and 'abort/stop current run'. Documents should be able to be saved -- everything is pretty much there to do so now, just a matter of returning an NSData containing the settings + the path to the script from the appropriate NSDocument method. ... My train has arrived at its destination, so I'm going to send this now... Given the direction that MacPython is going-- away from solely focused on the framework build and to a form that works with Apple's build of python or whatever happens to be present-- there are some other things that should likely change about the GUI tools used to work with the Python environment. Of course, a part of me wants to rewrite PythonLauncher using PyObjC :-). b.bum |
From: Jack J. <Jac...@or...> - 2002-10-25 08:00:54
|
On Friday, October 25, 2002, at 02:40 , Bill Bumgarner wrote: > Your skin is thick, you know you're a damned good at this stuff, > and I don't have a lot of time -- as such, I'm not going to candy coat > anything... just try to stick with terse [hopefully] constructive > criticism in the form of a basic code /architecture review. Bill, thanks a *lot*! This style of comment is very helpful to me when exploring a new language. I'll have another look at the code and try to bring it more in line with what you suggest, -- - Jack Jansen <Jac...@or...> http://www.cwi.nl/~jack - - If I can't dance I don't want to be part of your revolution -- Emma Goldman - |
From: Jack J. <Jac...@cw...> - 2002-10-25 13:31:36
|
Bill, a couple of questions on your architectural remarks. On Friday, Oct 25, 2002, at 02:40 Europe/Amsterdam, Bill Bumgarner wrote: > Bugs & Architecture: > > - there should be a way in the GUI to open a file into the > settings -- i.e. the Open... command should be "Run script..." and > "Open..." should truly open the script as a document. [...] > > - the 'run in terminal' button doesn't update the field contents > and, as such, the contents can get out of sync... > > - If the multi-doc architecture is going to be used, there should > be something to save! [...] > Finally, the app really isn't a multiple-document type app. [...] All these hinge on the fact that PythonLauncher looks like a multidocument application, but really isn't. Is that a problem? I modeled the semantics more-or-less after Stuffit Expander: PythonLauncher can operate in 2 modes, one where it's already running (and opening a document always goes into interactive mode) and another one where the application is started for a single document, which is launched (optionally after allowing interaction to set the options) after which PythonLauncher quits without further ado. > - If I use the new menu item, it doesn't seem possible to set the > script to be executed by the document. That's because I haven't been able to disable the New command, which is what I really would want to do. Can you tell me how to do this? (Or, better, tell me where I should have found the information) > - Since both the preferences window and the documents have the > same interior UI, the NIB file for that UI should be split out and the > preferences and document window should share that single NIB. The > preferences window should likely move to a tabbed view with the > different file types in the tabs -- that seems to be the HIG way these > days. Again, I wanted to do this but I haven't been able to come up with a way to do it. Please enlighten me. There's actually two things that I haven't been able to find out: 1. How can I share the interior contents of two windows? 2. How do I get a tabbed view without actually having something different on every tab (I want the same controls on each tab, really, and I don't want to duplicate either the code or the controls)? > - NSTask would be a better candidate than system() to subshell out > the command. It would allow the app to monitor the output and display > a console. [...] > The first step in moving to a true multi-doc style app is for the app > to give the user control over when documents are closed -- that is, if > a user opens a python script [as opposed to Running... a script > without opening a visible document at all], the associated window > should remain open until the user tells it to go away. The document > should have a notion of 'currently running, do you want to launch > another instance of the same thing?' and 'abort/stop current run'. These are things I specifically don't want to do (i.e. convince me otherwise if you think it's worthwhile). The intention of PythonLauncher is to be like Java AppletLauncher (or the above mentioned Stuffit Expander): it should "fire and forget" the script. Remember, the reason this was written in the first place is because CFBundleTypeRole=Shell doesn't work (which is what it's trying to emulate, with the options dialog thrown in so that we no longer have to provide that in pythonw, and have the functionality for console scripts too). Ideally a naive user shouldn't even be aware of the fact that this thing exists. -- - Jack Jansen <Jac...@or...> http://www.cwi.nl/~jack - - If I can't dance I don't want to be part of your revolution -- Emma Goldman - |
From: Bill B. <bb...@co...> - 2002-10-27 22:44:29
|
On Friday, October 25, 2002, at 09:31 AM, Jack Jansen wrote: > Bill, > a couple of questions on your architectural remarks. > On Friday, Oct 25, 2002, at 02:40 Europe/Amsterdam, Bill Bumgarner > wrote: >> Bugs & Architecture: >> >> - there should be a way in the GUI to open a file into the >> settings -- i.e. the Open... command should be "Run script..." and >> "Open..." should truly open the script as a document. [...] >> >> - the 'run in terminal' button doesn't update the field contents >> and, as such, the contents can get out of sync... >> >> - If the multi-doc architecture is going to be used, there should >> be something to save! [...] >> Finally, the app really isn't a multiple-document type app. [...] > > All these hinge on the fact that PythonLauncher looks like a > multidocument application, but really isn't. Is that a problem? I > modeled the semantics more-or-less after Stuffit Expander: > PythonLauncher can operate in 2 modes, one where it's already running > (and opening a document always goes into interactive mode) and another > one where the application is started for a single document, which is > launched (optionally after allowing interaction to set the options) > after which PythonLauncher quits without further ado. Ahh... OK -- that clarifies things a bit and I'll modify my comments accordingly. I could see use for a multi-doc app if one were to want to save per-script configuration information but, as you indicate, there isn't a whole heck of a lot of value in that. A console might be nice, though, and that would open the need to leave the app running. >> - If I use the new menu item, it doesn't seem possible to set the >> script to be executed by the document. > > That's because I haven't been able to disable the New command, which > is what I really would want to do. Can you tell me how to do this? > (Or, better, tell me where I should have found the information) In a multiple document architecture app, the 'new' menu item is bound to newDocument: on the First Responder. If it should always be disabled, why not just delete the menu item? In any case, you can use Cocoa's automatic menu validation to disable the menu item. Implement the following method on the application's delegate: - (BOOL)validateMenuItem:(NSMenuItem *)aCell { SEL action = [aCell action]; if (action == @selector(newDocument:)) return NO; return YES; } -validateMenuItem: can be implemented on any object in the responder chain. Whenever a menu is popped down, the method is called for each cell in the menu -- the invocation of methods follows the same pattern as the responder chain. I.e. first responder view -> superview -> superview -> ...etc... -> window -> window's delegate -> app -> app's delegate. If you don't have any documents/windows on the screen, then the responder chain is just app -> app's delegate and, in this case, means you want to return NO for the newDocument: item from the app's delegate's implementation. >> - Since both the preferences window and the documents have the >> same interior UI, the NIB file for that UI should be split out and >> the preferences and document window should share that single NIB. >> The preferences window should likely move to a tabbed view with the >> different file types in the tabs -- that seems to be the HIG way >> these days. > > Again, I wanted to do this but I haven't been able to come up with a > way to do it. Please enlighten me. There's actually two things that I > haven't been able to find out: > 1. How can I share the interior contents of two windows? First, create a new nib file that contains a Custom View in it (a Custom View is just a container for other views, in this instance -- kind of like a window in a regular nib file). Stick the shared UI into this NIB file. The trick is that the file's owner doesn't have to be the same class as it is in the runtime-- it just needs to be the instance of some class that defines the same set of actions and outlets as are used in IB. An alternative would be to make the Settings class control the UI elements -- if the outlets are non-nil, it keeps the UI up to date and monitors user interaction with the UI. An instance of settings could then be passed as the owner. Then, when you load either the preferences panel or a script window's NIB, load this second NIB as well. Now that you have all the UI elements loaded, the trick is to shove 'em into the window. This is mostly a case of moving the various views around to make room for the new chunk of content. Very likely, the easiest solution is to simply dump a custom view into the window. Resize it to be in the position and of the same size as the chunk of UI you are going to be sharing between the two windows. Add an outlet to the PreferencesWindowController and MyDocument classes that connect to the view to be replaced. Then, in awakeFromNib:, do something like: [[viewToBeReplacedWithRealContents superview] replaceSubview: viewToBeReplacedWithRealContents with: customViewThatContainsTheSharedContentsInThatOtherNibFile] More sane variable names would likely be preferable... (For the preferences controller, there is no need to do the view swap thing as the TabView already has a view in it that can be used to swap the UI elements in as necessary. > 2. How do I get a tabbed view without actually having something > different on every tab (I want the same controls on each tab, really, > and I don't want to duplicate either the code or the controls)? Good question. I don't... didn't... know. I gave it a try and it boils down to a one liner (I love Cocoa that way :-). Set your window controller (document, whatever) to be the delegate of the Tab View. Then, implement something like: - (void)tabView:(NSTabView *)aTabView didSelectTabViewItem:(NSTabViewItem *)tabViewItem; { // share the shared UI elements across all tabs. Use -identifier to figure out which tab was selected if you want to do so passively. Alternatively, use [[tabView selectedTabViewItem] ...] or create three outlets to the tab view items and simply do == when updating / reading from the UI. NSLog(@"Did select tab %@ (%@)", [tabViewItem identifier], [tabViewItem label]); [[[tabView selectedTabViewItem] view] addSubview: sharedUIElements]; } To make sure *something* is displayed when the nib is loaded, do the following in, say, -awakeFromNib: [[[tabView selectedTabViewItem] view] addSubview: sharedUIElements]; You can grab the example from the following URL -- it is bogus save for the tab view manipulation. It also shows how to programmatically create tabs -- may be necessary if you want to support a dynamic list of configurations or something similar. http://www.friday.com/software/examples/tabtest.tgz >> - NSTask would be a better candidate than system() to subshell >> out the command. It would allow the app to monitor the output and >> display a console. > [...] >> The first step in moving to a true multi-doc style app is for the app >> to give the user control over when documents are closed -- that is, >> if a user opens a python script [as opposed to Running... a script >> without opening a visible document at all], the associated window >> should remain open until the user tells it to go away. The document >> should have a notion of 'currently running, do you want to launch >> another instance of the same thing?' and 'abort/stop current run'. > > These are things I specifically don't want to do (i.e. convince me > otherwise if you think it's worthwhile). The intention of > PythonLauncher is to be like Java AppletLauncher (or the above > mentioned Stuffit Expander): it should "fire and forget" the script. > Remember, the reason this was written in the first place is because > CFBundleTypeRole=Shell doesn't work (which is what it's trying to > emulate, with the options dialog thrown in so that we no longer have > to provide that in pythonw, and have the functionality for console > scripts too). Ideally a naive user shouldn't even be aware of the fact > that this thing exists. I'm all for keeping it as simple as possible. If someone really wants to have more control over the execution of a script, then they can use the IDE or command line directly. Given the clarification as to the design goals provided above, these requested features are pretty much out the window-- but they would be nice to have in other contexts... b.bum |