The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.
package Padre::Config;

=pod

=head1 NAME

Padre::Config - Configuration subsystem for Padre

=head1 SYNOPSIS

    use Padre::Config;
    [...]
    if ( Padre::Config->main_statusbar ) { [...] }

=head1 DESCRIPTION

This module not only stores the complete Padre configuration, it also holds
the functions for loading and saving the configuration.

The Padre configuration lives in two places:

=over

=item a user-editable text file usually called F<config.yml>

=item an SQLite database which shouldn't be edited by the user

=back

=head2 Generic usage

Every setting is accessed by a mutator named after it as follows:

  # Get the identity of the current user
  my $name = $config->identity_name;
  
  # Set the identity of the current user
  my $changed = $config->identity_name("John Smith");

=head2 Different types of settings

Padre needs to store different types of settings, storing them in different
places depending on their impact, with C<Padre::Config> allows access to access
them with a unified API (a mutator).

Here are the various types of settings that C<Padre::Config> can manage:

=over 4

=item * User settings

Those settings are general settings that relates to user preferences. They range
from general user interface I<look & feel> (whether to show the line numbers, etc.)
to editor preferences (tab width, etc.) and other personal settings.

Those settings are stored in a YAML file in your configuration directory (which you
can see in the About dialog)

=item * Host settings

Those preferences are related to the host on which Padre is run. The principal
example of those settings is the locatio of the main window appearance, and other
values which could be different between different operating systems and machines.

Those settings are stored in a SQLite file.

=item * Project settings

Those preferences are related to the project of the file you are currently
editing and allow, in principle, projects to set policies on certain values.

Examples of those settings are whether to use tabs or spaces, etc.

=back

=head1 METHODS

While the vast majority of the methods for this class are mutator front ends,
a number of methods exist which allow you to interact with the config system
more directly.

=cut

use 5.008;
use strict;
use warnings;
use Carp                   ();
use File::Spec             ();
use Scalar::Util           ();
use Params::Util           ();
use Padre::Constant        ();
use Padre::Util            ();
use Padre::Current         ();
use Padre::Config::Setting ();
use Padre::Config::Human   ();
use Padre::Config::Host    ();
use Padre::Locale::T;
use Padre::Logger;

our $VERSION    = '0.98';
our $COMPATIBLE = '0.93';

our ( %SETTING, %DEFAULT, %STARTUP, $REVISION, $SINGLETON );

BEGIN {

	# Master storage of the settings
	%SETTING = ();

	# A cache for the defaults
	%DEFAULT = ();

	# A cache for startup.yml settings
	%STARTUP = ();

	# Storage for the default config object
	$SINGLETON = undef;

	# Load Portable Perl support if needed
	require Padre::Portable if Padre::Constant::PORTABLE;
}

# Accessor generation
use Class::XSAccessor::Array {
	getters => {
		host    => Padre::Constant::HOST,
		human   => Padre::Constant::HUMAN,
		project => Padre::Constant::PROJECT,
	},
	accessors => {
		restart => Padre::Constant::RESTART,
	}
};

my $PANEL_OPTIONS = {
	left   => _T('Left Panel'),
	right  => _T('Right Panel'),
	bottom => _T('Bottom Panel'),
};





#####################################################################
# Settings Specification

# This section identifies the set of all named configuration entries,
# and where the configuration system should resolve them to.

=pod

=head2 settings

  my @names = Padre::Config->settings;

Returns the names of all registered settings as a sorted list.

=cut

sub settings {
	my @names = keys %SETTING;
	return wantarray ? sort @names : scalar @names;
}

#
# setting( %params );
#
# Create a new setting, with %params used to feed the new object.
#
sub setting {

	# Allow this sub to be called as a method or function
	shift if ref( $_[0] ) eq __PACKAGE__;

	# Validate the setting
	my $object = Padre::Config::Setting->new(@_);
	my $name   = $object->{name};
	if ( $SETTING{$name} ) {
		Carp::croak("The $name setting is already defined");
	}

	# Generate the accessor
	SCOPE: {
		local $@;
		eval $object->code;
		Carp::croak("Failed to compile setting $object->{name}: $@") if $@;
	}

	# Save the setting
	$SETTING{$name} = $object;
	$DEFAULT{$name} = $object->{default};
	$STARTUP{$name} = 1 if $object->{startup};

	return 1;
}





#####################################################################
# Constructor and Input/Output

sub new {
	my $class = shift;
	my $host  = shift;
	my $human = shift;
	unless ( Params::Util::_INSTANCE( $host, 'Padre::Config::Host' ) ) {
		Carp::croak("Did not provide a host config to Padre::Config->new");
	}
	unless ( Params::Util::_INSTANCE( $human, 'Padre::Config::Human' ) ) {
		Carp::croak("Did not provide a user config to Padre::Config->new");
	}

	# Create the basic object with the two required elements
	my $self = bless [ $host, $human, undef, 0 ], $class;

	# Add the optional third element
	if (@_) {
		my $project = shift;
		unless ( Params::Util::_INSTANCE( $project, 'Padre::Config::Project' ) ) {
			Carp::croak("Did not provide a project config to Padre::Config->new");
		}
		$self->[Padre::Constant::PROJECT] = $project;
	}

	return $self;
}

=pod

=head2 read

  my $config = Padre::Config->read;

The C<read> method reads and loads the config singleton for the current instance of Padre
from the various places it is stored, or returns the singleton again if it has already
been loaded.

Returns a B<Padre::Config> object, or throws an exception if loaded of the configuration
fails.

=cut

sub read {
	my $class = shift;

	unless ($SINGLETON) {
		TRACE("Loading configuration for $class") if DEBUG;

		# Load the host configuration
		my $host = Padre::Config::Host->read;

		# Load the user configuration
		my $human = Padre::Config::Human->read
			|| Padre::Config::Human->create;

		# Hand off to the constructor
		$SINGLETON = $class->new( $host, $human );
	}

	return $SINGLETON;
}

sub write {
	TRACE( $_[0] ) if DEBUG;
	my $self = shift;

	# Save the user configuration
	delete $self->[Padre::Constant::HUMAN]->{version};
	delete $self->[Padre::Constant::HUMAN]->{Version};
	$self->[Padre::Constant::HUMAN]->write;

	# Save the host configuration
	delete $self->[Padre::Constant::HOST]->{version};
	delete $self->[Padre::Constant::HOST]->{Version};
	$self->[Padre::Constant::HOST]->write;

	# Write the startup subset of the configuration.
	# NOTE: Use a hyper-minimalist listified key/value file format
	# so that we don't need to load YAML::Tiny before the thread fork.
	# This should save around 400k of memory per background thread.
	my %startup = (
		VERSION => $VERSION,
		map { $_ => $self->$_() } sort keys %STARTUP
	);
	open( my $FILE, '>', Padre::Constant::CONFIG_STARTUP ) or return 1;
	print $FILE map {"$_\n$startup{$_}\n"} sort keys %startup or return 1;
	close $FILE or return 1;

	return 1;
}

