"""
This file is part of Mokonnect.
Mokonnect is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License Version 3
as published by the Free Software Foundation.
Mokonnect 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 Mokonnect. If not, see .
"""
#
# mkmenu.py
# provides the main menu class
#
import os
import sys
import mkbase
import mkdev_usbnet
import mkdev_wifi
import mkdev_gprs
import mkdev_nat
class Menu():
def __init__(self,win,pager,bus,exit_func):
self.win = win
self.exit_func = exit_func
self.pager = pager
self.bus = bus
self.dev_errors = []
self.devices = []
self.about = "Version 0.4
* GPRS Beta connection
* Wifi static configuration
* USB Static configuration
* Hidden wifi Networks
* NAT Routing
- Created by Fate"
try:
self.devices.append(mkdev_usbnet.USBNetDevice(win,pager,bus))
except Exception,e:
self.dev_errors.append(str(e))
try:
self.devices.append(mkdev_wifi.WifiDevice(win,pager,bus))
except Exception,e:
self.dev_errors.append(str(e))
try:
self.devices.append(mkdev_gprs.GPRSDevice(win,pager,bus))
except Exception,e:
self.dev_errors.append(str(e))
try:
self.devices.append(mkdev_nat.NATDevice(win,pager,bus))
except Exception,e:
self.dev_errors.append(str(e))
self.config = {"profile":"Unknown","description":"Current profile is unknown, Select a profile or save a new one.","device_powerdown":True}
self.config["profile_list"] = {}
self.gui_profile = {
"type": "frame",
"label": "Profile",
"align": (-1,0),
"content": {
"type": "box",
"content": [
{"type": "button","align":(-1,0),"config_link":"profile","save_object":"profile_button","clicked": self.SelectProfileClicked},
{"type": "entry","align":(-1,0),"config_link":"description","editable":False,"save_object":"profile_description"}
]
}
}
self.gui_errors = {
"type": "frame",
"label": "Errors",
"align": (-1,0),
"content": {
"type": "box",
"content": [
# filled dynamically
]
}
}
for err in self.dev_errors:
self.gui_errors["content"]["content"].append(
{"type": "entry","align":(-1,0),"entry":err,"editable":False})
self.gui_devices = {
"type": "frame",
"label": "Configurations",
"align": (-1,0),
"content": {
"type":"box",
"content": [
# filled acording to self.devices
]
}
}
# filling the gui_devices
for dev in self.devices:
self.gui_devices["content"]["content"].append(
{"type":"button","align":(-1,0),"name":dev.name,"label":dev.name,"clicked": self.DeviceClicked})
self.gui_options = {
"type": "frame",
"label": "Options",
"align": (-1,0),
"content": {
"type":"box",
"content": [
{"type":"button","align":(-1,0),"label":"Save Profile","clicked":self.SaveProfileClicked},
{"type":"button","align":(-1,0),"label":"About","clicked":self.AboutClicked},
{"type":"button","align":(-1,0),"label":"Exit","clicked":self.ExitClicked}
]
}
}
self.gui_menu = {
"type":"scroller",
"bounce": (0,0),
"content": {
"type": "box",
"align": (-1.0,-1.0),
"weight": (1.0,1.0),
"content": [self.gui_profile,self.gui_devices,self.gui_options]
}
}
# add errors if exist
if len(self.dev_errors) != 0:
self.gui_menu["content"]["content"] = [self.gui_errors,self.gui_profile,self.gui_devices,self.gui_options]
self.gui_devicebox = {
"type":"box",
"content": [
{"type": "scroller","bounce":(0,0),"align":(-1,-1),"weight":(1,1),"save_object":"device_content"},
{"type": "table","align":(-1,0),"cols":3,"content":
[[
{"type":"button","label":"Discard","clicked":self.DeviceDiscardClicked},
{"type":"box","align":(-1,0),"weight":(1,1)},
{"type":"button","label":"Apply","clicked":self.DeviceApplyClicked}
]]
}
]
}
self.gui_infobox = {
"type":"box",
"content": [
{"type":"scroller","bounce":(0,0),"align":(-1,-1),"weight":(1,1),"content":
{"type":"entry","editable":False,"weight":(1,1),"align":(-1,0),"scale":0.7,"save_object":"log_entry"}
},
{"type":"button","label":"Done","save_object":"done_button","hidden":True,"clicked":self.InfoDoneClicked}
]
}
self.gui_saveprofile = {
"type":"box",
"content": [{
"type": "scroller",
"bounce":(0,0),
"align":(-1,-1),
"weight":(1,1),
"content": {
"type":"box",
"align":(-1,0),
"weight":(1,0),
"content": [{
"type":"frame",
"label":"Profile Information",
"align":(-1,0),
"content": {
"type": "table",
"align": (-1,0),
"cols": 3,
"content": [[
{"type":"label","label":"Profile Name:"},
{"type":"box","align":(-1,0),"weight":(1,1)},
{"type":"entry","entry":"NameOfProfile","save_object":"newprof_name"}
],
[{"type":"label","label":"Profile Description"}],
[{"type":"entry","align":(-1,0),"weight":(1,1),"save_object":"newprof_desc","entry":"Short Description of the profile purpose"}]
]
}
},
{
"type":"frame",
"label":"Profile Devices",
"align":(-1,0),
"content": {
"type": "box",
"content": [
# Append a check box for each device dynamically
]
}
}]
}
},{
"type": "table",
"align":(-1,0),
"cols":3,
"content": [[
{"type":"button","label":"Cancel","clicked":self.ProfileCancelClicked},
{"type":"box","align":(-1,0),"weight":(1,1)},
{"type":"button","label":"Save","clicked":self.ProfileSaveClicked}
]]
}]
}
for dev in self.devices:
self.gui_saveprofile["content"][0]["content"]["content"][1]["content"]["content"].append(
{"type":"check","label":dev.name,"name":dev.name,"save_object":"newprof_dev_%s" % dev.name})
self.gui_selectprofile = {
"type":"box",
"content": [{
"type": "scroller",
"bounce":(0,0),
"align":(-1,-1),
"weight":(1,1),
"content": {
"type": "box",
"align": (-1,0),
"weight":(1,0),
"content": [
# filled dynamically
]
}
},{
"type":"check","label":"Power down unused devices.","config_link":"device_powerdown"
},
{
"type":"button","label":"Back","clicked":self.ProfileCancelClicked
}]
}
self.about_hover = mkbase.MKHoverMessage(win,"About",self.about)
self.about_hover.config = self.config
def LogEntry(self,msg):
if msg != "__DONE__":
self.config["obj_log_entry"].entry_insert(msg+"
")
else:
self.config["obj_done_button"].show()
def ProfileDeleteClicked(self,obj,*args,**kargs):
print "ProfileDeleteClicked"
pfname = obj.name_get()
del self.config["profile_list"][pfname]
self.config["obj_profile_%s" % pfname].delete()
def ProfileLogEntry(self,msg):
if msg != "__DONE__":
self.config["obj_log_entry"].entry_insert(msg+"
")
else:
if len(self.devices_to_config) == 0:
if len(self.devices_to_powerdown) == 0:
self.config["obj_done_button"].show()
else:
next_dev = self.devices_to_powerdown[0]
self.devices_to_powerdown = self.devices_to_powerdown[1:]
self.config["obj_log_entry"].entry_insert("Power down %s...
" % next_dev.name)
next_dev.PowerOff(self.ProfileLogEntry)
else:
next_dev = self.devices_to_config[0]
self.devices_to_config = self.devices_to_config[1:]
self.config["obj_log_entry"].entry_insert("Configuring %s...
" % next_dev.name)
next_dev.Apply(self.ProfileLogEntry)
def ProfileApplyClicked(self,obj,*args,**kargs):
print "ProfileApplyClicked"
self.config["device_powerdown"] = False
if self.config["cfg_device_powerdown"].state_get() == 1:
self.config["device_powerdown"] = True
#load profile config
self.devices_to_config = []
self.devices_to_powerdown = []
pfname = obj.name_get()
for devname in self.config["profile_list"][pfname]["Devices"]:
for dev in self.devices:
if dev.name == devname:
dev.ImportConfig(self.config["profile_list"][pfname]["Devices"][devname])
self.devices_to_config.append(dev)
break
# check to see if we power down unused devices
if self.config["device_powerdown"]:
for dev in self.devices:
if not dev in self.devices_to_config:
self.devices_to_powerdown.append(dev)
# create an apply window
ibox = mkbase.EFLBuildObject(self.win,self.gui_infobox,self.config)
self.pager.content_pop()
self.pager.content_push(ibox)
# updating the gui button and description
self.config["profile"] = pfname
self.config["description"] = self.config["profile_list"][pfname]["Description"]
self.config["obj_profile_button"].label_set(pfname)
self.config["obj_profile_button"].name_set(pfname)
self.config["obj_profile_description"].entry_set(self.config["description"])
# marking the start of the chain
self.ProfileLogEntry("__DONE__")
def ProfileCancelClicked(self,obj,*args,**kargs):
print "ProfileCancelClicked"
self.pager.content_pop()
def ProfileSaveClicked(self,obj,*args,**kargs):
print "ProfileSaveClicked"
# collect list of devices to save in profile
dev_names = []
for cfg in self.config:
if cfg.startswith("obj_newprof_dev_"):
if 1 == self.config[cfg].state_get():
dev_names.append(cfg[len("obj_newprof_dev_"):])
# make sure some device has been selected
if len(dev_names) == 0:
return
nprof = {}
nprofname = self.config["obj_newprof_name"].entry_get()
nprofname = nprofname.replace("
","")
nprof["Description"] = self.config["obj_newprof_desc"].entry_get()
nprof["Devices"] = {}
for dev_name in dev_names:
for dev in self.devices:
if dev.name == dev_name:
nprof["Devices"][dev_name] = dev.ExportConfig()
break
self.config["profile_list"][nprofname] = nprof
self.pager.content_pop()
def SelectProfileClicked(self,obj,*args,**kargs):
print "SelectProfileClicked"
# update the profiles
self.gui_selectprofile["content"][0]["content"]["content"] = []
for pfname in self.config["profile_list"]:
gui_prof = {
"type":"frame",
"save_object":"profile_%s" % pfname,
"label":pfname,
"align":(-1,0),
"content": {
"type": "table",
"align":(-1,0),
"cols":2,
"content": [
[{"type":"entry","align":(-1,0),"weight":(1,1),"editable":False,"entry":self.config["profile_list"][pfname]["Description"]}],
[
{"type":"button","align":(-1,0),"label":"Delete","name":pfname,"clicked":self.ProfileDeleteClicked},
{"type":"button","align":(-1,0),"name":pfname,"label":"Apply","clicked":self.ProfileApplyClicked}
]
]
}
}
self.gui_selectprofile["content"][0]["content"]["content"].append(gui_prof)
# generate gui
sbox = mkbase.EFLBuildObject(self.win,self.gui_selectprofile,self.config)
self.pager.content_push(sbox)
def DeviceClicked(self,obj,*args,**kargs):
print "DeviceClicked"
cdev = None
for dev in self.devices:
if dev.name == obj.name_get():
cdev = dev
if not cdev:
return
self.current_device = cdev
dbox = mkbase.EFLBuildObject(self.win,self.gui_devicebox,self.config)
self.config["obj_device_content"].content_set(cdev.BuildDevice())
self.pager.content_push(dbox)
def DeviceDiscardClicked(self,obj,*args,**kargs):
print "DeviceDiscardClicked"
self.pager.content_pop()
def DeviceApplyClicked(self,obj,*args,**kargs):
print "DeviceApplyClicked"
ibox = mkbase.EFLBuildObject(self.win,self.gui_infobox,self.config)
self.pager.content_pop()
self.pager.content_push(ibox)
self.current_device.UpdateConfig()
self.current_device.Apply(self.LogEntry)
def InfoDoneClicked(self,obj,*args,**kargs):
print "InfoDoneClicked"
self.pager.content_pop()
def SaveProfileClicked(self,obj,*args,**kargs):
print "SaveProfileClicked"
pbox = mkbase.EFLBuildObject(self.win,self.gui_saveprofile,self.config)
self.pager.content_push(pbox)
def AboutClicked(self,obj,*args,**kargs):
print "AboutClicked"
self.about_hover.BuildHoverMessage()
def ExitClicked(self,obj,*args,**kargs):
print "ExitClicked"
self.exit_func()
def BuildMenu(self):
return mkbase.EFLBuildObject(self.win,self.gui_menu,self.config)
def SaveConfig(self):
# global config
save_dict = {}
for key in self.config:
if not (key.startswith("cfg_") or key.startswith("obj_")):
save_dict[key] = self.config[key]
# save devices config
dev_dict = {}
for dev in self.devices:
dev_dict[dev.name] = dev.ExportConfig()
# write to python file
fh = file(os.path.join(sys.path[0],"mkconfig.py"),"wt")
fh.write("menu_config = %s\n" % str(save_dict))
fh.write("devices_config = %s\n" % str(dev_dict))
fh.close()
def LoadConfig(self):
# global config
try:
cfgmod = __import__("mkconfig")
except:
print "No mkconfig.py, loading default config"
return
for k in cfgmod.menu_config:
self.config[k] = cfgmod.menu_config[k]
# load devices
for dev in self.devices:
if dev.name in cfgmod.devices_config:
dev.ImportConfig(cfgmod.devices_config[dev.name])