Post by Guy RouillierPost by Jens MiltnerAnother thing to consider would be to make the sandbox settings
local, i.e. don't use global variables to hold the values: at least
MacCvs allows to open more than one sandbox browser simultaneously
and currently, it's a bit of a hack to switch settings when a window
comes to front (because settings are global in the current
implementation).
Jens, thanks for the reply. I don't use the Mac, so please help me
understand what you mean by local sandbox settings. Do these get
persisted or is their lifetime only while the app instance is running?
If they get persisted, what differentiates one set from another? Are
they connected to a specific project, like non-global settings? If so,
could we persist them in the same store that maintains the project settings?
The current implementation already differentiates between "global"
and "project" settings: when constructing a CPersistent, it takes a
kClassPersistent argument, which uses the completely non-intuitive
enum values "kNoClass" and "kAddSettings". Values of type "kNoClass"
are considered global variables and values of type "kAddSettings" are
stored on a per-sandbox basis.
In the Mac implementation, the two classes of settings are also
stored in different locations: the global ones are stored in the
standard system preference location (kind of similar to the Windows
Registry), whereas the per-sandbox settings are stored in text files
in a specific subdirectory of the Mac's Preference folder. Each text
file contains (among other settings) the sandbox path, so the
settings can be identified to be connected to that sandbox...
I'm pretty sure the basic mechanism is the same for the other
platforms, IIRC, even the implementation for the per-sandbox settings
is shared, the only differences are the location where things are
stored and the storage format of the global settings.
Post by Guy RouillierPerhaps what we should do is use the global settings as the
default, and
allow the project settings to override. If we do that, I'd like to
break out Admin-Preferences into two separate menu items: Global
settings and Project settings. Having two sets of the same
settings in
a single dialog box would get very confusing.
I think in general, the idea to allow overriding a global setting is
good, however, there are certainly some settings that you would want
to toggle globally, i.e. you don't want to check with each sandbox
whether they have been defined there. You mentioned the cvs
executable, which is a good example of such a setting...
In general, I think the current classification between global and per-
sandbox settings isn't too bad, the only thing missing is a defined
way to specify your default settings and allow to override specific
settings per-sandbox. Right now, you can specify which settings to
use as the starting point when browsing a new sandbox (at least
that's how it works in MacCvs), but once you picked the settings,
this contains all settings, i.e. changing the default settings won't
affect any existing sandbox...
Post by Guy RouillierLet's be explicit. In gCvs, on the Preferences dialog is a Globals tab
Checkout read=only
Use TCP/IP compression
Quiet mode
Dirty files support
Prune empty directories
Supply control when adding files
In WinCvs, I see
File attribute (equivalent to Checkout read-only in gCvs)
CVS Messages (equivalent to Quiet mode in gCvs)
Prune empty directories
Compression level
Encrypt communication
Checkout text files with Unix LF
Disable splash screen
Supply control when adding files
Match path case with Entries case
Logout automatically after N minutes
Are these the ones you are referring to, or are you referring to
everything in the Settings dialog?
Regardless, I still like the idea of having Project setting inherit the
global ones but allow for override. But now having written all this, it
sounds like a better name would be "Default settings" and then
"Project
settings".
Some things seem truly global, like path to CVS executable, preferred
external diff program. Why would you want that to vary by project?
Perhaps we need to revisit what is a global and what is per project.
As I mentioned above, the distinction between global and per-project
(or per-sandbox) settings is already there...
The other thing I was referring to were the 'local' settings: In
MacCvs, you can have more than one browser window open, each one
pointing to a different sandbox. However, the current settings
implementation uses global CPersistent instances to access the
settings. This means that theoretically, each of the browsers would
access the very same settings. The current solution in MacCvs is to
switch the settings when bringing another browser window to front,
i.e. store the modified settings of the browser/sandbox being
deactivated and load the settings for the browser becoming the front/
focused window. This is really a big hack, since if there was some
code that would read settings for a background window, this code
would suddenly get the settings for the other sandbox!
In order to solve this problem, I started once to make the
CPersistent values dynamically allocated and create a
CPersistentContainer that would encompass the set of persistent
values that comprise the sandbox settings. Then the browser would
keep a pointer to the CpersistentContainer object and ask this object
for specific settings. Essentially, it's pretty much making the
CvsPrefs class not a singleton, but allocated dynamically where each
instance keeps it's own set of settings (except for the global
settings, which are, of course, shared among all instances, to make
them - well - global ;-)
This involved quite a dose of code changes, since the settings object
needs to be passed around to anything that needs access to the
settings. There were also a couple of places left where I haven't yet
come up with a proper solution - like e.g. the timer code that
automatically logs out after a specified interval. This code is -
most likely - broken anyway on the Mac, since it assumes there is a
single cvs pserver we're connected to, but if you have multiple
browser windows open, chances are you are logged into more than one
server...
Anyway, the main issue here is that switching to a 'local settings'
model requires some major API changes to pass the settings around,
but it would also allow things like 'shoot and forget' style cvs
command handling, i.e. allow to kick off one cvs command and without
having to wait for this command to finish, immediately kick off the
next command. This may even be helpful for single browser
implementations, where you wouldn't have to wait for certain
commands to finish before launching the next command (e.g. update one
subdirectory, commit another one, etc.)
IMHO, the switch to 'local' settings is the more important step over
the switch to overridable settings and/or replacing the CPersistent
model. However, when breaking the APIs anyway, it would certainly be
a good time to adjust the persistent model as well.
Personally, my favorite settings implementation would really look
something like this:
class Settings
{
public:
static Settings* CreateSettingsForPath(const char* sandboxPath);
void Read();
void Write();
bool GetString(const char* key, std::string& value);
void SetString(const char* key, const std::string& value);
bool GetInt(const char* key, int& value);
void SetInt(const char* key, int value);
bool GetBool(const char* key, bool& value);
void SetBool(const char* key, bool value);
// ... more specific accessors could go here
// this one allows to retrieve lists of [sub-]settings - this one
would allow to implement things like persistent string lists
// (e.g. the list of previous CVSROOTs)
bool GetArray(const char* key, std::vector<Settings>& valueArray);
void SetArray(const char* key, const std::vector<Settings>&
valueArray);
};
We'd pass around a settings object and any code needing settings
would ask that settings object for the specific setting values.
The settings class is responsible for reading/writing settings in a
type-safe manner, i.e. it would check for proper values when reading
settings (which would also be platform specific to allow storing the
settings in a platform specific manner - PropertyList files on Mac
OS, perhaps Registry on Windows, ASCII files in ~/.gCvs/Settings/ on
Linux).
Alternatively, the accessor APIs could just return the value itself,
e.g.
std::string GetString(const char* key);
If the settings value is not specified in the project settings, a
default value would be returned. Maybe that's even easier, although
it might be nice to have both APIs (in case you need to check for the
existence of certain settings). The second variant could then just
use the first one internally and provide the default value if the
first one returns false...
just my €.02,
</jum>
Yahoo! Groups Links
<*> To visit your group on the web, go to:
http://groups.yahoo.com/group/cvsgui-dev/
<*> To unsubscribe from this group, send an email to:
cvsgui-dev-***@yahoogroups.com
<*> Your use of Yahoo! Groups is subject to:
http://docs.yahoo.com/info/terms/