sub clone {
	my $self  = shift;
	my $class = Scalar::Util::blessed($self);
	my $host  = $self->host->clone;
	my $human = $self->human->clone;
	if ( $self->project ) {
		my $project = $self->project->clone;
		return $class->new( $host, $human, $project );
	} else {
		return $class->new( $host, $human );
	}
}





######################################################################
# Main Methods

=pod

=head2 meta

  my $setting = Padre::Config->meta("identity_name");

The C<meta> method finds the configuration metadata for a named
setting.

Returns a L<Padre::Config::Setting> object, or throws an exception if the
named setting does not exist.

=cut

sub meta {
	$SETTING{ $_[1] } or die("Missing or invalid setting name '$_[1]'");
}

=pod

=head2 default

  my $value = Padre::Config->default("main_directory_panel");

The C<default> method reports the default value for the setting in the
context of the currently running instance of Padre (some settings may have
different default on different operating systems, for example)

Returns a value that is legal for the setting type, or throws an exception if
the named setting does not exist.

=cut

sub default {
	my $self = shift;
	my $name = shift;

	# Does the setting exist?
	unless ( $SETTING{$name} ) {
		Carp::croak("The configuration setting '$name' does not exist");
	}

	return $DEFAULT{$name};
}

=pod

=head2 changed

  my $same = ! $config->changed( "identity_name", "John Smith" );

The C<changed> method takes a named setting and a value for that setting,
and determines if setting that value on the config would result in the
configuration being changed.

Returns true if the value provided is different to the current setting, or
false if the value provided is the same (or effectively the same) as the
current setting.

=cut

sub changed {
	my $self = shift;
	my $name = shift;
	my $new  = shift;
	my $old  = $self->$name();
	my $type = $self->meta($name)->type;
	if ( $type == Padre::Constant::ASCII or $type == Padre::Constant::PATH ) {
		return $new ne $old;
	} else {
		return $new != $old;
	}
}

=pod

=head2 set

  my $changed = $config->set("identity_name", "John Smith");

The C<set> method takes a named setting and a value and modifies the
configuration object to have that value.

Changes made to the configuration in this manner will not be reflected in
the running instance, for that you should use the C<apply> method.

Returns true, or throws an exception on errors such as a non-existant setting
name or an illegal value for that setting type.

=cut

sub set {
	TRACE( $_[1] ) if DEBUG;
	my $self  = shift;
	my $name  = shift;
	my $value = shift;

	# Does the setting exist?
	my $setting = $SETTING{$name};
	unless ($setting) {
		Carp::croak("The configuration setting '$name' does not exist");
	}

	# All types are Padre::Constant::ASCII-like
	unless ( defined $value and not ref $value ) {
		Carp::croak("Missing or non-scalar value for setting '$name'");
	}

	# We don't need to do additional checks on Padre::Constant::ASCII
	my $type  = $setting->type;
	my $store = $setting->store;
	unless ( defined $type ) {
		Carp::croak("Setting '$name' has undefined type");
	}
	if ( $type == Padre::Constant::BOOLEAN ) {
		$value = 0 if $value eq '';
		if ( $value ne '1' and $value ne '0' ) {
			Carp::croak("Setting '$name' to non-boolean '$value'");
		}
	}
	if ( $type == Padre::Constant::POSINT and not Params::Util::_POSINT($value) ) {
		Carp::croak("Setting '$name' to non-posint '$value'");
	}
	if ( $type == Padre::Constant::INTEGER and not _INTEGER($value) ) {
		Carp::croak("Setting '$name' to non-integer '$value'");
	}
	if ( $type == Padre::Constant::PATH ) {
		if ( Padre::Constant::WIN32 and utf8::is_utf8($value) ) {
			require Win32;
			my $long = Win32::GetLongPathName($value);

			# GetLongPathName returns undef if it doesn't exist.
			unless ( defined $long ) {
				Carp::croak("Setting '$name' to non-existant path '$value'");
			}
			$value = $long;

			# Wx::DirPickerCtrl upgrades data to utf8.
			# Perl on Windows cannot handle utf8 in file names,
			# so this hack converts path back.
		}
		unless ( -e $value ) {
			Carp::croak("Setting '$name' to non-existant path '$value'");
		}

		# If we are in Portable mode convert the path to dist relative if
		# the setting is going into the host backend.
		if ( Padre::Constant::PORTABLE and $store == Padre::Constant::HOST ) {

			# NOTE: Even though this says "directory" it is safe for files too
			$value = Padre::Portable::freeze_directory($value);
		}
	}

	# Now we can stash the variable
	$self->[$store]->{$name} = $value;

	return 1;
}

=pod

=head2 apply

  my $changed = $config->apply("main_directory_panel", "right");

The C<apply> method is a higher order version of the C<set> which will set
the configuration value, and then immediately update the running instance of
Padre to reflect the change.

For example, if the directory panel is open and on the left side of the
display, running the sample code above will change the location preference to
the right side and immediately move the directory panel to the other side of
the IDE.

See L<Padre::Config::Apply> for more information on Padre's on-the-fly
configuration change support.

Returns true if the configuration was changed, false if the value was the
same as the existing configuration value and did not need to be modified,
or throws an exception on errors such as a non-existant setting name or
an illegal value for that setting type.

=cut

sub apply {
	TRACE( $_[0] ) if DEBUG;
	my $self = shift;
	my $name = shift;
	my $new  = shift;

	# Does the setting exist?
	my $setting = $SETTING{$name};
	unless ($setting) {
		Carp::croak("The configuration setting '$name' does not exist");
	}

	# Shortcut if the value has not changed
	my $changed = $self->changed($name, $new);
	return $changed unless $changed;

	# Set the config value
	my $old = $self->$name();
	$self->set( $name => $new );

	# Does this setting have an apply hook
	my $code = do {
		require Padre::Config::Apply;
		Padre::Config::Apply->can($name);
	};
	if ( $code ) {
		# Hand off control to the apply hook
		my $current = Padre::Current::_CURRENT(@_);
		$code->( $current->main, $new, $old );
	} elsif ( $setting->restart ) {
		# Change requires a restart of Padre
		$self->restart(1);
	}

	return 1;
}

