#!/usr/bin/env python # # gui.py # # (c) Copyright 2009 Michael Towers (larch42 at googlemail dot com) # # This file is part of the larch project. # # larch 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. # # larch 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 larch; if not, write to the Free Software Foundation, Inc., # 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA # #---------------------------------------------------------------------------- # 2010.03.22 from uipi import Uipi import locale, os # Try to work around problems when the system encoding is not utf8 encoding = locale.getdefaultlocale()[1] if encoding == "UTF8": encoding = None class Ui(Uipi): def __init__(self, guiexec): if guiexec and os.path.isfile(base_dir + "/" + guiexec): guiexec = base_dir + "/" + guiexec Uipi.__init__(self, backend=guiexec, cwd=base_dir) def init(self): # Build the main window self.widget("Window", ":larch", title="larch", size="700_500", icon="images/larchicon.png", closesignal="$$$uiclose$$$") # - Header self.widget("Label", ":image", image="images/larch80.png") self.widget("Label", ":header", html='

%s

' % _("larch Live Arch Linux Construction Kit")) self.widget("Button", "^:showlog", text=_("View Log"), tt=_("This button switches to the log viewer")) self.widget("Button", "^:docs", text=_("Help"), tt=_("This button switches to the documentation viewer")) self.widget("Button", ":quit", text=_("Quit"), tt=_("Stop the current action and quit the program")) self.addsignal(":quit", "clicked", sname="$$$uiquit$$$") # - Main widget self.widget("Stack", ":tabs", pages=["tab:main", "tab:progress", "tab:log", "tab:doc", "tab:edit"]) self.widget("Notebook", "^:notebook", tabs=[ (":page_settings", _("Project Settings")), (":page_installation", _("Installation")), (":page_larchify", _("Larchify")), (":page_medium", _("Prepare Medium")), (":page_tweaks", _("Installation Tweaks")), ]) self.layout(":larch", ["*VBOX*", ["*HBOX*", ":image", ["*VBOX*", ["*HBOX*", ":header", "*SPACE"], ["*HBOX*", ":showlog", ":docs", "*SPACE", ":quit"],]], ":tabs"]) self.layout("tab:main", ["*VBOX*", ":notebook"]) self.progress = Progress() self.logger = Logger() self.docviewer = DocViewer() self.editor = Editor() self.setDisableWidgets(":larch", [":notebook"]) self.runningtab(0) # A list-choice popup widget self.listpopup = Popuplist() self.popuplist = self.listpopup.popup def go(self): self.command(":larch.show") def unbusy(self, ok=True): # 'ok' is only used by the console interface Uipi.unbusy(self) def runningtab(self, i=-1): if i < 0: i = self.maintab elif i < 2: self.maintab = i self.command(":tabs.set", i) #TODO: progress bar? class Progress: def __init__(self): self.active = False ui.widget("Label", "progress:header", html='

%s

%s

' % (_("Processing ..."), _("Here you can follow the detailed, low-level progress" " of the commands."))) ui.widget("TextEdit", "progress:text", ro=True) ui.widget("LineEdit", "progress:progress", ro=True, tt=_("An indication of the progress of the current operation, if possible")) ui.widget("Button", "progress:cancel", text=_("Cancel"), tt=_("Stop the current action")) ui.widget("Button", "^progress:done", text=_("Done")) ui.layout("tab:progress", ["*VBOX*", "progress:header", ["*HBOX*", "progress:text", ["*VBOX*", "progress:cancel", "*SPACE", "progress:done"]], "progress:progress"]) ui.addsignal("progress:cancel", "clicked", sname="$$$cancel$$$") ui.addslot("progress:done*clicked", self._done) def _done(self): ui.runningtab(0) def start(self): ui.command("progress:text.x__text") ui.command("progress:progress.x__text") ui.command("progress:done.enable", False) ui.command("progress:cancel.enable", True) self.active = True ui.runningtab(1) def end(self): ui.command("progress:cancel.enable", False) ui.command("progress:done.enable", True) self.active = False def addLine(self, line): # Try to work around problems when the system encoding is not utf8 if encoding: line = line.decode(self.encoding, "replace").encode("UTF8") ui.command("progress:text.append_and_scroll", line) def set(self, text=""): ui.command("progress:progress.x__text", text) class Logger: def __init__(self): ui.widget("Label", "log:header", html='

%s

%s

' % (_("Low-level Command Logging"), _("Here you can follow the detailed, low-level progress" " of the commands."))) ui.widget("TextEdit", "log:text", ro=True) ui.widget("Button", "^log:clear", text=_("Clear")) ui.widget("Button", "^log:hide", text=_("Hide"), tt=_("Go back to the larch controls")) ui.layout("tab:log", ["*VBOX*", "log:header", ["*HBOX*", "log:text", ["*VBOX*", "log:clear", "*SPACE", "log:hide"]]]) ui.addslot("log:clear*clicked", self.clear) ui.addslot("log:hide*clicked", self._hide) def clear(self): ui.command("log:text.x__text") def addLine(self, line): # Try to work around problems when the system encoding is not utf8 if encoding: line = line.decode(self.encoding, "replace").encode("UTF8") ui.command("log:text.append_and_scroll", line) def _hide(self): ui.runningtab() class DocViewer: def __init__(self): self.index = self._getPage("index.html") self.home = None ui.widget("Label", "doc:header", html='

