diff options
-rw-r--r-- | Auth.pm | 50 | ||||
-rw-r--r-- | Category.pm | 132 | ||||
-rw-r--r-- | ConfigReader.pm | 111 | ||||
-rw-r--r-- | MainDisplay.pm | 330 | ||||
-rw-r--r-- | Module.pm | 57 | ||||
-rw-r--r-- | SettingsReader.pm | 44 | ||||
-rwxr-xr-x | apanel.pl | 76 | ||||
-rw-r--r-- | categories.conf | 36 | ||||
-rw-r--r-- | extras/README | 10 | ||||
-rw-r--r-- | extras/org.freedesktop.policykit.pkexec.policy | 22 | ||||
-rw-r--r-- | images/logo_mageia.png | bin | 0 -> 2425 bytes | |||
-rw-r--r-- | images/mageia.png | bin | 0 -> 1788 bytes | |||
-rw-r--r-- | images/quit.png | bin | 0 -> 2880 bytes | |||
-rw-r--r-- | modules/test.cpp | 137 | ||||
-rw-r--r-- | settings.conf | 9 |
15 files changed, 1014 insertions, 0 deletions
diff --git a/Auth.pm b/Auth.pm new file mode 100644 index 00000000..c55e0678 --- /dev/null +++ b/Auth.pm @@ -0,0 +1,50 @@ +# Copyright 2012 Matteo Pasotti +# +# This file is part of mcc2 +# +# mcc2 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. +# +# mcc2 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 mcc2. If not, see <http://www.gnu.org/licenses/>. + +package Auth; + +require Exporter; +@ISA = qw(Exporter); +@EXPORT = qw(require_root_capability + ask_for_authentication); + +use strict; +use warnings; +use diagnostics; +use Data::Dumper; + + +sub require_root_capability { + return 0 if(!$>); + return 1; +} + +sub ask_for_authentication { + my @args = @ARGV; + my $command = wrap_command($0); + unshift(@args, $command->[2]); + exec { $command->[0] } $command->[1], @args or die ("command %s missing", $command->[0]); + die "You must be root to run this program" if $>; +} + +sub wrap_command { + my $currenv = "env"; + my $wrapper = "pkexec"; + my $app = $0; + my $command = [$wrapper, $currenv, $app]; + ($command); +} diff --git a/Category.pm b/Category.pm new file mode 100644 index 00000000..6e4a58d4 --- /dev/null +++ b/Category.pm @@ -0,0 +1,132 @@ +# Copyright 2012 Steven Tucker +# +# This file is part of AdminPanel +# +# AdminPanel 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. +# +# AdminPanel 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 AdminPanel. If not, see <http://www.gnu.org/licenses/>. + + +#Class Category +package Category; + +use strict; +use warnings; +use diagnostics; +use yui; + +## Can only add the config file data at constructor +## The Gui elements are added in setupGui inside MainDisplay +sub new { + my ($class, $newName, $newIcon) = @_; + my $self = { + my $name = 0, + my $button = 0, + my $icon = 0, + my $modules = 0 + }; + bless $self, 'Category'; + + $self->{name} = $newName; + $self->{icon} = $newIcon; + + return $self; +} + +## Add a new module to the list +sub loadModule { + my ($self, $module) = @_; + + push ( @{$self->{modules}}, $module ); + +} + +## Create and add buttons for each module +sub addButtons { + my($self, $pane, $factory) = @_; + my $count = 0; + my $tmpButton; + my $currLayout = 0; + $factory->createVSpacing($pane, 2); + foreach my $mod (@{$self->{modules}}) { + if(($count % 2) != 1) + { + $currLayout = $factory->createHBox($pane); + $factory->createHStretch($currLayout); + } + $count++; + $tmpButton = $factory->createPushButton($currLayout, + $mod->{name} + ); + $mod->setButton($tmpButton); + $tmpButton->setLabel($mod->{name}); + $tmpButton->setIcon($mod->{icon}); + $factory->createHStretch($currLayout); + if(($count % 2) != 1) + { + $factory->createVSpacing($pane, 2); + } + } + $factory->createVStretch($pane); +} + +## Delete the module buttons +sub removeButtons { + my($self) = @_; + + for(@{$self->{modules}}) { + $_->removeButton(); + } +} + +sub setIcon { + my($self) = @_; + + $self->{button}->setIcon($self->{icon}); +} + +1; +__END__ + +=pod + +=head1 NAME + + Category - add new category to window + +=head1 SYNOPSIS + + $category = new Category('Category Name'); + + +=head1 USAGE + + my $display = new MainDisplay(); + + my $category = new Category('Network'); + $display->loadCategory($category); + + $display->start(); + +=head1 FUNCTIONS + +=head2 new (name) + + Constructor: creates a new category named Name + + $category = new Category('Name'); + +=head3 name (String) + + The name of the category + +=cut diff --git a/ConfigReader.pm b/ConfigReader.pm new file mode 100644 index 00000000..22d3b495 --- /dev/null +++ b/ConfigReader.pm @@ -0,0 +1,111 @@ +# Copyright 2012 Steven Tucker +# +# This file is part of AdminPanel +# +# AdminPanel 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. +# +# AdminPanel 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 AdminPanel. If not, see <http://www.gnu.org/licenses/>. + + +#Class ConfigReader +package ConfigReader; + +use strict; +use warnings; +use diagnostics; +use XML::Simple; +use Data::Dumper; + +sub new { + my ($class, $fileName) = @_; + + my $self = { + my $data = 0, + my $catLen = 0, + my $currCat = 0, + my $modLen = 0, + my $currMod = 0, + my $placeHolder = 0 + }; + bless $self, 'ConfigReader'; + + my $xml = new XML::Simple (KeyAttr=>[]); + $self->{data} = $xml->XMLin($fileName); + $self->{catLen} = scalar(@{$self->{data}->{category}}); + $self->{currCat} = -1; + + if(ref(@{$self->{data}->{category}}[0]->{module}) eq "ARRAY") { + $self->{modLen} = scalar(@{@{$self->{data}->{category}}[0]->{module}}); + } else { + $self->{modLen} = 1; + } + $self->{currMod} = -1; + + return $self; +} + +sub hasNextCat { + my ($self) = @_; + + if($self->{currCat} + 1 >= $self->{catLen}) { + return 0; + } + return 1; +} + +sub getNextCat { + my ($self) = @_; + + $self->{currCat}++; + if($self->{currCat} >= $self->{catLen}) { + return 0; + } + + # Reset the Module Count and Mod length for new Category + $self->{currMod} = -1; + if(ref(@{$self->{data}->{category}}[$self->{currCat}]->{module}) eq "ARRAY") { + $self->{modLen} = scalar(@{@{$self->{data}->{category}}[$self->{currCat}]->{module}}); + } else { + $self->{modLen} = 1; + } + + my $tmp = @{$self->{data}->{category}}[$self->{currCat}]; + + return $tmp; +} + +sub hasNextMod { + my ($self) = @_; + + if($self->{currMod} + 1 >= $self->{modLen}) { + return 0; + } + return 1; +} + +sub getNextMod { + my ($self) = @_; + + my $ret = 0; + + $self->{currMod}++; + + if($self->{modLen} == 1) { + $ret = @{$self->{data}->{category}}[$self->{currCat}]->{module}; + } else { + $ret = @{@{$self->{data}->{category} }[$self->{currCat}]->{module}}[$self->{currMod}]; + } + + return $ret; +} + +1; diff --git a/MainDisplay.pm b/MainDisplay.pm new file mode 100644 index 00000000..5e42641c --- /dev/null +++ b/MainDisplay.pm @@ -0,0 +1,330 @@ +# Copyright 2012 Steven Tucker +# +# This file is part of AdminPanel +# +# AdminPanel 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. +# +# AdminPanel 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 AdminPanel. If not, see <http://www.gnu.org/licenses/>. + + +#Class MainDisplay +package MainDisplay; + +use strict; +use warnings; +use diagnostics; +use SettingsReader; +use ConfigReader; +use Category; +use Module; +use Data::Dumper; +use yui; + +sub new { + + my $self = { + my $categories = 0, + my $event = 0, + my $factory = 0, + my $mainWin = 0, + my $mainLayout = 0, + my $menuLayout = 0, + my $menus = { + my $file = 0, + my $help = 0 + }, + my $layout = 0, + my $leftPane = 0, + my $rightPane = 0, + my $currCategory = 0, + my $confDir = 0, + my $title = 0, + my $settings = 0, + my $exitButton = 0, +# my $justToGetRidOfERROR = 0, + my $replacePoint = 0 + }; + bless $self, 'MainDisplay'; + +## Default values + $self->{name} = "Administration panel"; + $self->{categories} = []; + $self->{confDir} = "/etc/apanel", + $self->{title} = "apanel", + $self->setupGui(); + + return $self; +} + +## Begin the program event loop +sub start { + my ($self) = shift; + my $reqExit = 0; + + ##Default category selection + $self->{currCategory} = @{$self->{categories}}[0]; + $self->{currCategory}->addButtons($self->{rightPane}, $self->{factory}); + $self->{rightPaneFrame}->setLabel($self->{currCategory}->{name}); + $self->{factory}->createSpacing($self->{rightPane}, 1, 1, 1.0 ); + + my $launch = 0; + while(!$launch) { + + ## Grab Event + $self->{event} = $self->{mainWin}->waitForEvent(); + + ## Check for window close + if ($self->{event}->eventType() == $yui::YEvent::CancelEvent) + { + last; + } + +## why i can't test item() with $self->{menus}->{file}[0]? + ## Check for Exit button push or menu + if($self->{event}->widget() == $self->{exitButton} || + ($self->{event}->item() && ($self->{event}->item()->label() eq $self->{menus}->{file}[0]->label() ))) { + last; + }; + + ## Discover if a menu button was selected. + ## If menu button selected, set right panel to display + ## selected Category Modules + for(@{$self->{categories}}){ + if( $_->{button} == $self->{event}->widget() ){ + + ## Menu item selected, set right pane + $self->{mainWin}->startMultipleChanges(); + ## Remove existing modules + $self->{replacePoint}->deleteChildren(); + $self->{rightPane} = $self->{factory}->createVBox($self->{replacePoint}); + + ## Change Current Category to the selected one + $self->{currCategory} = $_; + ## Add new Module Buttons to Right Pane + $self->{currCategory}->addButtons($self->{rightPane}, $self->{factory}); + $self->{rightPaneFrame}->setLabel($self->{currCategory}->{name}); + $self->{factory}->createSpacing($self->{rightPane}, 1, 1, 1.0 ); + $self->{replacePoint}->showChild(); + $self->{mainWin}->recalcLayout(); + $self->{mainWin}->doneMultipleChanges(); + + last; + } + } + + ## Check if event is from current Category View + ## If icon click, launch the Module + for(@{$self->{currCategory}->{modules}}) { + if( $_->{button} == $self->{event}->widget() ){ + $launch = $_->{launch}; + last; + } + } + } + + return $launch; +} + +sub destroy { + my ($self) = shift; + $self->{mainWin}->destroy(); +} + +sub setupGui { + my ($self) = shift; + + my $cmdline = new yui::YCommandLine; + +## TODO add parameter check + my $pos = $cmdline->find("--name"); + if ($pos > 0) + { + $self->{title} = $cmdline->arg($pos+1); + } + $pos = $cmdline->find("--conf_dir"); + if ($pos > 0) + { + $self->{confDir} = $cmdline->arg($pos+1); + } + else + { + $self->{confDir} = "/etc/$self->{title}"; + } +# print "name = ".$self->{title}."\n"; +# print "conf dir = ".$self->{confDir}."\n"; + + $self->loadSettings(); + yui::YUILog::setLogFileName($self->{settings}->{log}); + $self->{name} = $self->{settings}->{title}; + yui::YUI::app()->setApplicationTitle($self->{name}); + yui::YUI::app()->setApplicationIcon($self->{settings}->{icon}); + + $self->{factory} = yui::YUI::widgetFactory; + $self->{mainWin} = $self->{factory}->createMainDialog; +#print "Title: ".yui::YUI::app()->applicationTitle()."\n"; + + $self->{mainLayout} = $self->{factory}->createVBox($self->{mainWin}); + $self->{menuLayout} = $self->{factory}->createHBox($self->{mainLayout}); + + ## Menu file + ## TODO i8n + my $align = $self->{factory}->createAlignment($self->{menuLayout}, 1, 0); + my $menu = $self->{factory}->createMenuButton($align, "File"); + my $item = new yui::YMenuItem("Exit"); + + push(@{$self->{menus}->{file}}, $item); + $menu->addItem($item); + $menu->rebuildMenuTree(); + + $align = $self->{factory}->createAlignment($self->{menuLayout}, 2, 0); + $menu = $self->{factory}->createMenuButton($align, "Help"); + $item = new yui::YMenuItem("Help"); + $menu->addItem($item); + push(@{$self->{menus}->{help}}, $item); + $item = new yui::YMenuItem("About"); + $menu->addItem($item); + push(@{$self->{menus}->{help}}, $item); + $menu->rebuildMenuTree(); + + $self->{layout} = $self->{factory}->createHBox($self->{mainLayout}); + + #create left Panel Frame no need to add a label for title + $self->{leftPaneFrame} = $self->{factory}->createFrame($self->{layout}, $self->{settings}->{category_title}); + #create right Panel Frame no need to add a label for title (use setLabel when module changes) + $self->{rightPaneFrame} = $self->{factory}->createFrame($self->{layout}, ""); + #create replace point for dynamically created widgets + $self->{replacePoint} = $self->{factory}->createReplacePoint($self->{rightPaneFrame}); + + $self->{rightPane} = $self->{factory}->createVBox($self->{replacePoint}); + $self->{leftPane} = $self->{factory}->createVBox($self->{leftPaneFrame}); + + #logo from settings + my $logo = $self->{factory}->createImage($self->{leftPane}, $self->{settings}->{logo}); + $logo->setAutoScale(1); + + $self->{leftPaneFrame}->setWeight(0, 25); + $self->{rightPaneFrame}->setWeight(0, 75); + + $self->loadCategories(); + $self->{factory}->createVStretch($self->{leftPane}); + + $self->{exitButton} = $self->{factory}->createPushButton($self->{leftPane}, "Exit"); + $self->{exitButton}->setIcon("$self->{settings}->{images_dir}/quit.png"); + $self->{exitButton}->setStretchable(0, 1); +# $self->{exitButton}->setStretchable(1, 1); +} + +## adpanel settings +sub loadSettings { + my ($self) = @_; +# configuration file name + my $fileName = "$self->{confDir}/settings.conf"; + $self->{settings} = new SettingsReader($fileName); +} + +sub loadCategory { + my ($self, $category) = @_; + + push ( @{$self->{categories}}, $category ); + + @{$self->{categories}}[-1]->{button} = $self->{factory}->createPushButton( + $self->{leftPane}, + $self->{categories}[-1]->{name} + ); + @{$self->{categories}}[-1]->setIcon(); + + @{$self->{categories}}[-1]->{button}->setStretchable(0, 1); +# @{$self->{categories}}[-1]->{button}->setStretchable(1, 1); +} + +sub loadCategories { + my ($self) = @_; + +# configuration file name + my $fileName = "$self->{confDir}/categories.conf"; + + my $inFile = new ConfigReader($fileName); + my $tmpCat; + my $tmp; + my $hasNextCat = $inFile->hasNextCat(); + while( $hasNextCat ) { + $tmp = $inFile->getNextCat(); + $tmpCat = new Category($tmp->{title}, $tmp->{icon}); + $self->loadCategory($tmpCat); + $hasNextCat = $inFile->hasNextCat(); + $self->{currCategory} = $tmpCat; + + my $hasNextMod = $inFile->hasNextMod(); + while( $hasNextMod ) { + $tmp = $inFile->getNextMod(); + my $tmpMod = new Module($tmp->{title}, + $tmp->{icon}, + $tmp->{launcher} + ); + $self->{currCategory}->loadModule($tmpMod); + + $hasNextMod = $inFile->hasNextMod(); + } + } + undef($tmpCat); +} + +sub menuEventIndex { + my ($self) = shift; + + my $index = -1; + + for(my $i = 0; $i < scalar(@{$self->{categories}} ); ++$i) + { + print "Current Index = ".$index."\n"; + if($self->{event}->widget() == @{$self->{categories}}[$i]->{button}) + { + $index = $i; + print "Index found is : ".$index; + last; + } + } + return $index; +} + +1; + +=pod + +=head1 NAME + + MainDisplay - class for the main window + +=head1 SYNOPSIS + + $mainDisplay = new MainDisplay(); + +=head1 METHODS + +=head2 start + + contains the main loop of the application + where we can check for events + +=head2 setupGui + + creates a popupDialog using a YUI::WidgetFactory + and then populate this dialog with some components + +=head2 loadCategory + + creates a new button representing a category + +=head3 category (String) + +=cut + diff --git a/Module.pm b/Module.pm new file mode 100644 index 00000000..990de15f --- /dev/null +++ b/Module.pm @@ -0,0 +1,57 @@ +#!/usr/bin/perl + +# Copyright 2012 Steven Tucker +# +# This file is part of AdminPanel +# +# AdminPanel 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. +# +# AdminPanel 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 AdminPanel. If not, see <http://www.gnu.org/licenses/>. + + +#Class Module +package Module; + +use strict; +use warnings; +use diagnostics; +use yui; + +sub new { + my ($class, $newName, $newIcon, $newLaunch) = @_; + my $self = { + my $name = 0, + my $icon = 0, + my $launch = 0, + my $button = 0 + }; + bless $self, 'Module'; + + $self->{name} = $newName; + $self->{icon} = $newIcon; + $self->{launch} = $newLaunch; + + return $self; +} + +sub setButton { + my ($self, $button) = @_; + $self->{button} = $button; +} + +sub removeButton { + my($self) = @_; + + undef($self->{button}); +} + +1; diff --git a/SettingsReader.pm b/SettingsReader.pm new file mode 100644 index 00000000..dddcdd4e --- /dev/null +++ b/SettingsReader.pm @@ -0,0 +1,44 @@ +# Copyright 2012 Angelo Naselli +# +# This file is part of AdminPanel +# +# AdminPanel 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. +# +# AdminPanel 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 AdminPanel. If not, see <http://www.gnu.org/licenses/>. + + +#Class SettingsReader +package SettingsReader; + +use strict; +use warnings; +use diagnostics; +use XML::Simple; +use Data::Dumper; + +sub new { + my ($class, $fileName) = @_; + + my $self = { + my $settings = 0, + my $justToGetRidOfERROR = 0 + }; + bless $self, 'SettingsReader'; + + my $xml = new XML::Simple (KeyAttr=>[]); + $self->{settings} = $xml->XMLin($fileName); + + return $self->{settings}; +} + + +1; diff --git a/apanel.pl b/apanel.pl new file mode 100755 index 00000000..6e50f2cb --- /dev/null +++ b/apanel.pl @@ -0,0 +1,76 @@ +#!/usr/bin/perl + +# Copyright 2012 Steven Tucker +# +# This file is part of AdminPanel +# +# AdminPanel 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. +# +# AdminPanel 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 AdminPanel. If not, see <http://www.gnu.org/licenses/>. + +use strict; +use warnings; +use diagnostics; +use FindBin; +use lib "$FindBin::RealBin"; +use Getopt::Long; +use Auth; +use MainDisplay; +use yui; + +my $help=0; + +my $result = GetOptions ("help" => \$help); + +usage() if($help); + +ask_for_authentication() if(require_root_capability()); + +my $mainWin = new MainDisplay(); +my $launch = $mainWin->start(); + +while($launch) +{ + $mainWin->destroy(); + undef($mainWin); + + my $err = yui::YUI::app()->runInTerminal("$launch --ncurses"); + if ($err == -1) + { + system($launch); + } + + $mainWin = new MainDisplay(); + $launch = $mainWin->start(); +} + +$mainWin->destroy(); +undef($mainWin); + +sub usage { + print "\n"; + print "Usage apanel [options...]\n\n"; + print "Options:\n"; + print "\t--help | -h print this help\n"; + print "\t--name string specify the window title of the administration panel\n"; + print "\t--conf_dir path specify the settings.conf file directory\n"; + print "\n"; + exit(0); +} + +=pod + +=head1 main + + main launcher + +=cut diff --git a/categories.conf b/categories.conf new file mode 100644 index 00000000..256fc9e9 --- /dev/null +++ b/categories.conf @@ -0,0 +1,36 @@ +<?xml version='1.0'?> +<categories> + <category> + <title>Software Management</title> + <icon>/usr/share/icons/applications_section.png</icon> + <module> + <title>Add Software</title> + <launcher>./modules/test</launcher> + <icon>/usr/share/icons/mageiaupdate.png</icon> + </module> + <module> + <title>Remove Software</title> + <launcher>./modules/test</launcher> + <icon>/usr/share/icons/edit-urpm-sources.png</icon> + </module> + <module> + <title>Update Software</title> + <launcher>./modules/test</launcher> + <icon>/usr/share/icons/mageiaupdate.png</icon> + </module> + <module> + <title>Edit Sources</title> + <launcher>./modules/test</launcher> + <icon>/usr/share/icons/edit-urpm-sources.png</icon> + </module> + </category> + <category> + <title>Hardware</title> + <icon>/usr/share/icons/configuration_section.png</icon> + <module> + <title>CD/DVD Config</title> + <launcher>./modules/test</launcher> + <icon>./modules/pythonMod</icon> + </module> + </category> +</categories> diff --git a/extras/README b/extras/README new file mode 100644 index 00000000..52650fca --- /dev/null +++ b/extras/README @@ -0,0 +1,10 @@ +Please copy extras/org.freedesktop.policykit.pkexec.policy to /usr/share/polkit-1/actions/org.freedesktop.policykit.pkexec.policy +to make apanel be usable through policykit (mcc is currently using pam, a bit more complicated compared to polkit). + +After that you have to make a symbolic link to apanel.pl into /usr/bin/ (i.e. /usr/bin/apanel.pl) and make your local apanel.pl script executable (chmod +x apanel.pl). + +This settings will be automatically handled at rpm installation time in future/production. + +TODO: +- support to pam (wip) +- add testing/develop exceptions (avoid to insert password at develop time) diff --git a/extras/org.freedesktop.policykit.pkexec.policy b/extras/org.freedesktop.policykit.pkexec.policy new file mode 100644 index 00000000..b110dba6 --- /dev/null +++ b/extras/org.freedesktop.policykit.pkexec.policy @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE policyconfig PUBLIC + "-//freedesktop//DTD PolicyKit Policy Configuration 1.0//EN" + "http://www.freedesktop.org/standards/PolicyKit/1/policyconfig.dtd"> +<policyconfig> + + <vendor>APanel PolicyKit Configuration</vendor> + <vendor_url>http://hal.freedesktop.org/docs/PolicyKit/</vendor_url> + + <action id="org.freedesktop.policykit.pkexec.run-apanel"> + <description>Allow APanel GUI</description> + <message>Authentication is required to run the program apanel (user=$(user), program=$(program), command_line=$(command_line))</message> + <defaults> + <allow_any>no</allow_any> + <allow_inactive>no</allow_inactive> + <allow_active>auth_admin</allow_active> + </defaults> + <annotate key="org.freedesktop.policykit.exec.path">/usr/bin/apanel.pl</annotate> + <annotate key="org.freedesktop.policykit.exec.allow_gui">TRUE</annotate> + </action> + +</policyconfig> diff --git a/images/logo_mageia.png b/images/logo_mageia.png Binary files differnew file mode 100644 index 00000000..32fe51c3 --- /dev/null +++ b/images/logo_mageia.png diff --git a/images/mageia.png b/images/mageia.png Binary files differnew file mode 100644 index 00000000..6769fda3 --- /dev/null +++ b/images/mageia.png diff --git a/images/quit.png b/images/quit.png Binary files differnew file mode 100644 index 00000000..322c187e --- /dev/null +++ b/images/quit.png diff --git a/modules/test.cpp b/modules/test.cpp new file mode 100644 index 00000000..6f3178ef --- /dev/null +++ b/modules/test.cpp @@ -0,0 +1,137 @@ +// Trivial libyui example. +// +// Compile with: +// +// g++ -I/usr/include/yui -lyui test.cpp -o test +// +#include "YUI.h" +#include "YApplication.h" +#include "YWidgetFactory.h" +#include "YDialog.h" +#include "YPushButton.h" +#include "YLayoutBox.h" +#include "YReplacePoint.h" +#include "YEvent.h" +#include "YFrame.h" +#include <vector> + +int main( int argc, char **argv ) +{ + YUI::app()->setApplicationTitle("Test module"); + YUI::app()->setApplicationIcon("/usr/share/icons/mageia.png"); + + YDialog * dialog = YUI::widgetFactory()->createPopupDialog(); + YFrame* frame = YUI::widgetFactory()->createFrame(dialog, "Test frame"); + YLayoutBox * hbox = YUI::widgetFactory()->createHBox(frame); + YFrame* lframe = YUI::widgetFactory()->createFrame(hbox, "Left frame"); + YFrame* rframe = YUI::widgetFactory()->createFrame(hbox, "Right frame"); + // here we change the widget + YReplacePoint* replacePoint = YUI::widgetFactory()->createReplacePoint(rframe); + + YLayoutBox * vbox_rframe = YUI::widgetFactory()->createVBox( replacePoint ); + YLayoutBox * vbox = YUI::widgetFactory()->createVBox( lframe ); +// vbox->setSize( 1000, 1000 ); + lframe->setWeight(YD_HORIZ, 25); + rframe->setWeight(YD_HORIZ, 75); + YUI::widgetFactory()->createLabel ( vbox, "Hello, World!" ); + YPushButton* addButton = YUI::widgetFactory()->createPushButton( vbox, "Add Button" ); + YPushButton* removeButton = YUI::widgetFactory()->createPushButton( vbox, "Remove Button" ); + YPushButton* exitButton = YUI::widgetFactory()->createPushButton( vbox, "&Exit" ); + YUI::widgetFactory()->createSpacing( vbox, YD_VERT, true, 1.0 ); + + //YPushButton* testButton = YUI::widgetFactory()->createPushButton( vbox, "&Cannot be added" ); + //testButton->hide(); <-- Angelo, I could not see this call in the api + + int bnum = 0; + std::vector<YPushButton*>buttons; + + for (;;) + { + YEvent* event = dialog->waitForEvent(); + // Check for window close + if (event->eventType() == YEvent::CancelEvent) + { + break; + } + + // Check for Exit button push + if(event->widget() == (YWidget*)exitButton ) { + break; + }; + + if(event->widget() == (YWidget*)addButton ) { + if(bnum < 6) { + dialog->startMultipleChanges(); + replacePoint->deleteChildren(); + vbox_rframe = YUI::widgetFactory()->createVBox( replacePoint ); + bnum++; + buttons.clear(); + for (int i=0; i < bnum; ++i) + { + YPushButton* tmpB = YUI::widgetFactory()->createPushButton( vbox_rframe, "Delete Me" ); + buttons.push_back(tmpB); + } + replacePoint->showChild(); + dialog->recalcLayout(); + dialog->doneMultipleChanges(); + } + else if (bnum == 6) + { + dialog->startMultipleChanges(); + replacePoint->deleteChildren(); + vbox_rframe = YUI::widgetFactory()->createVBox( replacePoint ); + buttons.clear(); + for (int i=0; i < bnum; ++i) + { + YPushButton* tmpB = YUI::widgetFactory()->createPushButton( vbox_rframe, "Delete Me" ); + buttons.push_back(tmpB); + } + YUI::widgetFactory()->createSpacing( vbox_rframe, YD_VERT, false, 1.0 ); + replacePoint->showChild(); + dialog->recalcLayout(); + dialog->doneMultipleChanges(); + } + } + if(event->widget() == (YWidget*)removeButton ) { + if (bnum > 0) + { + dialog->startMultipleChanges(); + replacePoint->deleteChildren(); + vbox_rframe = YUI::widgetFactory()->createVBox( replacePoint ); + bnum--; + buttons.clear(); + for (int i=0; i < bnum; ++i) + { + YPushButton* tmpB = YUI::widgetFactory()->createPushButton( vbox_rframe, "Delete Me" ); + buttons.push_back(tmpB); + } + replacePoint->showChild(); + dialog->recalcLayout(); + dialog->doneMultipleChanges(); + } + } + + + for(int i = 0; i < bnum; ++i) + { + if (event->widget() == (YWidget*)buttons[i]) { + dialog->startMultipleChanges(); + replacePoint->deleteChildren(); + vbox_rframe = YUI::widgetFactory()->createVBox( replacePoint ); + bnum--; + buttons.clear(); + for (int i=0; i < bnum; ++i) + { + YPushButton* tmpB = YUI::widgetFactory()->createPushButton( vbox_rframe, "Delete Me" ); + buttons.push_back(tmpB); + } + replacePoint->showChild(); + dialog->recalcLayout(); + dialog->doneMultipleChanges(); + break; + } + } + } + + dialog->destroy(); +} diff --git a/settings.conf b/settings.conf new file mode 100644 index 00000000..023f76a7 --- /dev/null +++ b/settings.conf @@ -0,0 +1,9 @@ +<?xml version='1.0'?> +<settings> + <title>Admin Panel</title> + <logo>images/logo_mageia.png</logo> + <icon>images/mageia.png</icon> + <log>/tmp/apanel.log</log> + <images_dir>/usr/share/icons</images_dir> + <category_title>Categories</category_title> +</settings> |