Beispiel #1
0
// New creates an applet preview widget.
//
func New(log cdtype.Logger) *Preview {
	builder := buildhelp.New()
	builder.AddFromString(string(appletpreviewXML()))
	// builder.AddFromFile("appletpreview.xml")

	widget := &Preview{
		Box:          *builder.GetBox("widget"),
		title:        builder.GetLabel("title"),
		author:       builder.GetLabel("author"),
		size:         builder.GetLabel("size"),
		stateText:    builder.GetLabel("stateText"),
		stateIcon:    builder.GetImage("stateIcon"),
		description:  builder.GetLabel("description"),
		previewFrame: builder.GetFrame("previewFrame"),
		previewImage: builder.GetImage("previewImage"),
		log:          log,
	}

	if len(builder.Errors) > 0 {
		for _, e := range builder.Errors {
			log.Err(e, "build appletpreview")
		}
		return nil
	}

	widget.Connect("destroy", widget.RemoveTmpFile)

	return widget
}
Beispiel #2
0
// NewFromFileSafe creates a config page builder from the file.
//
// If the load file failed, an error widget is returned with false.
//
func NewFromFileSafe(source cftype.Source, log cdtype.Logger, file, originalConf, gettextDomain string) (cftype.Grouper, bool) {
	build, e := NewFromFile(source, log, file, originalConf, gettextDomain)
	if !log.Err(e, "Load config file", file) {
		return build, true // Load ok, return it.
	}

	// Load failed. Build a warning widget from virtual source.

	conf := vstorage.NewVirtual(file, originalConf)
	build = newFromStorage(source, log, conf, originalConf, gettextDomain)

	group := "problem"
	build.AddGroup(group,
		newkey.Frame(group, "fail", "Load failed", "dialog-error"),
		newkey.TextLabel(group, "text", "Can't load the configuration file to build the interface."),
		newkey.TextLabel(group, "file", file),
	)

	hack := TweakKeyMakeWidget(group, "file", func(key *cftype.Key) {
		key.Label().SetLineWrap(true)
		// key.Label().SetJustify(gtk.JUSTIFY_FILL)
		key.Label().SetSelectable(true)
	})

	return build.BuildSingle(group, hack), false
}
Beispiel #3
0
// New creates a dock shortkeys management widget.
//
func New(control cftype.Source, log cdtype.Logger, btn btnaction.Tune) *Shortkeys {
	builder := buildhelp.NewFromBytes(confshortkeysXML())

	widget := &Shortkeys{
		ScrolledWindow: *builder.GetScrolledWindow("widget"),
		model:          builder.GetListStore("model"),
		tree:           builder.GetTreeView("tree"),
		selection:      builder.GetTreeSelection("selection"),
		control:        control,
		btn:            btn,
		log:            log,
		rows:           make(map[*gtk.TreeIter]cdglobal.Shortkeyer),
	}

	rend := builder.GetCellRendererText("cellrenderertextShortkey")

	if len(builder.Errors) > 0 {
		for _, e := range builder.Errors {
			log.Err(e, "build confshortkeys")
		}
		return nil
	}

	// The user is allowed to edit the shortcut text. This will handle the new text.
	rend.Connect("edited", widget.onManualEdit)

	widget.Load()
	return widget
}
Beispiel #4
0
// NewList creates cairo-dock main config pages list.
//
func NewList(control controlItems, log cdtype.Logger) *List {
	builder := buildhelp.NewFromBytes(confcoreXML())

	widget := &List{
		ScrolledWindow: *builder.GetScrolledWindow("widget"),
		model:          builder.GetListStore("model"),
		tree:           builder.GetTreeView("tree"),
		selection:      builder.GetTreeSelection("selection"),
		control:        control,
		log:            log,
		rows:           make(map[string]*row),
	}

	if len(builder.Errors) > 0 {
		for _, e := range builder.Errors {
			log.Err(e, "build confcore list")
		}
		return nil
	}

	// Action: Treeview Select line.
	widget.selection.Connect("changed", widget.onSelectionChanged)

	return widget
}
Beispiel #5
0
func getValueListCombo(widget *gtk.ComboBox, model *gtk.ListStore, log cdtype.Logger) func() interface{} {
	return func() interface{} {
		iter, _ := widget.GetActiveIter()
		text, e := getActiveRowInCombo(model, iter)
		log.Err(e, "ListIcons")
		return text
	}
}
Beispiel #6
0
// InfoApplet asks the dock all informations about an applet.
//
func InfoApplet(log cdtype.Logger, name string) *packages.AppletPackage {
	vars, _ := DockProperties("type=Module & name=" + name)
	if len(vars) == 0 {
		log.NewErr("unknown applet", "InfoApplet", name)
		return nil
	}
	pack, _ := parseApplet(log, vars[0])
	return pack
}
Beispiel #7
0
// ListFieldsIDByName searches the list of fields for the matching key.
// Returns the position of the field in the list.
// Returns 0 if not found, to have a valid entry to select.
//
func ListFieldsIDByName(fields []Field, key string, log cdtype.Logger) int {
	for i, field := range fields {
		if key == field.Key {
			return i
		}
	}
	if log != nil {
		log.NewErr("not found", "ListFieldsIDByName", key, fields)
	}
	return 0
}
Beispiel #8
0
// NewYTDLFile creates a video file downloader.
//
func NewYTDLFile(log cdtype.Logger, url string) (Filer, error) {
	info, e := ytdl.GetVideoInfo(url)
	if e != nil {
		return nil, fmt.Errorf("Unable to fetch video info: %s", e.Error())
	}

	// formats := info.Formats
	// // parse filter arguments, and filter through formats
	// for _, filter := range options.filters {
	// 	filter, e := parseFilter(filter)
	// 	if !log.Err(e) {
	// 		formats = filter(formats)
	// 	}
	// }
	// if len(formats) == 0 {
	// 	return nil, fmt.Errorf("No formats available that match criteria: %s", e.Error())
	// }

	log.Info("Author", info.Author)
	log.Info("Description", info.Description)
	log.Info("ID", info.ID)
	log.Info("vid", info)

	var list []*Format
	for _, v := range info.Formats {
		nf := &Format{
			Itag:          v.Itag,
			Extension:     v.Extension,
			Resolution:    v.Resolution,
			VideoEncoding: v.VideoEncoding,
			AudioEncoding: v.AudioEncoding,
			AudioBitrate:  v.AudioBitrate,
		}

		s := v.ValueForKey("clen")
		if s != nil {
			nf.Size, e = strconv.Atoi(s.(string))
			nf.Size /= 1000000
			log.Err(e, "convert size. format=", v.Itag)
			// } else {
			// log.Info("no clen", v.Itag)
		}

		list = append(list, nf)
	}

	// pretty.Println(info)

	return &YTDLFile{
		VideoInfo: *info,
		formats:   list,
		log:       log,
	}, nil
}
Beispiel #9
0
// New creates a welcome widget with informations about the program.
//
func New(source cftype.Source, log cdtype.Logger, switcher *pageswitch.Switcher) cftype.Grouper {
	const group = "Dev"
	title := tran.Slate("hi")

	// all packages in the application gopath.
	pathGoTest := strings.Join(append(cdglobal.AppBuildPath, "..."), "/")

	pathTestConfCmd := cdglobal.AppBuildPathFull("test", "confcmd", "confcmd.go")
	pathTestConfGUI := cdglobal.AppBuildPathFull("test", "confgui", "confgui.go")
	pathTestConfCmd, _ = filepath.EvalSymlinks(pathTestConfCmd)
	pathTestConfGUI, _ = filepath.EvalSymlinks(pathTestConfGUI)

	printConfig := func(showAll bool) {
		path := source.MainConfigFile()
		def := source.MainConfigDefault()

		otherSw := pageswitch.New()
		defer otherSw.Destroy()
		build, e := cfbuild.NewFromFile(source, log, path, def, "")
		if !log.Err(e, "load current dock config file") {
			// build.BuildSingle("TaskBar")
			build.BuildAll(otherSw)
			println("conf", path, def)
			cfprint.Default(build, showAll)
			build.Destroy()
		}
	}

	buildInfo := cfbuild.TweakAddGroup(group,
		newkey.TextLabel(group, "txt_title", common.Bold(common.Big(title))),
		newkey.Separator(group, "sep_title"),
		newkey.TextLabel(group, "txt_dev_page", "Test page, with useful tools for the developer."),
		newkey.CustomButtonLabel(group, "printConfig", "Print configuration", "show mainconf edited", func() { printConfig(false) }),
		newkey.CustomButtonLabel(group, "printConfig", "Print configuration", "show mainconf all", func() { printConfig(true) }),
		newkey.Separator(group, "sep_go_area"),
		newkey.TextLabel(group, "txt_go_area", "<b>Those commands requires the application sources in their Go environment</b>."),
		newkey.Separator(group, "sep_tests_gui"),
		newkey.LaunchCommand(group, "testConfGUI", "Launch config GUI test", "go run "+pathTestConfGUI),
		newkey.Separator(group, "sep_tests_cmd"),
		newkey.LaunchCommand(group, "testConfGUI", "Launch config console test", "go run "+pathTestConfCmd),
		newkey.LaunchCommand(group, "testConfGUI", "Launch config console mainconf diff", "go run "+pathTestConfCmd+" "+source.MainConfigFile()),
		newkey.Separator(group, "sep_tests_go"),
		newkey.LaunchCommand(group, "gotest", "Launch go tests", "go test "+pathGoTest),
		newkey.LaunchCommand(group, "golint", "Launch go lint", "golint "+pathGoTest),
		newkey.LaunchCommand(group, "govet", "Launch go vet", "go vet "+pathGoTest),
	)

	build := cfbuild.NewVirtual(source, log, "", "", "").BuildAll(switcher, buildInfo)

	build.ShowAll()
	return build
}
Beispiel #10
0
// NewServer creates a Dbus service.
//
func NewServer(srvObj, srvPath string, log cdtype.Logger) *Server {
	conn, c, e := SessionBus()
	if log.Err(e, "DBus Connect") {
		return nil
	}

	load := &Server{
		Conn:    conn,
		Events:  c,
		Log:     log,
		srvObj:  srvObj,
		srvPath: srvPath,
	}

	return load
}
Beispiel #11
0
// NewBuilder creates the target renderer/builder.
// The name is mandatory for a single applet (internal or not).
//
func NewBuilder(target SourceType, name string, log cdtype.Logger) Builder {
	switch target {

	case TypeGodock:
		build := &BuilderGodock{}
		build.SetLogger(log)
		return build

	case TypeCore:
		build := &BuilderCore{}
		build.SetLogger(log)
		return build

	case TypeApplets:
		build := &BuilderApplets{}
		build.SetLogger(log)
		return build

	case TypeAppletCompiled:
		dir, icon := AppletInfo(log, name)
		if dir == "" {
			log.NewErr("applet not found: "+name, "new builder")
			return &BuilderNull{}
		}

		build := &BuilderCompiled{Module: name}
		build.SetLogger(log)
		build.SetIcon(icon)
		build.SetDir(dir)
		return build

	case TypeAppletInternal:
		// Ask icon of module to the Dock as we can't guess its dir and icon name.
		_, icon := AppletInfo(log, strings.Replace(name, "-", " ", -1))
		if icon == "" {
			icon = IconMissing
		}

		build := &BuilderInternal{Module: name}
		build.SetLogger(log)
		build.SetIcon(icon)
		return build
	}

	// ensure we have a valid target.
	return &BuilderNull{}
}
Beispiel #12
0
// NewFromFile creates a config page builder from the file.
//
func NewFromFile(source cftype.Source, log cdtype.Logger, configFile, originalConf, gettextDomain string) (cftype.Grouper, error) {
	storage, e := LoadFile(configFile, originalConf)
	if e != nil {
		log.Err(e, "NewFromFile")
		return nil, e
	}
	grouper := newFromStorage(source, log, storage, originalConf, gettextDomain)
	grouper.free = func() {
		grouper.keyFile = &storage.KeyFile // MOVE ONE LINE UP ?
		grouper.Builder.Free()
		storage.KeyFile.Free()
		if storage.def != nil {
			storage.def.Free()
		}
	}
	return grouper, nil
}
Beispiel #13
0
// ListIcons asks the dock the list of active icons.
//
// TODO: add argument for advanced queries.
// would be cool to have argument list.
//
func ListIcons(log cdtype.Logger) (list []*CDIcon) {
	iconsInfo, e := DockProperties("type=Icon")
	log.Err(e, "ListIcons")
	for _, props := range iconsInfo {
		ic := &CDIcon{log: log}
		for k, v := range props {
			ic.getProp(k, v)

		}
		// if ic.Name == "" {
		// 	log.NewErr("ListIcons name empty", ic.Type, ic.ConfigFile)
		// } else {
		list = append(list, ic)
		// }
	}
	return
}
Beispiel #14
0
// NewList creates a new applets list widget.
//
func NewList(control ControlDownload, log cdtype.Logger) *List {
	builder := buildhelp.New()

	builder.AddFromString(string(appletlistXML()))
	// builder.AddFromFile("appletlist.xml")

	widget := &List{
		ScrolledWindow: *builder.GetScrolledWindow("widget"),
		model:          builder.GetListStore("model"),
		tree:           builder.GetTreeView("tree"),
		columnCategory: builder.GetTreeViewColumn("columnCategory"),
		control:        control,
		log:            log,
		rows:           make(map[string]*Row),
	}

	columnName := builder.GetTreeViewColumn("columnName")

	if len(builder.Errors) > 0 {
		for _, e := range builder.Errors {
			log.Err(e, "build appletlist")
		}
		return nil
	}

	control.SetControlInstall(widget)

	// Double click launch add action.
	widget.tree.Connect("button-press-event", func(tree *gtk.TreeView, ev *gdk.Event) {
		btn := &gdk.EventButton{Event: ev}
		if btn.Button() == 1 && btn.Type() == gdk.EVENT_2BUTTON_PRESS {
			control.Save()
		}
	})

	// Action: Treeview Select line.
	if sel, e := widget.tree.GetSelection(); !log.Err(e, "appletlist TreeView.GetSelection") {
		sel.Connect("changed", widget.onSelectionChanged) // Changed is connected to TreeSelection
	}

	// Sort applets by name.
	columnName.Emit("clicked")

	return widget
}
Beispiel #15
0
// Run starts dock routines and locks the main thread with gtk.
//
// It wraps all backends and clients to start a dock :
// Dbus server, applets manager, GUI, menu and gldi.
//
// Dbus service is enabled by default. Mandatory if enabled, to provide remote control.
// This will prevent launching a 2nd instance without the disable Dbus service option.
//
// You can add custom changes, launched before the start, with CustomHacks.
//
// Run returns true if the dock is able to start. This can be done with:
//   gldi.Lock()      // alias for gtk_main.
//   maindock.Clean() // may be better with defer, but cause confused panic messages.
//
func Run(log cdtype.Logger, getSettings func() maindock.DockSettings) bool {
	settings := getSettings()

	// Logger debug state.
	log.SetDebug(settings.Debug)
	maindock.SetLogger(log)

	// Dock init.
	settings.Init()

	// Load new config settings. New options are in an other file to keep the
	// original config file as compatible with the real dock as possible.
	file, e := globals.DirUserAppData(confown.GuiFilename)
	e = confown.Init(log, file, e)
	log.Err(e, "Load ConfigSettings")

	// Register go internal applets events.
	appmgr := mgrgldi.Register(log)

	// Start the polling loop for go internal applets (can be in DBus with other events).
	if settings.DisableDBus {
		go appmgr.StartLoop()

	} else {
		// DBus service is mandatory if enabled. This prevent double launch.
		dbus, e := serviceDbus(log)
		if log.Err(e, "start dbus service") {
			fmt.Println("restart the program with the -N flag if you really need a second instance")
			return false
		}
		dbus.SetManager(appmgr)
		go dbus.StartLoop()
	}

	// HTTP listener for the pprof debug.
	if settings.HTTPPprof {
		websrv.Service.Register("debug/pprof", pprof.Index, log)
		websrv.Service.Start("debug/pprof")
	}

	// Print useful packages versions.
	versions.Print()

	// Custom calls added by devs for their own uses and tests.
	CustomHacks()

	// Register GUI events.
	backendgui.Register(guibridge.New(log))

	// Register mouse events.
	eventmouse.Register(log)

	// Register menus events.
	backendmenu.Register(log, mainmenu.BuildMenuContainer, mainmenu.BuildMenuIcon)

	// Finish startup.
	settings.Start()

	return true
}
Beispiel #16
0
// Init will try to load the own config data from the file, and create it if missing.
//
func Init(log cdtype.Logger, file string, e error) error {
	if e != nil {
		return e
	}

	// Create file if needed.
	if !files.IsExist(file) {
		source := globals.DirShareData(GuiFilename)
		e := files.CopyFile(source, file, os.FileMode(0644))
		if e != nil {
			return e
		}
		log.Info("created config file", file)
	}

	// Create our user settings
	Settings = ConfigSettings{
		File: file,
		log:  log,
	}
	return Settings.Load()
}
Beispiel #17
0
// NewMenuDownload creates the menu to control the selected applet.
//
func NewMenuDownload(log cdtype.Logger) *MenuDownload {
	widget := &MenuDownload{
		Box:       *newgtk.Box(gtk.ORIENTATION_HORIZONTAL, 0),
		installed: newgtk.Switch(),
		active:    newgtk.Switch(),
		log:       log,
	}

	// Actions
	var e error
	widget.handlerInstalled, e = widget.installed.Connect("notify::active", widget.toggledInstalled)
	log.Err(e, "Connect installed button callback")
	widget.handlerActive, e = widget.active.Connect("notify::active", widget.toggledActive)
	log.Err(e, "Connect active button callback")

	widget.PackStart(newgtk.Label("Installed"), false, false, 4)
	widget.PackStart(widget.installed, false, false, 0)
	widget.PackStart(newgtk.Box(gtk.ORIENTATION_VERTICAL, 0), false, false, 8)
	widget.PackStart(newgtk.Label("Active"), false, false, 4)
	widget.PackStart(widget.active, false, false, 0)
	return widget
}
Beispiel #18
0
func (o *dockIcon) LaunchCommand(log cdtype.Logger, args ...string) bool {
	cmd := o.GetCommand()
	switch {
	case cmd == "":

	case cmd[0] == '<': // Launch as shortkey.
		success := shortkeys.Trigger(cmd)
		if success {
			return true
		}

		// try also as exec.
		exec, e := log.ExecShlex(cmd, args...)
		if log.Err(e, "parse command", cmd) {
			return false
		}

		e = exec.Run()
		return e == nil

	default: // Exec command.
		exec, e := log.ExecShlex(cmd, args...)
		if log.Err(e, "parse command", cmd) {
			return false
		}

		e = exec.Run()
		if log.Err(e, "launch command", cmd, strings.Join(args, " ")) {
			// try also as shortkey.
			return shortkeys.Trigger(cmd)
		}

		return true
	}

	return false
}
Beispiel #19
0
// New creates a handbook widget (applet info).
//
func New(log cdtype.Logger) *Handbook {
	builder := buildhelp.New()

	builder.AddFromString(string(handbookXML()))
	// builder.AddFromFile("handbook.xml")

	widget := &Handbook{
		Frame:        *builder.GetFrame("handbook"),
		title:        builder.GetLabel("title"),
		author:       builder.GetLabel("author"),
		description:  builder.GetLabel("description"),
		previewFrame: builder.GetFrame("previewFrame"),
		previewImage: builder.GetImage("previewImage"),
	}

	if len(builder.Errors) > 0 {
		for _, e := range builder.Errors {
			log.Err(e, "build handbook")
		}
		return nil
	}

	return widget
}
Beispiel #20
0
// AccessUnlock releases the access to config files.
//
func AccessUnlock(log cdtype.Logger) {
	log.Debug("files.Access", "Unlock")
	access.Unlock()
}
Beispiel #21
0
// AccessLock locks and prevents concurrent access to config files.
// Could be improved, but it may be safer to use for now.
//
func AccessLock(log cdtype.Logger) {
	log.Debug("files.Access", "Lock")
	access.Lock()
}