%s

' % _("Documentation")) ui.widget("HtmlView", "doc:content") ui.widget("Button", "^doc:hide", text=_("Hide"), tt=_("Go back to the larch controls")) ui.widget("Button", "^doc:back", icon="left", tt=_("Go back in the viewing history")) ui.widget("Button", "^doc:forward", icon="right", tt=_("Go forward in the viewing history")) ui.widget("Button", "^doc:home", icon="reload", tt=_("Reload the documentation for the current larch tab")) ui.widget("Button", "^doc:parent", icon="up", tt=_("Go to the general larch documentation index")) ui.layout("tab:doc", ["*VBOX*", "*HLINE", ["*HBOX*", "doc:header", "*SPACE", "doc:back", "doc:forward", "doc:home", "doc:parent", "doc:hide"], "doc:content"]) command.addconnections([ ("doc:hide*clicked", self._hide), ("doc:back*clicked", self._back), ("doc:forward*clicked", self._forward), ("doc:home*clicked", self.gohome), ("doc:parent*clicked", self.goto), ]) def _hide(self): ui.runningtab() def _back(self): ui.command("doc:content.prev") def _forward(self): ui.command("doc:content.next") def _getPage(self, page): if lang and (len(lang) > 1): p = base_dir + ("/docs/%s/html/" % lang[0:2]) + page if os.path.isfile(p): return p return base_dir + "/docs/html/" + page def gohome(self, home=None): if home: self.home = self._getPage(home) self.goto(self.home) def goto(self, path=None): if not path: path = self.index ui.command("doc:content.setUrl", path) class Editor: def __init__(self): ui.widget("Label", "edit:header", html='

%s

' % _("Editor")) ui.widget("Label", "edit:title") ui.widget("TextEdit", "edit:content") ui.widget("Button", "^edit:ok", text=_("OK")) ui.widget("Button", "^edit:cancel", text=_("Cancel")) ui.widget("Button", "^edit:revert", text=_("Revert"), tt=_("Restore the text to its initial state")) ui.widget("Button", "^edit:copy", text=_("Copy")) ui.widget("Button", "^edit:cut", text=_("Cut")) ui.widget("Button", "^edit:paste", text=_("Paste")) ui.widget("Button", "^edit:undo", text=_("Undo")) ui.widget("Button", "^edit:redo", text=_("Redo")) ui.layout("tab:edit", ["*VBOX*", ["*HBOX*", "edit:header", "*SPACE", "edit:title"], ["*HBOX*", "edit:content", ["*VBOX*", "edit:copy", "edit:cut", "edit:paste", "edit:undo", "edit:redo", "edit:revert", "*SPACE", "edit:cancel", "edit:ok"]]]) def start(self, title, endcall, text="", revert=None): ui.command("edit:title.x__text", title) self.endcall = endcall self.revert = revert try: self.text0 = revert() if text == None else text except: run_error("BUG: Editor - no revert function?") ui.command("edit:content.x__text", self.text0) command.addconnections([ ("edit:ok*clicked", self.ok), ("edit:cancel*clicked", self.cancel), ("edit:revert*clicked", self.dorevert), ("edit:copy*clicked", self.copy), ("edit:cut*clicked", self.cut), ("edit:paste*clicked", self.paste), ("edit:undo*clicked", self.undo), ("edit:redo*clicked", self.redo), ("$edit-done$", self.sendtext), ]) ui.runningtab(4) def ok(self): ui.asknowait("edit:content.get", "$edit-done$") def sendtext(self, text): self.endcall(text) ui.runningtab() def cancel(self): ui.runningtab() def dorevert(self): if self.revert: self.text0 = self.revert() ui.command("edit:content.x__text", self.text0) def copy(self): ui.command("edit:content.copy") def cut(self): ui.command("edit:content.cut") def paste(self): ui.command("edit:content.paste") def undo(self): ui.command("edit:content.undo") def redo(self): ui.command("edit:content.redo") class Popuplist: def __init__(self): ui.widget("Dialog", "popuplist", icon="images/larchicon.png") ui.widget("Label", "popuplist:label") ui.widget("ListChoice", "^popuplist:list") ui.widget("DialogButtons", "popuplist:buttons", buttons=("Save", "Discard"), dialog="popuplist") ui.layout("popuplist", ["*VBOX*", "popuplist:label", "popuplist:list", "popuplist:buttons"]) ui.addslot("popuplist:list*changed", self.callback) def popup(self, items, index=0, title=_("Choose an item"), text=_("Select one of the following items:")): ui.command("popuplist.x__title", title) ui.command("popuplist:label.x__text", text) ui.command("popuplist:list.set", items, index) self.choice = index return (self.choice if ui.ask("popuplist.showmodal") else None) def callback(self, i): self.choice = i