sub themes {
	my $class          = shift;
	my $core_directory = Padre::Util::sharedir('themes');
	my $user_directory = File::Spec->catdir(
		Padre::Constant::CONFIG_DIR,
		'themes',
	);

	# Scan themes directories
	my %themes = ();
	foreach my $directory ( $user_directory, $core_directory ) {
		next unless -d $directory;

		# Search the directory
		local *STYLEDIR;
		unless ( opendir( STYLEDIR, $directory ) ) {
			die "Failed to read '$directory'";
		}
		foreach my $file ( readdir STYLEDIR ) {
			next unless $file =~ s/\.txt\z//;
			next unless Params::Util::_IDENTIFIER($file);
			next if $themes{$file};
			$themes{$file} = File::Spec->catfile(
				$directory,
				"$file.txt"
			);
		}
		closedir STYLEDIR;
	}

	return \%themes;
}





######################################################################
# Support Functions

#
# my $is_integer = _INTEGER( $scalar );
#
# return true if $scalar is an integer.
#
sub _INTEGER {
	return defined $_[0] && !ref $_[0] && $_[0] =~ m/^(?:0|-?[1-9]\d*)$/;
}





######################################################################
# Basic Settings

# User identity (simplistic initial version)
# Initially, this must be ascii only
setting(
	name    => 'identity_name',
	type    => Padre::Constant::ASCII,
	store   => Padre::Constant::HUMAN,
	default => '',
);
setting(
	name    => 'identity_email',
	type    => Padre::Constant::ASCII,
	store   => Padre::Constant::HUMAN,
	default => '',
);
setting(
	name    => 'identity_nickname',
	type    => Padre::Constant::ASCII,
	store   => Padre::Constant::HUMAN,
	default => '',
);
setting(
	name    => 'identity_location',
	type    => Padre::Constant::ASCII,
	store   => Padre::Constant::HOST,
	default => '',
);

# Indent settings
# Allow projects to forcefully override personal settings
setting(
	name    => 'editor_indent_auto',
	type    => Padre::Constant::BOOLEAN,
	store   => Padre::Constant::HUMAN,
	default => 1,
	project => 1,
);
setting(
	name    => 'editor_indent_tab',
	type    => Padre::Constant::BOOLEAN,
	store   => Padre::Constant::HUMAN,
	default => 1,
	project => 1,
);
setting(
	name    => 'editor_indent_tab_width',
	type    => Padre::Constant::POSINT,
	store   => Padre::Constant::HUMAN,
	default => 8,
	project => 1,
);
setting(
	name    => 'editor_indent_width',
	type    => Padre::Constant::POSINT,
	store   => Padre::Constant::HUMAN,
	default => 8,
	project => 1,
);





#####################################################################
# Startup Behaviour Rules

setting(
	name    => 'startup_splash',
	type    => Padre::Constant::BOOLEAN,
	store   => Padre::Constant::HUMAN,
	default => 0,
	startup => 1,
	help    => _T('Showing the splash image during start-up'),
);

# Startup mode, if no files given on the command line this can be
#   new        - a new empty buffer
#   nothing    - nothing to open
#   last       - the files that were open last time
setting(
	name    => 'startup_files',
	type    => Padre::Constant::ASCII,
	store   => Padre::Constant::HUMAN,
	default => 'new',
	options => {
		'last'    => _T('Previous open files'),
		'new'     => _T('A new empty file'),
		'nothing' => _T('No open files'),
		'session' => _T('Open session'),
	},
	help => _T('"Open session" will ask which session (set of files) to open when you launch Padre.')
		. _T(
		'"Previous open files" will remember the open files when you close Padre and open the same files next time you launch Padre.'
		),
);

# How many times has the user run Padre?
# Default is 1 and the value is incremented at shutdown rather than
# startup so that we don't have to write files in the startup sequence.
setting(
	name    => 'nth_startup',
	type    => Padre::Constant::POSINT,
	store   => Padre::Constant::HUMAN,
	default => 1,
);

# Save if feedback has been send or not
setting(
	name    => 'nth_feedback',
	type    => Padre::Constant::BOOLEAN,
	store   => Padre::Constant::HUMAN,
	default => 0,
);

# Have we shown the birthday popup this year? (Prevents duplicate popups)
# Store it on the host, because we can't really sync it properly.
setting(
	name    => 'nth_birthday',
	type    => Padre::Constant::INTEGER,
	store   => Padre::Constant::HOST,
	default => 0,
);




######################################################################
# Main Window Tools and Layout

# Window
setting(
	name  => 'main_title',
	type  => Padre::Constant::ASCII,
	store => Padre::Constant::HUMAN,
	default => ( Padre::Constant::PORTABLE ? 'Padre Portable' : 'Padre' ),
	help => _T('Contents of the window title') . _T('Several placeholders like the filename can be used'),
);

setting(
	name    => 'main_singleinstance',
	type    => Padre::Constant::BOOLEAN,
	store   => Padre::Constant::HUMAN,
	default => Padre::Constant::DEFAULT_SINGLEINSTANCE,
	startup => 1,
);

setting(
	name    => 'main_singleinstance_port',
	type    => Padre::Constant::POSINT,
	store   => Padre::Constant::HOST,
	default => Padre::Constant::DEFAULT_SINGLEINSTANCE_PORT,
	startup => 1,
);

setting(
	name    => 'main_lockinterface',
	type    => Padre::Constant::BOOLEAN,
	store   => Padre::Constant::HUMAN,
	default => 1,
);

setting(
	name    => 'main_functions',
	type    => Padre::Constant::BOOLEAN,
	store   => Padre::Constant::HUMAN,
	default => 0,
);

setting(
	name    => 'main_functions_panel',
	type    => Padre::Constant::ASCII,
	store   => Padre::Constant::HUMAN,
	default => 'right',
	options => $PANEL_OPTIONS,
);

setting(
	name    => 'main_functions_order',
	type    => Padre::Constant::ASCII,
	store   => Padre::Constant::HUMAN,
	default => 'alphabetical',
	options => {
		'original'                  => _T('Code Order'),
		'alphabetical'              => _T('Alphabetical Order'),
		'alphabetical_private_last' => _T('Alphabetical Order (Private Last)'),
	},
);

setting(
	name    => 'main_outline',
	type    => Padre::Constant::BOOLEAN,
	store   => Padre::Constant::HUMAN,
	default => 0,
);

setting(
	name    => 'main_outline_panel',
	type    => Padre::Constant::ASCII,
	store   => Padre::Constant::HUMAN,
	default => 'right',
	options => $PANEL_OPTIONS,
);

