Author: jannis Date: 2006-07-19 20:26:19 +0000 (Wed, 19 Jul 2006) New Revision: 22486
Modified: installit/trunk/ChangeLog installit/trunk/backends/Source.py installit/trunk/components/packages.py installit/trunk/i18n/po/de.po installit/trunk/tools/shell.py installit/trunk/ui/installation.py Log: * components/packages.py: Added methods to return sets of unresolved libraries/programs and their paths. Added a new wrapper class for unresolved Programs. Renamed UnresolvedPackage into UnresolvedLibrary. * tools/shell.py: Added another constructor parameter for additional paths. If this parameter is defined, it will later be appended to $PATH. * ui/installation.py: Remove subtitles from installation wizard. Looks better without (less text -> users understand better). * backend/Source.py: Pass paths of dependencies (programs only) to all shell commands executed during the build process. This will help ./configure-scripts to find required programs. Added a requirements (dependencies) page, which now allows to resolve programs which were not found. Manual library resolving will follow. * ui/installation.py: Properly display installation/deinstallation wizards on the center of the screen. Avoid duplicate header title content. Modified: installit/trunk/ChangeLog =================================================================== --- installit/trunk/ChangeLog 2006-07-19 20:06:26 UTC (rev 22485) +++ installit/trunk/ChangeLog 2006-07-19 20:26:19 UTC (rev 22486) @@ -1,5 +1,29 @@ +2006-07-19 Jannis Pohlmann <[EMAIL PROTECTED]> + + * components/packages.py: Added methods to return sets of + unresolved libraries/programs and their paths. Added a new wrapper + class for unresolved Programs. Renamed UnresolvedPackage into + UnresolvedLibrary. + * tools/shell.py: Added another constructor parameter for additional + paths. If this parameter is defined, it will later be appended to + $PATH. + * ui/installation.py: Remove subtitles from installation wizard. + Looks better without (less text -> users understand better). + * backend/Source.py: Pass paths of dependencies (programs only) to + all shell commands executed during the build process. This will + help ./configure-scripts to find required programs. + Added a requirements (dependencies) page, which now allows to + resolve programs which were not found. Manual library resolving + will follow. + 2006-07-12 Jannis Pohlmann <[EMAIL PROTECTED]> + * ui/installation.py: Properly display installation/deinstallation + wizards on the center of the screen. Avoid duplicate header title + content. + +2006-07-12 Jannis Pohlmann <[EMAIL PROTECTED]> + * i18n/po/de.po, i18n/po/i2t.po: New strings merged. * tools/env.py: Add link() and hasLibrary() methods. * components/packages.py: Use Environment.hasLibrary method to detect Modified: installit/trunk/backends/Source.py =================================================================== --- installit/trunk/backends/Source.py 2006-07-19 20:06:26 UTC (rev 22485) +++ installit/trunk/backends/Source.py 2006-07-19 20:26:19 UTC (rev 22486) @@ -29,6 +29,7 @@ from tools.shell import Command from components.mirrors import MirrorList from components.config import Config +from components.packages import Program, Library from ui.installation import BackendInstallationWizard, \ BackendDeinstallationWizard from ui.extensions import showMessage, forceRefresh @@ -79,16 +80,18 @@ # Determine working directory directory = path.join(Config.get("TempDir"), package.unpackDir) - + # Build configure command - return Command("./configure %s" % " ".join(options), directory) + return Command("./configure %s" % " ".join(options), directory, + ":".join(package.getProgramPaths())) def getBuildCommand(self, package): # Determine working directory directory = path.join(Config.get("TempDir"), package.unpackDir) # Generate build command - return Command("make", directory) + return Command("make", directory, + ":".join(package.getProgramPaths())) def getTestInstallCommand(self, package): # Determine working directory @@ -96,14 +99,16 @@ # Generate temporary installation command return Command("make DESTDIR=%s install" - % package.getTempInstallPrefix(), directory) + % package.getTempInstallPrefix(), directory, + ":".join(package.getProgramPaths())) def getInstallCommand(self, package): # Determine working directory directory = path.join(Config.get("TempDir"), package.unpackDir) # Generate installation command - return Command("make install", directory) + return Command("make install", directory, + ":".join(package.getProgramPaths())) def writeInstallLog(self, package): # Determine log directory @@ -179,9 +184,9 @@ page.show() # System requirements - # page = RequirementsPage(self, package) - # self.pages.add(page) - # page.show() + page = RequirementsPage(self, package) + self.pages.add(page) + page.show() # Extract page = ExtractPage(self, package) @@ -637,6 +642,149 @@ gtk.gdk.threads_leave() +class RequirementsPage(SourceWizardPage): + + def __init__(self, wizard, package): + SourceWizardPage.__init__(self, wizard, package, + _("System Requirements for %s") % package.name) + + # Generate main container + self.box = gtk.Frame() + self.box.set_shadow_type(gtk.SHADOW_NONE) + self.add(self.box) + self.box.show() + + # Create a file chooser dialog for manually resolving dependencies + self.fileChooser = gtk.FileChooserDialog(_("Choose Folder"), None, + gtk.FILE_CHOOSER_ACTION_SELECT_FOLDER, + (gtk.STOCK_CANCEL, gtk.RESPONSE_REJECT, + gtk.STOCK_OK, gtk.RESPONSE_ACCEPT)) + + # Sets of unresolved programs/libraries + self.programs = set() + self.libraries = set() + + self.locations = dict() + self.statusButtons = dict() + + def activate(self, wizard): + SourceWizardPage.activate(self, wizard) + + wizard.backButton.set_sensitive(True) + + if self.box.get_child(): + self.box.remove(self.box.get_child()) + + container = gtk.VBox(False, 0) + self.box.add(container) + container.show() + + self.programs.clear() + self.libraries.clear() + self.locations.clear() + self.statusButtons.clear() + + # Determine unresolved programs + self.programs = self.package.getUnresolvedPrograms() + + if len(self.programs) > 0: + # Add description label + label = gtk.Label(_("The following programs could not be found:")) + label.set_alignment(0.0, 0.5) + container.pack_start(label, False, False, 0) + label.show() + + # Add table + table = gtk.Table(1, 2) + table.set_border_width(6) + table.set_col_spacings(12) + container.pack_start(table, False, False, 0) + table.show() + + i = 0 + + for program in self.programs: + hbox = gtk.HBox(False, 0) + table.attach(hbox, 0, 1, i, i+1, gtk.SHRINK) + hbox.show() + + # Status button + status = gtk.Button() + status.connect("clicked", lambda button: + self._locateProgram(program)) + status.set_relief(gtk.RELIEF_NONE) + status.set_image(gtk.image_new_from_stock(gtk.STOCK_NO, + gtk.ICON_SIZE_BUTTON)) + hbox.pack_start(status, False, True, 0) + status.show() + + self.statusButtons[program] = status + + # Program label + label = gtk.Label() + label.set_markup("<b>%s</b>" % program.name) + label.set_alignment(0.0, 0.5) + hbox.pack_start(label, False, True, 0) + label.show() + + # Locate manually via file chooser + button = gtk.Button(_("Locate manually...")) + button.connect("clicked", lambda button: + self._locateProgram(program)) + button.set_image(gtk.image_new_from_stock(gtk.STOCK_FIND, + gtk.ICON_SIZE_BUTTON)) + table.attach(button, 1, 2, i, i+1, gtk.SHRINK) + button.show() + + # Determine unresolved libraries + self.libraries = self.package.getUnresolvedLibraries() + + + if self.validate(): + self.emit("page-success") + + def validate(self): + # We're done when there are no missing depdendencies left + if len(self.programs) == 0 and len(self.libraries) == 0: + return True + + def _locateProgram(self, program): + if self.locations.has_key(program): + self.fileChooser.set_filename(self.locations[program]) + + if self.fileChooser.run() == gtk.RESPONSE_ACCEPT: + self.locations[program] = self.fileChooser.get_filename() + + # Generate absolute path + fullpath = path.join(self.locations[program], program.name) + + # Check if program is executable + if os.access(fullpath, os.X_OK): + # Update status icon + image = gtk.image_new_from_stock(gtk.STOCK_YES, + gtk.ICON_SIZE_BUTTON) + self.statusButtons[program].set_image(image) + + # Create new (resolved) program object + newProgram = Program(program.name, + self.fileChooser.get_filename()) + + # Replace UnresolvedProgram with Program + self.package.dependencies.programs.remove(program) + self.package.dependencies.programs.add(newProgram) + + # Remove program from unresolved dependencies + self.programs.remove(program) + else: + # Update status icon + image = gtk.image_new_from_stock(gtk.STOCK_NO, + gtk.ICON_SIZE_BUTTON) + self.statusButtons[program].set_image(image) + + # Hide the file chooser again + self.fileChooser.hide() + + class BuildPage(SourceWizardPage): def __init__(self, wizard, package): Modified: installit/trunk/components/packages.py =================================================================== --- installit/trunk/components/packages.py 2006-07-19 20:06:26 UTC (rev 22485) +++ installit/trunk/components/packages.py 2006-07-19 20:26:19 UTC (rev 22486) @@ -76,7 +76,7 @@ self.install = None -class UnresolvedPackage: +class UnresolvedLibrary: def __init__(self, name, version, backend=None): self.name = name @@ -84,6 +84,12 @@ self.backend = backend +class UnresolvedProgram: + + def __init__(self, name): + self.name = name + + class Dependencies: def __init__(self): @@ -125,7 +131,33 @@ results = results.union(package.getDeepDependencies()) return results + def getUnresolvedPrograms(self): + results = set() + for dep in self.dependencies.programs: + if isinstance(dep, UnresolvedProgram): + results.add(dep) + + return results + + def getUnresolvedLibraries(self): + results = set() + + for dep in self.dependencies.libraries: + if isinstance(dep, UnresolvedLibrary): + results.add(dep) + + return results + + def getProgramPaths(self): + paths = set() + + for program in self.dependencies.programs: + paths.add(program.path) + + return paths + + # Register Package to GObject type system gobject.type_register(Package) @@ -526,7 +558,7 @@ paths = BaseDir.getPath() for location in paths: - if path.isfile(path.join(location, name)): + if os.access(path.join(location, name), os.X_OK): return Program(name, path.join(location, name)) raise ProgramNotFoundError(name) @@ -550,12 +582,12 @@ if Environment.hasLibrary(dep["name"], dep["version"]): return Library(dep["name"], dep["version"]) else: - return UnresolvedPackage(dep["name"], + return UnresolvedLibrary(dep["name"], dep["version"]) else: # Mark this dependency as unresolved and try resolving # it manually during installation. - pkg = UnresolvedPackage(dep["name"], dep["version"]) + pkg = UnresolvedLibrary(dep["name"], dep["version"]) newDeps.add(pkg) @@ -568,8 +600,8 @@ for dep in package.dependencies.programs: try: pkg = self._resolveProgram(dep["name"]) - except PackageNotFoundError, e: - pkg = UnresolvedPackage(dep["name"], None, None) + except ProgramNotFoundError, e: + pkg = UnresolvedProgram(dep["name"]) newDeps.add(pkg) Modified: installit/trunk/i18n/po/de.po =================================================================== --- installit/trunk/i18n/po/de.po 2006-07-19 20:06:26 UTC (rev 22485) +++ installit/trunk/i18n/po/de.po 2006-07-19 20:26:19 UTC (rev 22486) @@ -29,17 +29,19 @@ #: ../..//backends/Source.py:341 #, python-format -msgid "Please specify the installation prefix <b>%(name)s</b> should be installed to. You need write permissions for this directory." -msgstr "Bitte geben Sie das Zielverzeichnis an, in das <b>%(name)s</b> installiert werden soll. Sie benötigen für dieses Verzeichnis Schreibrechte." +msgid "" +"Please specify the installation prefix <b>%(name)s</b> should be installed " +"to. You need write permissions for this directory." +msgstr "" +"Bitte geben Sie das Zielverzeichnis an, in das <b>%(name)s</b> installiert " +"werden soll. Sie benötigen für dieses Verzeichnis Schreibrechte." #. File chooser dialog -#: ../..//backends/Source.py:351 -#: ../..//ui/main.py:82 +#: ../..//backends/Source.py:351 ../..//ui/main.py:82 msgid "Installation Prefix" msgstr "Zielverzeichnis" -#: ../..//backends/Source.py:378 -#: ../..//ui/initial.py:306 +#: ../..//backends/Source.py:378 ../..//ui/initial.py:306 #, python-format msgid "Directory %s is not writable." msgstr "Verzeichnis %s ist schreibgeschützt." @@ -205,7 +207,9 @@ #: ../..//ui/main.py:142 msgid "Perform package installations/removals/updates." -msgstr "Die gewünschten Installationen/Deinstallationen und Aktualisierungen durchführen." +msgstr "" +"Die gewünschten Installationen/Deinstallationen und Aktualisierungen " +"durchführen." #: ../..//ui/main.py:144 msgid "Select _Mirror" @@ -241,8 +245,12 @@ #. Display additional packages dialog #: ../..//ui/main.py:401 -msgid "The following additional packages have to be installed. Do you want to continue?" -msgstr "Die folgenden, zusätzlichen Pakete müssen installiert werden. Wollen Sie fortfahren?" +msgid "" +"The following additional packages have to be installed. Do you want to " +"continue?" +msgstr "" +"Die folgenden, zusätzlichen Pakete müssen installiert werden. Wollen Sie " +"fortfahren?" #: ../..//ui/main.py:417 msgid "No changes were made." @@ -253,8 +261,7 @@ msgid "Downloading packages" msgstr "Lade Pakete herunter" -#: ../..//ui/main.py:485 -#: ../..//ui/tasks.py:428 +#: ../..//ui/main.py:485 ../..//ui/tasks.py:428 #, python-format msgid "Could not fetch package from %s." msgstr "Konnte Paket nicht von %s holen." @@ -264,8 +271,12 @@ msgstr "Einleitende Konfiguration" #: ../..//ui/initial.py:112 -msgid "You have to configure InstallIt on first startup. Do you really want to abort?" -msgstr "InstallIt muss vor dem ersten Start konfiguriert werden. Sind Sie sicher, dass sie abbrechen wollen?" +msgid "" +"You have to configure InstallIt on first startup. Do you really want to " +"abort?" +msgstr "" +"InstallIt muss vor dem ersten Start konfiguriert werden. Sind Sie sicher, " +"dass sie abbrechen wollen?" #: ../..//ui/initial.py:135 msgid "Please fill out this page correctly." @@ -278,11 +289,15 @@ #. Description #: ../..//ui/initial.py:219 msgid "" -"InstallIt uses a repository system and needs to store some data on your harddrive, like the mirror list, package information and temporary installation files.\n" +"InstallIt uses a repository system and needs to store some data on your " +"harddrive, like the mirror list, package information and temporary " +"installation files.\n" " \n" "Please enter/select the directories you want InstallIt to use." msgstr "" -"InstallIt verwendet ein Paketsystem und muss Daten auf Ihrer Festplatte speichern, wie zum Beispiel die Mirror-Liste, Paketinformationen und temporäre Installationsdateien. \n" +"InstallIt verwendet ein Paketsystem und muss Daten auf Ihrer Festplatte " +"speichern, wie zum Beispiel die Mirror-Liste, Paketinformationen und " +"temporäre Installationsdateien. \n" "\n" "Bitte geben sie die Verzeichnisse an, die InstallIt dafür nutzen soll." @@ -304,8 +319,7 @@ msgstr "Verzeichnis auswählen" #. Name column -#: ../..//ui/categories.py:94 -#: ../..//ui/installation.py:107 +#: ../..//ui/categories.py:94 ../..//ui/installation.py:107 #: ../..//ui/packages.py:158 msgid "Name" msgstr "Name" @@ -334,8 +348,7 @@ msgid "Installation Wizard" msgstr "Installation" -#: ../..//ui/installation.py:174 -#: ../..//ui/installation.py:312 +#: ../..//ui/installation.py:174 ../..//ui/installation.py:312 msgid "<b>Packages:</b>" msgstr "<b>Pakete:</b>" @@ -353,8 +366,7 @@ msgid "All packages were removed successfully." msgstr "Alle Pakete wurden erfolgreich entfernt." -#: ../..//ui/download.py:114 -#: ../..//ui/download.py:115 +#: ../..//ui/download.py:114 ../..//ui/download.py:115 msgid "Establishing connection..." msgstr "Stelle Verbindung her..." @@ -421,11 +433,13 @@ #: ../..//setup.py:43 msgid "You need at least PyGTK 2.6 to run InstallIt (i2t)" -msgstr "Sie benötigen mindestens PyGTK 2.6 um InstallIt (i2t) nutzen zu können." +msgstr "" +"Sie benötigen mindestens PyGTK 2.6 um InstallIt (i2t) nutzen zu können." #: ../..//setup.py:59 msgid "Graphical source-based package manager and installer" -msgstr "Grafisches, quellenbasiertes Paketverwaltungs- und Installationsprogramm" +msgstr "" +"Grafisches, quellenbasiertes Paketverwaltungs- und Installationsprogramm" #: ../..//setup.py:61 msgid "InstallIt (i2t) is a source-based package management solution" @@ -458,16 +472,22 @@ #~ msgid "Features" #~ msgstr "Features" + #~ msgid "Configuration" #~ msgstr "Konfiguration" + #~ msgid "Performing Test Installation" #~ msgstr "Führe Testinstallation durch" + #~ msgid "Download Wizard" #~ msgstr "Download" + #~ msgid "Moving %(file)s to %(dir)s" #~ msgstr "Verschiebe %(file)s nach %(dir)s" + #~ msgid "All packages were successfully installed." #~ msgstr "Alle Pakete wurden erfolgreich installiert." + #~ msgid "Select _mirror" #~ msgstr "_Mirror auswählen" @@ -488,16 +508,20 @@ #~ msgid_plural "Remove packages" #~ msgstr[0] "Paket _entfernen" #~ msgstr[1] "Paket _entfernen" + #~ msgid "Version" #~ msgstr "Version" + #~ msgid "Backend" #~ msgstr "Backend" + #~ msgid "" #~ "GTK+ bindings for Python could not be found. Please install python-gtk or " #~ "pygtk first." #~ msgstr "" #~ "GTK+-Bindungen für Python konnten nicht gefunden werden. Bitte " #~ "installieren Sie zunächst python-gtk oder pygtk." + #~ msgid "" #~ "This is your first start of InstallIt. In order to use it you will have " #~ "to define working directories first. \n" @@ -508,4 +532,3 @@ #~ "können, müssen vorab Arbeitsverzeichnisse festgelegt werden. \n" #~ "Sie können alternativ dazu die vordefinierten Verzeichnisse nutzen. Diese " #~ "sind für die meisten Benutzer ausreichend." - Modified: installit/trunk/tools/shell.py =================================================================== --- installit/trunk/tools/shell.py 2006-07-19 20:06:26 UTC (rev 22485) +++ installit/trunk/tools/shell.py 2006-07-19 20:26:19 UTC (rev 22486) @@ -33,11 +33,12 @@ class Command(gobject.GObject): - def __init__(self, command, directory=None): + def __init__(self, command, directory=None, path=""): gobject.GObject.__init__(self) self.command = command self.directory = directory + self.path = path def _reset(self): self.terminated = False @@ -53,6 +54,12 @@ def _process(self): # Setup process environment env = Environment.copy() + + # Expand $PATH + if env.has_key("PATH"): + env["PATH"] = env["PATH"] + ":" + self.path + else: + env["PATH"] = self.path Environment.expandPkgConfigPath(env) Environment.expandLibraryPath(env) Modified: installit/trunk/ui/installation.py =================================================================== --- installit/trunk/ui/installation.py 2006-07-19 20:06:26 UTC (rev 22485) +++ installit/trunk/ui/installation.py 2006-07-19 20:26:19 UTC (rev 22486) @@ -41,7 +41,6 @@ self.package = package def setTitle(self, title): - self.dialog.set_subtitle(title) self.dialog.set_title(_("Installation: %s" % title)) @@ -71,7 +70,6 @@ self.package = package def setTitle(self, title): - self.dialog.heading.set_subtitle(title) self.dialog.set_title(_("Deinstallation: %s") % title) @@ -153,6 +151,7 @@ # Basic window setup self.set_default_size(640, 480) + self.set_position(gtk.WIN_POS_CENTER_ALWAYS) self.set_type_hint(gtk.gdk.WINDOW_TYPE_HINT_NORMAL) self.set_property("skip-taskbar-hint", False) self.set_property("skip-pager-hint", False) @@ -291,6 +290,7 @@ # Basic window setup self.set_default_size(640, 480) + self.set_position(gtk.WIN_POS_CENTER_ALWAYS) self.set_type_hint(gtk.gdk.WINDOW_TYPE_HINT_NORMAL) self.set_property("skip-taskbar-hint", False) self.set_property("skip-pager-hint", False) _______________________________________________ Xfce4-commits mailing list Xfce4-commits@xfce.org http://foo-projects.org/mailman/listinfo/xfce4-commits