# data file for the Fltk User Interface Designer (fluid) version 1.0106 header_name {.h} code_name {.cxx} class stxinstall {open } { Function {make_window(self)} {open } { Fl_Window {} { label {STX Installer} open xywh {373 138 630 480} type Single visible } { Fl_Text_Display txtHelp { xywh {5 100 145 340} box THIN_DOWN_BOX } Fl_Button btnNext { label Next xywh {550 450 75 25} box THIN_UP_BOX code0 {btnNext.callback(self.next)} } Fl_Button btnPrev { label Previous xywh {470 450 75 25} box THIN_UP_BOX code0 {btnPrev.callback(self.prev)} } Fl_Button btnCancel { label Cancel xywh {5 450 75 25} box THIN_UP_BOX code0 {btnCancel.callback(self.quit)} } Fl_Group grpLogo {open xywh {0 -1 630 92} box BORDER_BOX align 17 } {} Fl_Wizard wzdMain {open xywh {160 100 480 345} box FLAT_BOX } { Fl_Group grpWelcome { label {Welcome to the STX Installer! This program will install STX to your computer's hard drive. Throughout the installation process help will be displayed in the box on the left of this window.} open xywh {160 100 465 345} align 149 hide code0 {self.pagedict["welcome"] = grpWelcome} } { Fl_Group grpType { label {Please select the type of installation you wish to perform:} open xywh {160 170 465 190} align 21 code0 {self.pagedict["type"] = grpType} } { Fl_Button btnPartition { label {Launch Partitioning Tool} callback {self.launch_partitioner} xywh {160 265 180 25} box THIN_UP_BOX } Fl_Round_Button radCustom { label {Custom install} callback {self.enable_partitioner} xywh {175 195 145 20} down_box ROUND_DOWN_BOX code0 {radCustom.setonly()} code1 {radCustom.type(FL_RADIO_BUTTON)} } Fl_Round_Button radFull { label {Full disk install} callback {self.disable_partitioner} xywh {175 215 145 20} down_box ROUND_DOWN_BOX code0 {radFull.type(FL_RADIO_BUTTON)} } Fl_Round_Button radFree { label {Free space install} callback {self.enable_partitioner} xywh {175 235 145 20} down_box ROUND_DOWN_BOX code0 {radFree.type(FL_RADIO_BUTTON)} } } } Fl_Group grpSelParts { label {Select the partitions you would like STX to use. You can change your partitions by launching the partitioning tool on the previous page.} open xywh {160 100 466 345} align 149 hide } { Fl_Choice chcRoot { label {Root partition: } open xywh {275 315 350 20} down_box BORDER_BOX } {} Fl_Choice chcHome { label {Home partition: } open xywh {275 340 350 20} down_box BORDER_BOX } {} Fl_Choice chcSwap { label {Swap partition: } open xywh {275 365 350 20} down_box BORDER_BOX } {} Fl_Check_Button {} { label {Preserve home partition} xywh {165 420 190 20} down_box DOWN_BOX align 24 deactivate } Fl_Group {} { label {Partitions:} open xywh {165 185 460 125} box FLAT_BOX align 5 } { Fl_Scroll scrPart {open xywh {165 185 460 110} box THIN_DOWN_FRAME code0 {scrPart.type(FL_VERTICAL)} } { Fl_Pack pckPart {open xywh {167 187 455 106} resizable code0 {pckPart.spacing(2)} } {} } } Fl_Choice chcFormat { label {Format: } open xywh {275 390 350 20} down_box BORDER_BOX } {} } Fl_Group grpInstall { label {This is your last chance to change your options. If you do wish to change them press the "Previous" button. When you are certain that they are correct press the "Begin Installation" button.} open xywh {160 100 470 345} align 149 hide } { Fl_Progress progress { xywh {165 255 450 25} box PLASTIC_UP_BOX selection_color 136 deactivate } Fl_Button btnInstall { label {Begin Installation} xywh {165 170 200 25} box THIN_UP_BOX down_box THIN_DOWN_BOX code0 {btnInstall.callback(self.install)} } Fl_Group grpStatus { label {Status: Waiting for the installation to begin.} open xywh {160 215 430 35} align 21 deactivate } {} } Fl_Group grpUsers { label {STX is now installed on your computer. As the last stage in the installation you need to create a user account and set the root password (root is the administration account).} open xywh {160 100 470 345} align 145 hide } { Fl_Input {} { label {Username:} xywh {295 175 150 25} } Fl_Input {} { label {Password:} xywh {295 235 150 25} } Fl_Input {} { label {Confirm Password:} xywh {295 265 150 25} } Fl_Input {} { label {Full Name:} xywh {295 205 150 25} } Fl_Input {} { label {Root Password:} xywh {295 315 150 25} } Fl_Input {} { label {Confirm Password:} xywh {295 345 150 25} } } Fl_Group grpFinished { label {The installation is now complete! Restart your computer to enter your new STX system.} open xywh {160 150 470 295} labelsize 18 align 177 } {} } } } Function {next(self, button)} {open } { code {global currentPage wzdMain.next() if currentPage == 0: self.populate_partitions() btnPrev.activate() print radFull.value() if radFull.value() == 1 or radFree.value() == 1: \#Go forward 2 pages wzdMain.next() currentPage += 1 elif currentPage == 1: btnNext.deactivate() elif currentPage == 3: btnNext.label("Finish") elif currentPage == 4: self.quit(button) currentPage += 1 self.load_help()} {} } Function {prev(self, button)} {open } { code {global currentPage wzdMain.prev() if currentPage == 1: btnPrev.deactivate() elif currentPage == 2: btnNext.activate() currentPage -= 1 self.load_help()} {} } Function {quit(self, button)} {open selected } { code {if self.parser: self.parser.stop() self.parser.join() sys.exit(0)} {} } Function {__init__(self)} {open } { code {global sys, os, re, currentPage import sys, os, re self.parser = None from ConfigParser import SafeConfigParser self.basedir = "./" self.pagedict = dict() if os.geteuid()!=0: fl_message("Sorry, you need root permissions to use this program.") return self.winMain = self.make_window() imgLogo = Fl_PNG_Image(self.basedir + "stx.png") grpLogo.image(imgLogo) imgSmiley = Fl_PNG_Image(self.basedir + "smiley.png") grpFinished.image(imgSmiley) self.help = SafeConfigParser() self.help.read(self.basedir + "help.conf") bufHelp = Fl_Text_Buffer(1000) txtHelp.buffer(bufHelp) txtHelp.wrap_mode(1, 0) currentPage = 0 btnPrev.deactivate() self.load_help() self.winMain.show(sys.argv)} {} } Function {load_help(self)} {open } { code {global currentPage try: helppage = self.help.get(str(currentPage), "text") except: helppage = "Sorry, no help is available for this page." bufHelp = txtHelp.buffer() bufHelp.replace(0, 1000, helppage)} {} } Function {launch_partitioner(self, button)} {open } { code {os.popen("partitionmorpher")} {} } Function {enable_partitioner(self, button)} {open } { code {btnPartition.activate()} {} } Function {disable_partitioner(self, button)} {open } { code {btnPartition.deactivate()} {} } Function {populate_partitions(self)} {open } { code {self.rootlookup = [] self.homelookup = ["Root"] self.swaplookup = ["None"] self.formatlookup = ["ext3", "ext2", "reiserfs"] self.partbuttons = [] tooltips = [] pckPart.clear() chcRoot.callback(self.chcPart_selected, "Root") chcHome.callback(self.chcPart_selected, "Home") chcSwap.callback(self.chcPart_selected, "Swap") chcHome.add("Root") chcSwap.add("None") for format in self.formatlookup: chcFormat.add(format) disklist = os.popen("cat /proc/diskstats") partitions = disklist.readlines() diskPattern = re.compile("[hs]d.[0-9]+") prevDisk = None rootSet = False swapSet = False for partition in partitions: partition = diskPattern.findall(partition) if len(partition) == 0: continue partition = partition[0] partSize = os.popen("sfdisk -sn /dev/" + partition).readline() partSize = (int(partSize) / 1024.0) / 1024 partSizestr = str(round(partSize, 2)) \#Incase of screwed up partition tables if partSizestr == "0.0": continue partFormat = os.popen("sfdisk -cn /dev/" + partition[:3] + " " + partition[3:]).readline() partFormat = int(partFormat, 16) if partition[:2] == "sd": partitionName = "External Disk " else: partitionName = "Disk " partitionName += str(ord(partition[2:3]) - 96) + "; Partition " + partition[3:] + " (" + partition + ", size: " + partSizestr + "GiB)" if partFormat == 131: self.rootlookup.append(partition) chcRoot.add(partitionName) chcHome.add(partitionName) elif partFormat == 130: self.swaplookup.append(partition) chcSwap.add(partitionName) \#Handle pretty partition display if prevDisk != partition[:3]: prevDisk = partition[:3] diskSize = os.popen("sfdisk -sn /dev/" + partition[:3]).readline() diskSize = (int(diskSize) / 1024.0) / 1024 diskSize = round(diskSize, 2) pack = Fl_Pack(0, 0, -1, 25) pack.type(FL_HORIZONTAL) pack.spacing(2) pckPart.add(pack) width = partSize / diskSize * pckPart.w() * 0.50 width = int(width) if width < 85: width = 85 if partFormat == 130 or partFormat == 131: btnPart = Fl_Menu_Button(0, 0, width, 25, partition) btnPart.textsize(10) else: \#Non linux partition, no menu btnPart = Fl_Button(0, 0, width, 25, partition) btnPart.box(FL_PLASTIC_UP_BOX) btnPart.labelsize(10) btnPart.callback(self.btnPart_selected, partition) if partFormat == 130: btnPart.color(fl_rgb_color(0, 200, 0)) btnPart.selection_color(fl_rgb_color(0, 255, 0)) btnPart.add("Use As Swap") format = "Linux Swap" if not swapSet: \#Select first Linux-Swap partition as swap btnPart.copy_label(partition + " (Swap)") swapSet = True elif partFormat == 131: btnPart.color(fl_rgb_color(0, 0, 200)) btnPart.selection_color(fl_rgb_color(0, 0, 255)) format = "Linux" btnPart.add("Use As Root") btnPart.add("Use As Home") btnPart.add("Use As Both") if not rootSet: \#Select first Linux partition as root+home btnPart.copy_label(partition + " (Root+Home)") rootSet = True else: btnPart.color(fl_rgb_color(100, 0, 0)) btnPart.selection_color(fl_rgb_color(126, 0, 0)) format = "Non-Linux" tooltips.append("Size: " + partSizestr + "GB | Type: " + format) btnPart.tooltip(tooltips[-1]) self.partbuttons.append(btnPart) pack.add(self.partbuttons[-1]) \#Set sensible defaults chcRoot.value(0) chcHome.value(0) chcSwap.value(len(self.swaplookup) - 1) chcFormat.value(0)} {} } Function {btnPart_selected(self, button, partition)} {open } { code {if button.color() == fl_rgb_color(0, 0, 200) or button.color() == fl_rgb_color(0, 0, 255): \# Linux if button.value() == 0: button.label(partition + " (Root)") \#Set chcRoot to match for i in range(0, len(self.rootlookup)): if self.rootlookup[i] == partition: chcRoot.value(i) break; if button.value() == 1: button.label(partition + " (Home)") \#Set chcHome to match for i in range(0, len(self.homelookup)): if self.homelookup[i] == partition: chcHome.value(i) break; if button.value() == 2: button.label(partition + " (Root+Home)") \#Set chcRoot and chcHome to match for i in range(0, len(self.rootlookup)): if self.rootlookup[i] == partition: chcRoot.value(i) chcHome.value(0) break; elif button.color() == fl_rgb_color(0, 200, 0) or button.color() == fl_rgb_color(0, 255, 0): \# Swap if button.value() == 0: button.label(partition + " (Swap)") \#Set chcSwap to match for i in range(0, len(self.swaplookup)): if self.swaplookup[i] == partition: chcSwap.value(i) break;} {} } Function {install(self, button)} {open } { code {btnInstall.deactivate() btnPrev.deactivate() btnNext.deactivate() \#btnCancel.deactivate() grpStatus.activate() progress.activate() grpStatus.label("Status: Beginning installation...") from shlexinstall import Parser self.parser = Parser("install.sh", self.update_display) self.parser.variables["$ROOT"] = self.rootlookup[chcRoot.value()] self.parser.variables["$HOME"] = self.homelookup[chcHome.value()] self.parser.variables["$SWAP"] = self.swaplookup[chcSwap.value()] self.parser.variables["$FORMAT"] = self.formatlookup[chcFormat.value()] self.parser.start()} {} } Function {update_display(self, text)} {open } { code {import re progCheck = re.compile("\\(\\d+\\%\\)$") progMatch = progCheck.search(text) if progMatch: prog = progMatch.group() \#Get integer from progress string prog = int(prog[1:-2]) progress.value(prog) grpStatus.label("Status: " + text) if prog == 100: btnNext.activate()} {} } Function {chcPart_selected(self, choice, type)} {open } { code {if type == "Root": partition = self.rootlookup[choice.value()] elif type == "Home": partition = self.homelookup[choice.value()] elif type == "Swap": partition = self.swaplookup[choice.value()] for button in self.partbuttons: if button.label()[:len(partition)] == partition: if (type == "Root" and (chcHome == "Root" or chcHome.value() == chcRoot.value() + 1)): type = "Root+Home" button.label(partition + " (" + type + ")")} {} } }