setting(
	name    => 'main_tasks',
	type    => Padre::Constant::BOOLEAN,
	store   => Padre::Constant::HUMAN,
	default => 0,
);

setting(
	name    => 'main_tasks_panel',
	type    => Padre::Constant::ASCII,
	store   => Padre::Constant::HUMAN,
	default => 'bottom',
	options => $PANEL_OPTIONS,
);

setting(
	name    => 'main_tasks_regexp',
	type    => Padre::Constant::ASCII,
	store   => Padre::Constant::HUMAN,
	default => "#\\s*(?:TO[- ]?DO|XXX|FIX[- ]?ME)(?:[ \\t]*[:-]?)(?:[ \\t]*)(.*?)\\s*\$",
);

setting(
	name    => 'main_directory',
	type    => Padre::Constant::BOOLEAN,
	store   => Padre::Constant::HUMAN,
	default => 0,
);

setting(
	name    => 'main_directory_order',
	type    => Padre::Constant::ASCII,
	store   => Padre::Constant::HUMAN,
	default => 'first',
	options => {
		first => _T('Directories First'),
		mixed => _T('Directories Mixed'),
	},
);

setting(
	name    => 'main_directory_panel',
	type    => Padre::Constant::ASCII,
	store   => Padre::Constant::HUMAN,
	default => 'left',
	options => $PANEL_OPTIONS,
);

setting(
	name  => 'main_directory_root',
	type  => Padre::Constant::ASCII,
	store => Padre::Constant::HOST,
	default => File::HomeDir->my_documents || '',
);

setting(
	name    => 'main_output',
	type    => Padre::Constant::BOOLEAN,
	store   => Padre::Constant::HUMAN,
	default => 0,
);

setting(
	name    => 'main_output_panel',
	type    => Padre::Constant::ASCII,
	store   => Padre::Constant::HUMAN,
	default => 'bottom',
	options => $PANEL_OPTIONS,
);

setting(
	name    => 'main_output_ansi',
	type    => Padre::Constant::BOOLEAN,
	store   => Padre::Constant::HUMAN,
	default => 1,
);

setting(
	name    => 'main_command',
	type    => Padre::Constant::BOOLEAN,
	store   => Padre::Constant::HUMAN,
	default => 0,
);

setting(
	name    => 'main_command_panel',
	type    => Padre::Constant::ASCII,
	store   => Padre::Constant::HUMAN,
	default => 'bottom',
	options => $PANEL_OPTIONS,
);

setting(
	name    => 'main_syntax',
	type    => Padre::Constant::BOOLEAN,
	store   => Padre::Constant::HUMAN,
	default => 0,
);

setting(
	name    => 'main_syntax_panel',
	type    => Padre::Constant::ASCII,
	store   => Padre::Constant::HUMAN,
	default => 'bottom',
	options => $PANEL_OPTIONS,
);

setting(
	name    => 'main_vcs',
	type    => Padre::Constant::BOOLEAN,
	store   => Padre::Constant::HUMAN,
	default => 0,
);

setting(
	name    => 'main_vcs_panel',
	type    => Padre::Constant::ASCII,
	store   => Padre::Constant::HUMAN,
	default => 'right',
	options => $PANEL_OPTIONS,
);

setting(
	name    => 'main_cpan',
	type    => Padre::Constant::BOOLEAN,
	store   => Padre::Constant::HUMAN,
	default => 0,
);

setting(
	name    => 'main_cpan_panel',
	type    => Padre::Constant::ASCII,
	store   => Padre::Constant::HUMAN,
	default => 'right',
	options => $PANEL_OPTIONS,
);

setting(
	name    => 'main_foundinfiles_panel',
	type    => Padre::Constant::ASCII,
	store   => Padre::Constant::HUMAN,
	default => 'bottom',
	options => $PANEL_OPTIONS,
);

setting(
	name    => 'main_replaceinfiles_panel',
	type    => Padre::Constant::ASCII,
	store   => Padre::Constant::HUMAN,
	default => 'bottom',
	options => $PANEL_OPTIONS,
);

setting(
	name    => 'main_breakpoints',
	type    => Padre::Constant::BOOLEAN,
	store   => Padre::Constant::HUMAN,
	default => 0,
);

setting(
	name    => 'main_debugoutput',
	type    => Padre::Constant::BOOLEAN,
	store   => Padre::Constant::HUMAN,
	default => 0,
);

setting(
	name    => 'main_debugger',
	type    => Padre::Constant::BOOLEAN,
	store   => Padre::Constant::HUMAN,
	default => 0,
);

setting(
	name    => 'main_statusbar',
	type    => Padre::Constant::BOOLEAN,
	store   => Padre::Constant::HUMAN,
	default => 1,
	help    => _T('Show or hide the status bar at the bottom of the window.'),
);

setting(
	name    => 'main_statusbar_template',
	type    => Padre::Constant::ASCII,
	store   => Padre::Constant::HUMAN,
	default => '%m %f',
	help    => _T('Contents of the status bar') . _T('Several placeholders like the filename can be used'),
);

setting(
	name  => 'main_toolbar',
	type  => Padre::Constant::BOOLEAN,
	store => Padre::Constant::HUMAN,

	# Toolbars are not typically used for Mac apps.
	# Hide it by default so Padre looks "more Mac'ish"
	# NOTE: Or at least, so we were told. Opinions apparently vary.
	default => Padre::Constant::MAC ? 0 : 1,
);

setting(
	name  => 'main_toolbar_items',
	type  => Padre::Constant::ASCII,
	store => Padre::Constant::HUMAN,

	# This lives here until a better place is found:
	# This is a list of toolbar items, separated by ;
	# The following items are supported:
	#   action
	#     Insert the action
	#   action(argument,argument)
	#     Insert an action which requires one or more arguments
	#   |
	#     Insert a seperator
	default => 'file.new;'
		. 'file.open;'
		. 'file.save;'
		. 'file.save_as;'
		. 'file.save_all;'
		. 'file.close;' . '|;'
		. 'file.open_example;' . '|;'
		. 'edit.undo;'
		. 'edit.redo;' . '|;'
		. 'edit.cut;'
		. 'edit.copy;'
		. 'edit.paste;'
		. 'edit.select_all;' . '|;'
		. 'search.find;'
		. 'search.replace;' . '|;'
		. 'edit.comment_toggle;' . '|;'
		. 'search.open_resource;'
		. 'search.quick_menu_access;' . '|;'
		. 'run.run_document;'
		. 'run.stop;' . '|;'
		. 'debug.launch;'
		. 'debug.set_breakpoint;'
		. 'debug.quit;' . '|;'
);

