1/*
2 * Copyright 2003-2009, Haiku. All rights reserved.
3 * Distributed under the terms of the MIT License.
4 *
5 * Authors:
6 *		Jérôme Duval
7 *		François Revol
8 *		Marcus Overhagen
9 *		Jonas Sundström
10 */
11
12//! VolumeControl and link items in Deskbar
13
14#include "desklink.h"
15
16#include <stdio.h>
17#include <stdlib.h>
18
19#include <Alert.h>
20#include <Application.h>
21#include <Deskbar.h>
22#include <MimeType.h>
23#include <Roster.h>
24#include <String.h>
25
26#include "DeskButton.h"
27#include "VolumeWindow.h"
28
29
30const char *kAppSignature = "application/x-vnd.Haiku-desklink";
31	// the application signature used by the replicant to find the
32	// supporting code
33
34
35int
36main(int, char **argv)
37{
38	BApplication app(kAppSignature);
39	bool atLeastOnePath = false;
40	BList titleList;
41	BList actionList;
42	BDeskbar deskbar;
43	status_t err = B_OK;
44
45	for (int32 i = 1; argv[i]!=NULL; i++) {
46		if (strcmp(argv[i], "--help") == 0)
47			break;
48
49		if (strcmp(argv[i], "--list") == 0) {
50			int32 count = deskbar.CountItems();
51			int32 found = 0;
52			int32 j = 0;
53			printf("Deskbar items:\n");
54
55			while (found < count) {
56				const char *name = NULL;
57				if (deskbar.GetItemInfo(j, &name) == B_OK) {
58					printf("Item %ld: '%s'\n", j, name);
59					free((void *)name);
60					found++;
61				}
62				j++;
63			}
64			return 0;
65		}
66
67		if (strcmp(argv[i], "--add-volume") == 0) {
68			entry_ref ref;
69			if (get_ref_for_path(argv[0], &ref) == B_OK) {
70				deskbar.AddItem(&ref);
71			}
72			return 0;
73		}
74
75		if (strcmp(argv[i], "--volume-control") == 0) {
76			BWindow* window = new VolumeWindow(BRect(200, 150, 400, 200));
77			window->Show();
78
79			wait_for_thread(window->Thread(), NULL);
80			return 0;
81		}
82
83		if (strncmp(argv[i], "--remove", 8) == 0) {
84			BString replicant = "DeskButton";
85			if (strncmp(argv[i] + 8, "=", 1) == 0) {
86				if (strlen(argv[i] + 9) > 0) {
87					replicant = argv[i] + 9;
88				} else {
89					printf("desklink: Missing replicant name.\n");
90					return 1;
91				}
92			}
93			int32 found = 0;
94			int32 found_id;
95			while (deskbar.GetItemInfo(replicant.String(), &found_id) == B_OK) {
96				err = deskbar.RemoveItem(found_id);
97				if (err != B_OK) {
98					printf("desklink: Error removing replicant id %ld: %s\n",
99						found_id, strerror(err));
100					break;
101				}
102				found++;
103			}
104			printf("Removed %ld items.\n", found);
105			return err;
106		}
107
108		if (strncmp(argv[i], "cmd=", 4) == 0) {
109			BString *title = new BString(argv[i] + 4);
110			int32 index = title->FindFirst(':');
111			if (index <= 0) {
112				printf("desklink: usage: cmd=title:action\n");
113			} else {
114				title->Truncate(index);
115				BString *action = new BString(argv[i] + 4);
116				action->Remove(0, index+1);
117				titleList.AddItem(title);
118				actionList.AddItem(action);
119			}
120			continue;
121		}
122
123		atLeastOnePath = true;
124
125		BEntry entry(argv[i], true);
126		entry_ref ref;
127
128		if (entry.Exists()) {
129			entry.GetRef(&ref);
130		} else if (BMimeType::IsValid(argv[i])) {
131			if (be_roster->FindApp(argv[i], &ref) != B_OK) {
132				printf("desklink: cannot find '%s'\n", argv[i]);
133				return 1;
134			}
135		} else {
136			printf("desklink: cannot find '%s'\n", argv[i]);
137			return 1;
138		}
139
140		err = deskbar.AddItem(&ref);
141		if (err != B_OK) {
142			err = deskbar.AddItem(new DeskButton(BRect(0, 0, 15, 15),
143				&ref, ref.name, titleList, actionList));
144			if (err != B_OK) {
145				printf("desklink: Deskbar refuses link to '%s': %s\n", argv[i], strerror(err));
146				return 1;
147			}
148		}
149
150		titleList.MakeEmpty();
151		actionList.MakeEmpty();
152	}
153
154	if (!atLeastOnePath) {
155		printf(	"usage: desklink { [ --list|--remove|[cmd=title:action ... ] [ path|signature ] } ...\n"
156			"--add-volume: install volume control into Deskbar.\n"
157			"--volume-control: show window with global volume control.\n"
158			"--list: list all Deskbar addons.\n"
159			"--remove: remove all desklink addons.\n"
160			"--remove=name: remove all 'name' addons.\n");
161		return 1;
162	}
163
164	return 0;
165}
166