#!/usr/bin/perl
# perlpanel-item-edit - a Gtk2-Perl .desktop file editor
# This file is part of PerlPanel.
# 
# PerlPanel is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
# 
# PerlPanel is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
# 
# You should have received a copy of the GNU General Public License
# along with PerlPanel; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
#
# Copyright: (C) 2003-2004 Gavin Brown <gavin.brown@uk.com>
#
# $Id: perlpanel-item-edit,v 1.8 2004/02/17 12:30:31 jodrell Exp $
use Gtk2;
use strict;

Gtk2->init;

my $desktop_namespace = 'Desktop Entry';

my $PREFIX = (-e '@PREFIX@' ? '@PREFIX@' : $ENV{PWD});

my $namespace = '';
my $data = {};

my $file = $ARGV[0] or print STDERR "Usage: perlpanel-item-edit [FILE]\n" and exit 1;

open(FILE, $file) or print STDERR "Error opening '$file': $!\n" and exit 1;

my $line_no = 0;

while (<FILE>) {
	$line_no++;
	chomp;
	s/\;.*$//g;
	s/^\s*//g;
	s/\s*$//g;
	next if (/^$/);
	if (/^\[(.+?)\]$/) {
		$namespace = $1;
	} elsif (/^(.+)=(.*)$/) {
		if ($namespace eq '') {
			print STDERR "Parse error on line $line_no of '$file'\n" and exit 1;
		} else {
			$data->{$namespace}{$1} = $2;
		}
	} else {
			print STDERR "Parse error on line $line_no of '$file'\n" and exit 1;
	}
}

close(FILE);

my $language = $ENV{LANG} || 'en_US';
$language =~ s/\..*$//g;

if ($data->{$desktop_namespace}{Name} eq '') {
	$data->{$desktop_namespace}{Name} = $data->{$desktop_namespace}{"Name[$language]"}
}

if ($data->{$desktop_namespace}{Comment} eq '') {
	$data->{$desktop_namespace}{Comment} = $data->{$desktop_namespace}{"Comment[$language]"}
}

my $pristine = {
	Name	=> $data->{$desktop_namespace}{Name},
	Comment	=> $data->{$desktop_namespace}{Comment},
	Icon	=> $data->{$desktop_namespace}{Icon},
	Exec	=> $data->{$desktop_namespace}{Exec},
};

my $icon = Gtk2::Gdk::Pixbuf->new_from_file(sprintf('%s/share/pixmaps/perlpanel-icon.png', $PREFIX));

my $window = Gtk2::Dialog->new;
$window->signal_connect('delete_event', \&save);
$window->set_position('center');
$window->set_title('Launcher Properties');
$window->set_border_width(8);
$window->set_icon($icon);
$window->vbox->set_spacing(8);

my $table = Gtk2::Table->new(3, 4, 0);
$table->set_col_spacings(8);
$table->set_row_spacings(8);

my $name_entry = Gtk2::Entry->new;
$name_entry->set_text($data->{$desktop_namespace}{Name});
$name_entry->signal_connect('activate', \&save);
my $name_label = Gtk2::Label->new('Name:');
$name_label->set_alignment(1, 0.5);

my $comment_entry = Gtk2::Entry->new;
$comment_entry->set_text($data->{$desktop_namespace}{Comment});
$comment_entry->signal_connect('activate', \&save);
my $comment_label = Gtk2::Label->new('Comment:');
$comment_label->set_alignment(1, 0.5);

my $exec_entry = Gtk2::Entry->new;
$exec_entry->set_text($data->{$desktop_namespace}{Exec});
$exec_entry->signal_connect('activate', \&save);
my $exec_label = Gtk2::Label->new('Program:');
$exec_label->set_alignment(1, 0.5);

my $exec_button_label = Gtk2::Label->new('Browse...');
my $exec_button_image = Gtk2::Image->new_from_stock('gtk-open', 'menu');
my $exec_button_box = Gtk2::HBox->new;
$exec_button_box->pack_start($exec_button_image, 0, 0, 0);
$exec_button_box->pack_start($exec_button_label, 1, 1, 0);
my $exec_button = Gtk2::Button->new;
$exec_button->add($exec_button_box);
$exec_button->signal_connect('clicked', \&choose_program);