# Directory Tree Settings
setting(
	name  => 'default_projects_directory',
	type  => Padre::Constant::PATH,
	store => Padre::Constant::HOST,
	default => File::HomeDir->my_documents || '',
);

# Editor Settings

# The default editor font should be Consolas 10pt on Vista and Windows 7
setting(
	name  => 'editor_font',
	type  => Padre::Constant::ASCII,
	store => Padre::Constant::HUMAN,
	default => Padre::Util::DISTRO =~ /^WIN(?:VISTA|7)$/ ? 'consolas 10' : '',
);
setting(
	name    => 'editor_linenumbers',
	type    => Padre::Constant::BOOLEAN,
	store   => Padre::Constant::HUMAN,
	default => 1,
);
setting(
	name    => 'editor_eol',
	type    => Padre::Constant::BOOLEAN,
	store   => Padre::Constant::HUMAN,
	default => 0,
);
setting(
	name    => 'editor_whitespace',
	type    => Padre::Constant::BOOLEAN,
	store   => Padre::Constant::HUMAN,
	default => 0,
);
setting(
	name    => 'editor_indentationguides',
	type    => Padre::Constant::BOOLEAN,
	store   => Padre::Constant::HUMAN,
	default => 0,
);
setting(
	name    => 'editor_calltips',
	type    => Padre::Constant::BOOLEAN,
	store   => Padre::Constant::HUMAN,
	default => 0,
);
setting(
	name    => 'editor_autoindent',
	type    => Padre::Constant::ASCII,
	store   => Padre::Constant::HUMAN,
	default => 'deep',
	options => {
		'no'   => _T('No Autoindent'),
		'same' => _T('Indent to Same Depth'),
		'deep' => _T('Indent Deeply'),
	},
);
setting(
	name    => 'editor_folding',
	type    => Padre::Constant::BOOLEAN,
	store   => Padre::Constant::HUMAN,
	default => 0,
);
setting(
	name    => 'editor_fold_pod',
	type    => Padre::Constant::BOOLEAN,
	store   => Padre::Constant::HUMAN,
	default => 0,
);

setting(
	name    => 'editor_brace_expression_highlighting',
	type    => Padre::Constant::BOOLEAN,
	store   => Padre::Constant::HUMAN,
	default => 0,
);

setting(
	name    => 'save_autoclean',
	type    => Padre::Constant::BOOLEAN,
	store   => Padre::Constant::HUMAN,
	default => 0,
);
setting(
	name    => 'editor_currentline',
	type    => Padre::Constant::BOOLEAN,
	store   => Padre::Constant::HUMAN,
	default => 1,
);
setting(
	name    => 'editor_currentline_color',
	type    => Padre::Constant::ASCII,
	store   => Padre::Constant::HUMAN,
	default => 'FFFF04',
);
setting(
	name    => 'editor_wordwrap',
	type    => Padre::Constant::BOOLEAN,
	store   => Padre::Constant::HUMAN,
	default => 0,
);
setting(
	name    => 'editor_file_size_limit',
	type    => Padre::Constant::POSINT,
	store   => Padre::Constant::HUMAN,
	default => 500_000,
);
setting(
	name    => 'editor_right_margin_enable',
	type    => Padre::Constant::BOOLEAN,
	store   => Padre::Constant::HUMAN,
	default => 0,
);
setting(
	name    => 'editor_right_margin_column',
	type    => Padre::Constant::POSINT,
	store   => Padre::Constant::HUMAN,
	default => 80,
);
setting(
	name    => 'editor_smart_highlight_enable',
	type    => Padre::Constant::BOOLEAN,
	store   => Padre::Constant::HUMAN,
	default => 1,
);
setting(
	name    => 'editor_cursor_blink',
	type    => Padre::Constant::INTEGER,
	store   => Padre::Constant::HUMAN,
	default => 500,                     # milliseconds
);
setting(
	name    => 'editor_dwell',
	type    => Padre::Constant::INTEGER,
	store   => Padre::Constant::HUMAN,
	default => 500,
);
setting(
	name    => 'find_case',
	type    => Padre::Constant::BOOLEAN,
	store   => Padre::Constant::HUMAN,
	default => 1,
);
setting(
	name    => 'find_regex',
	type    => Padre::Constant::BOOLEAN,
	store   => Padre::Constant::HUMAN,
	default => 0,
);
setting(
	name    => 'find_reverse',
	type    => Padre::Constant::BOOLEAN,
	store   => Padre::Constant::HUMAN,
	default => 0,
);
setting(
	name    => 'find_first',
	type    => Padre::Constant::BOOLEAN,
	store   => Padre::Constant::HUMAN,
	default => 0,
);
setting(
	name    => 'find_nohidden',
	type    => Padre::Constant::BOOLEAN,
	store   => Padre::Constant::HUMAN,
	default => 1,
);
setting(
	name    => 'find_nomatch',
	type    => Padre::Constant::BOOLEAN,
	store   => Padre::Constant::HUMAN,
	default => 0,
);
setting(
	name    => 'default_line_ending',
	type    => Padre::Constant::ASCII,
	store   => Padre::Constant::HUMAN,
	default => Padre::Constant::NEWLINE,
	options => {
		'UNIX' => 'UNIX',
		'WIN'  => 'WIN',
		'MAC'  => 'MAC',
	},
);
setting(
	name    => 'update_file_from_disk_interval',
	type    => Padre::Constant::ASCII,
	store   => Padre::Constant::HUMAN,
	default => 2,
);

# Autocomplete settings (global and Perl-specific)
setting(
	name    => 'autocomplete_multiclosebracket',
	type    => Padre::Constant::BOOLEAN,
	store   => Padre::Constant::HUMAN,
	default => 0,
);
setting(
	name    => 'autocomplete_always',
	type    => Padre::Constant::BOOLEAN,
	store   => Padre::Constant::HUMAN,
	default => 0,
);
setting(
	name    => 'autocomplete_method',
	type    => Padre::Constant::BOOLEAN,
	store   => Padre::Constant::HUMAN,
	default => 0,
);
setting(
	name    => 'autocomplete_subroutine',
	type    => Padre::Constant::BOOLEAN,
	store   => Padre::Constant::HUMAN,
	default => 0,
);
setting(
	name    => 'lang_perl5_autocomplete_max_suggestions',
	type    => Padre::Constant::ASCII,
	store   => Padre::Constant::HUMAN,
	default => 20,
);
setting(
	name    => 'lang_perl5_autocomplete_min_chars',
	type    => Padre::Constant::ASCII,
	store   => Padre::Constant::HUMAN,
	default => 1,
);
setting(
	name    => 'lang_perl5_autocomplete_min_suggestion_len',
	type    => Padre::Constant::ASCII,
	store   => Padre::Constant::HUMAN,
	default => 3,
);
setting(
	name    => 'lang_perl5_lexer_ppi_limit',
	type    => Padre::Constant::POSINT,
	store   => Padre::Constant::HUMAN,
	default => 4000,
);

# Behaviour Tuning
# When running a script from the application some of the files might have
# not been saved yet. There are several option what to do before running the
# script:
# none - don't save anything (the script will be run without current modifications)
# unsaved - as above but including modifications present in the buffer
# same - save the file in the current buffer
# all_files - all the files (but not buffers that have no filenames)
# all_buffers - all the buffers even if they don't have a name yet
setting(
	name    => 'run_save',
	type    => Padre::Constant::ASCII,
	store   => Padre::Constant::HUMAN,
	default => 'same',
);
setting(
	name  => 'run_perl_cmd',
	type  => Padre::Constant::ASCII,
	store => Padre::Constant::HOST,

	# We don't get a default from Padre::Perl, because the saved value
	# may be outdated sometimes in the future, reading it fresh on
	# every run makes us more future-compatible
	default => '',
);

setting(
	name  => 'lang_perl5_tags_file',
	type  => Padre::Constant::ASCII,
	store => Padre::Constant::HOST,

	# Don't save a default to allow future updates
	default => '',
);

setting(
	name    => 'lang_perl5_lexer',
	type    => Padre::Constant::ASCII,
	store   => Padre::Constant::HOST,
	default => '',
	options => {
		''                                => _T('Scintilla'),
		'Padre::Document::Perl::Lexer'    => _T('PPI Experimental'),
		'Padre::Document::Perl::PPILexer' => _T('PPI Standard'),
	},
);

setting(
	name    => 'xs_calltips_perlapi_version',
	type    => Padre::Constant::ASCII,
	store   => Padre::Constant::PROJECT,
	default => 'newest',
	project => 1,
);

setting(
	name    => 'info_on_statusbar',
	type    => Padre::Constant::BOOLEAN,
	store   => Padre::Constant::HUMAN,
	default => 0,
	help    => _T('Show low-priority info messages on statusbar (not in a popup)'),
);

# Move of stacktrace to run menu: will be removed (run_stacktrace)
setting(
	name    => 'run_stacktrace',
	type    => Padre::Constant::BOOLEAN,
	store   => Padre::Constant::HUMAN,
	default => 0,
);
setting(
	name    => 'autocomplete_brackets',
	type    => Padre::Constant::BOOLEAN,
	store   => Padre::Constant::HUMAN,
	default => 0,
);

setting(
	name    => 'mid_button_paste',
	type    => Padre::Constant::BOOLEAN,
	store   => Padre::Constant::HUMAN,
	default => 0,
);

setting(
	name    => 'sessionmanager_sortorder',
	type    => Padre::Constant::ASCII,
	store   => Padre::Constant::HUMAN,
	default => "0,0",
);

# By default use background threads unless profiling
# TO DO - Make the default actually change

# (Ticket # 669)
setting(
	name    => 'threads',
	type    => Padre::Constant::BOOLEAN,
	store   => Padre::Constant::HUMAN,
	default => 1,
	startup => 1,
);
setting(
	name    => 'threads_maximum',
	type    => Padre::Constant::INTEGER,
	store   => Padre::Constant::HOST,
	default => 9,
);
setting(
	name  => 'threads_stacksize',
	type  => Padre::Constant::INTEGER,
	store => Padre::Constant::HOST,
	default => Padre::Constant::WIN32 ? 4194304 : 0,
	startup => 1,
);
setting(
	name    => 'locale',
	type    => Padre::Constant::ASCII,
	store   => Padre::Constant::HUMAN,
	default => '',
);

# Colour Data
# Since it's in local files, it has to be a host-specific setting.
setting(
	name    => 'editor_style',
	type    => Padre::Constant::ASCII,
	store   => Padre::Constant::HOST,
	default => 'default',
	options => Padre::Config->themes,
);

# Window Geometry
setting(
	name    => 'main_maximized',
	type    => Padre::Constant::BOOLEAN,
	store   => Padre::Constant::HOST,
	default => 0,
);
setting(
	name    => 'main_top',
	type    => Padre::Constant::INTEGER,
	store   => Padre::Constant::HOST,
	default => -1,
);
setting(
	name    => 'main_left',
	type    => Padre::Constant::INTEGER,
	store   => Padre::Constant::HOST,
	default => -1,
);
setting(
	name    => 'main_width',
	type    => Padre::Constant::POSINT,
	store   => Padre::Constant::HOST,
	default => -1,
);
setting(
	name    => 'main_height',
	type    => Padre::Constant::POSINT,
	store   => Padre::Constant::HOST,
	default => -1,
);

# Run Parameters
setting(
	name    => 'run_interpreter_args_default',
	type    => Padre::Constant::ASCII,
	store   => Padre::Constant::HOST,
	default => '',
);
setting(
	name    => 'run_script_args_default',
	type    => Padre::Constant::ASCII,
	store   => Padre::Constant::HOST,
	default => '',
);
setting(
	name    => 'run_use_external_window',
	type    => Padre::Constant::BOOLEAN,
	store   => Padre::Constant::HOST,
	default => 1,
);

# External tool integration

setting(
	name  => 'bin_shell',
	type  => Padre::Constant::PATH,
	store => Padre::Constant::HOST,
	default => Padre::Constant::WIN32 ? 'cmd.exe' : '',
);

# Enable/Disable entire functions that some people dislike.
# Normally these should be enabled by default (or should be
# planned to eventually be enabled by default).

# Disable Bookmark functionality.
# Reduces code size and menu entries.
setting(
	name    => 'feature_bookmark',
	type    => Padre::Constant::BOOLEAN,
	store   => Padre::Constant::HUMAN,
	default => 1,
	restart => 1,
);

# Disable convenience font-size changes.
# Reduces menu entries and prevents accidental font size changes
# due to Ctrl-MouseWheel mistakes.
setting(
	name    => 'feature_fontsize',
	type    => Padre::Constant::BOOLEAN,
	store   => Padre::Constant::HUMAN,
	default => 1,
	restart => 1,
);

# Disable code folding.
# Reduces code bloat and menu entries.
setting(
	name    => 'feature_folding',
	type    => Padre::Constant::BOOLEAN,
	store   => Padre::Constant::HUMAN,
	default => 1,
	restart => 1,
);