my $icon_label = Gtk2::Label->new('Icon:');
$icon_label->set_alignment(1, 0);
my $icon_image;
my $pixmap_path = sprintf('%s/share/pixmaps/%s', $PREFIX, $data->{$desktop_namespace}{Icon});
if (-e $data->{$desktop_namespace}{Icon}) {
	$icon_image = Gtk2::Image->new_from_file($data->{$desktop_namespace}{Icon});
} elsif (-e $pixmap_path) {
	$icon_image = Gtk2::Image->new_from_file($pixmap_path);
} else {
	$icon_image = Gtk2::Image->new_from_stock('gtk-missing-image', 'dialog');
}
my $icon_button = Gtk2::Button->new;
$icon_button->add($icon_image);
$icon_button->signal_connect('clicked', \&choose_icon);

$table->attach_defaults($name_label, 0, 1, 0, 1);
$table->attach_defaults($name_entry, 1, 3, 0, 1);

$table->attach_defaults($comment_label, 0, 1, 1, 2);
$table->attach_defaults($comment_entry, 1, 3, 1, 2);

$table->attach_defaults($exec_label, 0, 1, 2, 3);
$table->attach_defaults($exec_entry, 1, 2, 2, 3);
$table->attach_defaults($exec_button, 2, 3, 2, 3);

$table->attach_defaults($icon_label, 0, 1, 3, 4);
$table->attach($icon_button, 1, 2, 3, 4, 'shrink', 'shrink', 0, 0);

$window->vbox->pack_start($table, 1, 1, 0);

$window->add_button('gtk-ok', 0);

$window->signal_connect('response', sub { save() if $_[1] == 0 });

$window->show_all;

Gtk2->main;

sub choose_program {
	my $selector = Gtk2::FileSelection->new('Choose program');
	chomp(my $path = `which $data->{$desktop_namespace}{Exec}`);
	if (-e $path) {
		$selector->set_filename($path);
	} else {
		$selector->set_filename($data->{$desktop_namespace}{Exec});
	}
	$selector->ok_button->signal_connect('clicked', sub {
		$exec_entry->set_text($selector->get_filename);
		$selector->destroy;
	});
	$selector->cancel_button->signal_connect('clicked', sub {
		$selector->destroy;
	});
	$selector->show_all;
	return 1;
}

sub choose_icon {
	my $selector = Gtk2::FileSelection->new('Choose Icon');
	my $pixmap_path = sprintf('%s/share/pixmaps/%s', $PREFIX, $data->{$desktop_namespace}{Icon});
	if (-e $pixmap_path) {
		$selector->set_filename($pixmap_path);
	} else {
		$selector->set_filename($data->{$desktop_namespace}{Icon});
	}
	$selector->ok_button->signal_connect('clicked', sub {
		$data->{$desktop_namespace}{Icon} = $selector->get_filename;
		my $new_image = Gtk2::Image->new_from_file($data->{$desktop_namespace}{Icon});
		$new_image->show;
		$icon_button->remove($icon_button->child);
		$icon_button->add($new_image);
		$selector->destroy;
	});
	$selector->cancel_button->signal_connect('clicked', sub {
		$selector->destroy;
	});
	$selector->show_all;
	return 1;
}

sub save {
	$data->{$desktop_namespace}{Name} = $name_entry->get_text;
	$data->{$desktop_namespace}{Comment} = $comment_entry->get_text;
	$data->{$desktop_namespace}{Exec} = $exec_entry->get_text;

	my $changed = 0;
	my $empty = 0;
	foreach my $name (keys %{$pristine}) {
		$changed++ if ($pristine->{$name} ne $data->{$desktop_namespace}{$name});
		$empty++ if ($data->{$desktop_namespace}{$name} eq '');
	}

	exit if ($changed < 1 || $empty == scalar(keys %{$pristine}));

	open(FILE, ">$file") or print STDERR "Error opening '$file': $!\n" and exit 1;
	foreach my $namespace (keys %{$data}) {
		print FILE "[$namespace]\n";
		foreach my $name (keys %{$data->{$namespace}}) {
			print FILE "$name=$data->{$namespace}{$name}\n";
		}
	}
	close(FILE);
	exit;
}

exit;