# Disable session support.
# Reduces code bloat and database operations.
setting(
	name    => 'feature_session',
	type    => Padre::Constant::BOOLEAN,
	store   => Padre::Constant::HUMAN,
	default => 1,
	restart => 1,
);

# Disable remembering cursor position.
# Reduces code bloat and database operations.
setting(
	name    => 'feature_cursormemory',
	type    => Padre::Constant::BOOLEAN,
	store   => Padre::Constant::HUMAN,
	default => 1,
	restart => 1,
);

# Disable GUI debugger.
# Reduces code bloat and toolbar/menu entries for people that
# prefer to use command line debugger (which is also less buggy)
setting(
	name    => 'feature_debugger',
	type    => Padre::Constant::BOOLEAN,
	store   => Padre::Constant::HUMAN,
	default => 1,
	restart => 1,
);

# Enable experimental quick fix system.
setting(
	name    => 'feature_quick_fix',
	type    => Padre::Constant::BOOLEAN,
	store   => Padre::Constant::HUMAN,
	default => 0,
	restart => 1,
);

# Enable experimental preference sync support.
setting(
	name    => 'feature_sync',
	type    => Padre::Constant::BOOLEAN,
	store   => Padre::Constant::HUMAN,
	default => 0,
	restart => 1,
);

# Enable experimental expanded style support
setting(
	name    => 'feature_style_gui',
	type    => Padre::Constant::BOOLEAN,
	store   => Padre::Constant::HUMAN,
	default => 0,
	restart => 1,
);

# Enable experimental Run with Devel::EndStats support.
setting(
	name    => 'feature_devel_endstats',
	type    => Padre::Constant::BOOLEAN,
	store   => Padre::Constant::HUMAN,
	default => 0,
	restart => 1,
	help    => _T('Enable or disable the Run with Devel::EndStats if it is installed. ')
		. _T('This requires an installed Devel::EndStats and a Padre restart'),
);

# Specify Devel::EndStats options for experimental Run with Devel::EndStats support
setting(
	name    => 'feature_devel_endstats_options',
	type    => Padre::Constant::ASCII,
	store   => Padre::Constant::HUMAN,
	default => 'verbose,1',
	help    => _T(q{Specify Devel::EndStats options. 'feature_devel_endstats' must be enabled.}),
);

# Enable experimental Run with Devel::TraceUse support.
setting(
	name    => 'feature_devel_traceuse',
	type    => Padre::Constant::BOOLEAN,
	store   => Padre::Constant::HUMAN,
	default => 0,
	restart => 1,
	help    => _T('Enable or disable the Run with Devel::TraceUse if it is installed. ')
		. _T('This requires an installed Devel::TraceUse and a Padre restart'),
);

# Specify Devel::TraceUse options for experimental Run with Devel::TraceUse support
setting(
	name    => 'feature_devel_traceuse_options',
	type    => Padre::Constant::ASCII,
	store   => Padre::Constant::HUMAN,
	default => '',
	help    => _T(q{Specify Devel::TraceUse options. 'feature_devel_traceuse' must be enabled.}),
);

# Toggle syntax checker annotations in editor
setting(
	name    => 'feature_syntax_check_annotations',
	type    => Padre::Constant::BOOLEAN,
	store   => Padre::Constant::HUMAN,
	default => 1,
	restart => 1,
	help    => _T('Enable syntax checker annotations in the editor')
);

# Toggle document differences feature
setting(
	name    => 'feature_document_diffs',
	type    => Padre::Constant::BOOLEAN,
	store   => Padre::Constant::HUMAN,
	default => 1,
	restart => 1,
	help    => _T('Enable document differences feature')
);

# Toggle version control system (VCS) support
setting(
	name    => 'feature_vcs_support',
	type    => Padre::Constant::BOOLEAN,
	store   => Padre::Constant::HUMAN,
	default => 1,
	restart => 1,
	help    => _T('Enable version control system support')
);

# Toggle MetaCPAN CPAN explorer panel
setting(
	name    => 'feature_cpan',
	type    => Padre::Constant::BOOLEAN,
	store   => Padre::Constant::HUMAN,
	default => 1,
	restart => 1,
	help    => _T('Enable the CPAN Explorer, powered by MetaCPAN'),
);

# Toggle Diff window feature
setting(
	name    => 'feature_diff_window',
	type    => Padre::Constant::BOOLEAN,
	store   => Padre::Constant::HUMAN,
	default => 0,
	restart => 1,
	help    => _T('Toggle Diff window feature that compares two buffers graphically'),
);

# Experimental command line interface
setting(
	name    => 'feature_command',
	type    => Padre::Constant::BOOLEAN,
	store   => Padre::Constant::HUMAN,
	default => 0,
	restart => 1,
	help    => _T('Enable the experimental command line interface'),
);

# Toggle Perl 6 auto detection
setting(
	name    => 'lang_perl6_auto_detection',
	type    => Padre::Constant::BOOLEAN,
	store   => Padre::Constant::HUMAN,
	default => 0,
	help    => _T('Toggle Perl 6 auto detection in Perl 5 files')
);

# Window menu list shorten common path
setting(
	name    => 'window_list_shorten_path',
	type    => Padre::Constant::ASCII,
	store   => Padre::Constant::HUMAN,
	default => 1,
);

# Perl 5 Beginner Mode
setting(
	name    => 'lang_perl5_beginner',
	type    => Padre::Constant::BOOLEAN,
	store   => Padre::Constant::HUMAN,
	default => 1,
);

setting(
	name    => 'lang_perl5_beginner_split',
	type    => Padre::Constant::BOOLEAN,
	store   => Padre::Constant::HOST,
	default => 1,
);

setting(
	name    => 'lang_perl5_beginner_warning',
	type    => Padre::Constant::BOOLEAN,
	store   => Padre::Constant::HOST,
	default => 1,
);

setting(
	name    => 'lang_perl5_beginner_map',
	type    => Padre::Constant::BOOLEAN,
	store   => Padre::Constant::HOST,
	default => 1,
);

setting(
	name    => 'lang_perl5_beginner_debugger',
	type    => Padre::Constant::BOOLEAN,
	store   => Padre::Constant::HOST,
	default => 1,
);

setting(
	name    => 'lang_perl5_beginner_chomp',
	type    => Padre::Constant::BOOLEAN,
	store   => Padre::Constant::HOST,
	default => 1,
);

setting(
	name    => 'lang_perl5_beginner_map2',
	type    => Padre::Constant::BOOLEAN,
	store   => Padre::Constant::HOST,
	default => 1,
);

setting(
	name    => 'lang_perl5_beginner_perl6',
	type    => Padre::Constant::BOOLEAN,
	store   => Padre::Constant::HOST,
	default => 1,
);

setting(
	name    => 'lang_perl5_beginner_ifsetvar',
	type    => Padre::Constant::BOOLEAN,
	store   => Padre::Constant::HOST,
	default => 1,
);

setting(
	name    => 'lang_perl5_beginner_pipeopen',
	type    => Padre::Constant::BOOLEAN,
	store   => Padre::Constant::HOST,
	default => 1,
);

setting(
	name    => 'lang_perl5_beginner_pipe2open',
	type    => Padre::Constant::BOOLEAN,
	store   => Padre::Constant::HOST,
	default => 1,
);

setting(
	name    => 'lang_perl5_beginner_regexq',
	type    => Padre::Constant::BOOLEAN,
	store   => Padre::Constant::HOST,
	default => 1,
);

setting(
	name    => 'lang_perl5_beginner_elseif',
	type    => Padre::Constant::BOOLEAN,
	store   => Padre::Constant::HOST,
	default => 1,
);

setting(
	name    => 'lang_perl5_beginner_close',
	type    => Padre::Constant::BOOLEAN,
	store   => Padre::Constant::HOST,
	default => 1,
);

# Padre::File options

#   ::HTTP
setting(
	name    => 'file_http_timeout',
	type    => Padre::Constant::ASCII,
	store   => Padre::Constant::HUMAN,
	default => 30,
);

#   ::FTP
setting(
	name    => 'file_ftp_timeout',
	type    => Padre::Constant::ASCII,
	store   => Padre::Constant::HUMAN,
	default => 30,
);

setting(
	name    => 'file_ftp_passive',
	type    => Padre::Constant::BOOLEAN,
	store   => Padre::Constant::HUMAN,
	default => 1,
);

#################################################
# Version control system (VCS)
#################################################

# Show normal objects?
setting(
	name    => 'vcs_normal_shown',
	type    => Padre::Constant::BOOLEAN,
	store   => Padre::Constant::HUMAN,
	default => 0,
);

# Show unversioned objects?
setting(
	name    => 'vcs_unversioned_shown',
	type    => Padre::Constant::BOOLEAN,
	store   => Padre::Constant::HUMAN,
	default => 0,
);

# Show ignored objects?
setting(
	name    => 'vcs_ignored_shown',
	type    => Padre::Constant::BOOLEAN,
	store   => Padre::Constant::HUMAN,
	default => 0,
);

# Toggle experimental VCS command bar
setting(
	name    => 'vcs_enable_command_bar',
	type    => Padre::Constant::BOOLEAN,
	store   => Padre::Constant::HUMAN,
	default => 0,
);

# Non-preference settings
setting(
	name    => 'session_autosave',
	type    => Padre::Constant::BOOLEAN,
	store   => Padre::Constant::HUMAN,
	default => 0,
);

# The "config_" namespace is for the locations of configuration content
# outside of the configuration API, and the paths to other non-Padre config
# files for various external tools (usually so that projects can define the
# the location of their project-specific policies).

# The location of the server that will share config data between installs
setting(
	name    => 'config_sync_server',
	type    => Padre::Constant::ASCII,
	store   => Padre::Constant::HOST,
	default => 'http://sync.perlide.org/',
);

setting(
	name    => 'config_sync_username',
	type    => Padre::Constant::ASCII,
	store   => Padre::Constant::HOST,
	default => '',
);

setting(
	name    => 'config_sync_password',
	type    => Padre::Constant::ASCII,
	store   => Padre::Constant::HOST,
	default => '',
);

# Location of the Perl::Tidy RC file, if a project wants to set a custom one.
# When set to false, allow Perl::Tidy to use its own default config location.
# Load this from the project backend in preference to the host one, so that
# projects can set their own project-specific config file.
setting(
	name    => 'config_perltidy',
	type    => Padre::Constant::PATH,
	store   => Padre::Constant::PROJECT,
	default => '',
);

# Location of the Perl::Critic RC file, if a project wants to set a custom
# one. When set to false, allow Perl::Critic to use its own default config
# location. Load this from the project backend in preference to the host one,
# so that projects can set their own project-specific config file.
setting(
	name    => 'config_perlcritic',
	type    => Padre::Constant::PATH,
	store   => Padre::Constant::PROJECT,
	default => '',
);


# Support for Module::Starter
setting(
	name    => 'module_starter_directory',
	type    => Padre::Constant::ASCII,
	store   => Padre::Constant::HUMAN,
	default => '',
);
setting(
	name    => 'module_starter_builder',
	type    => Padre::Constant::ASCII,
	store   => Padre::Constant::HUMAN,
	default => 'Module::Install',
	options => {
		'ExtUtils::MakeMaker' => 'ExtUtils::MakeMaker',
		'Module::Build'       => 'Module::Build',
		'Module::Install'     => 'Module::Install',
	},
);
setting(
	name    => 'module_starter_license',
	type    => Padre::Constant::ASCII,
	store   => Padre::Constant::HUMAN,
	default => 'perl',

	# licenses list taken from
	# http://search.cpan.org/dist/Module-Build/lib/Module/Build/API.pod
	# even though it should be in http://module-build.sourceforge.net/META-spec.html
	# and we should fetch it from Module::Start or maybe Software::License.
	# (but don't load them in this module, it adds bloat)
	options => {
		'apache'       => _T('Apache License'),
		#'artistic'     => _T('Artistic License 1.0'),
		#'artistic_2'   => _T('Artistic License 2.0'),
		'bsd'          => _T('Revised BSD License'),
		'gpl'          => _T('GPL 2 or later'),
		'lgpl'         => _T('LGPL 2.1 or later'),
		'mit'          => _T('MIT License'),
		#'mozilla'      => _T('Mozilla Public License'),
		#'open_source'  => _T('Other Open Source'),
		'perl'         => _T('The same as Perl itself'),
		#'unrestricted' => _T('Other Unrestricted'),
		#'restrictive'  => _T('Proprietary/Restrictive'),
	},
);


1;

__END__

=pod

=head1 ADDING CONFIGURATION OPTIONS

Add a "setting()" - call to the correct section of this file.

The setting() call initially creates the option and defines some
metadata like the type of the option, it's living place and the
default value which should be used until the user configures
a own value.

=head1 COPYRIGHT & LICENSE

Copyright 2008-2013 The Padre development team as listed in Padre.pm.

This program is free software; you can redistribute it and/or modify it under the
same terms as Perl 5 itself.

=cut

# Copyright 2008-2013 The Padre development team as listed in Padre.pm.
# LICENSE
# This program is free software; you can redistribute it and/or
# modify it under the same terms as Perl 5 itself.