102be5353SAxel Dörfler/*
202be5353SAxel DörflerOpen Tracker License
302be5353SAxel Dörfler
402be5353SAxel DörflerTerms and Conditions
502be5353SAxel Dörfler
602be5353SAxel DörflerCopyright (c) 1991-2000, Be Incorporated. All rights reserved.
702be5353SAxel Dörfler
802be5353SAxel DörflerPermission is hereby granted, free of charge, to any person obtaining a copy of
902be5353SAxel Dörflerthis software and associated documentation files (the "Software"), to deal in
1002be5353SAxel Dörflerthe Software without restriction, including without limitation the rights to
1102be5353SAxel Dörfleruse, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
1202be5353SAxel Dörflerof the Software, and to permit persons to whom the Software is furnished to do
1302be5353SAxel Dörflerso, subject to the following conditions:
1402be5353SAxel Dörfler
1502be5353SAxel DörflerThe above copyright notice and this permission notice applies to all licensees
1602be5353SAxel Dörflerand shall be included in all copies or substantial portions of the Software.
1702be5353SAxel Dörfler
1802be5353SAxel DörflerTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
1902be5353SAxel DörflerIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF TITLE, MERCHANTABILITY,
2002be5353SAxel DörflerFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
2102be5353SAxel DörflerBE INCORPORATED BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
2202be5353SAxel DörflerAN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF, OR IN CONNECTION
2302be5353SAxel DörflerWITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
2402be5353SAxel Dörfler
2502be5353SAxel DörflerExcept as contained in this notice, the name of Be Incorporated shall not be
2602be5353SAxel Dörflerused in advertising or otherwise to promote the sale, use or other dealings in
2702be5353SAxel Dörflerthis Software without prior written authorization from Be Incorporated.
2802be5353SAxel Dörfler
2902be5353SAxel DörflerTracker(TM), Be(R), BeOS(R), and BeIA(TM) are trademarks or registered trademarks
3002be5353SAxel Dörflerof Be Incorporated in the United States and other countries. Other brand product
3102be5353SAxel Dörflernames are registered trademarks or trademarks of their respective holders.
3202be5353SAxel DörflerAll rights reserved.
3302be5353SAxel Dörfler*/
3402be5353SAxel Dörfler
358e5c1f23SJohn Scipione
368e5c1f23SJohn Scipione#include "DeskWindow.h"
378e5c1f23SJohn Scipione
384ed28a57SAlexandre Deckner#include <Catalog.h>
3902be5353SAxel Dörfler#include <Debug.h>
4002be5353SAxel Dörfler#include <FindDirectory.h>
414ed28a57SAlexandre Deckner#include <Locale.h>
4227c555cbSMarkus Himmel#include <Messenger.h>
4302be5353SAxel Dörfler#include <NodeMonitor.h>
4402be5353SAxel Dörfler#include <Path.h>
451f17f750SJohn Scipione#include <PathFinder.h>
46d058a4aeSPhilippe Saint-Pierre#include <PathMonitor.h>
4702be5353SAxel Dörfler#include <PopUpMenu.h>
48d058a4aeSPhilippe Saint-Pierre#include <Resources.h>
4902be5353SAxel Dörfler#include <Screen.h>
501f17f750SJohn Scipione#include <String.h>
511f17f750SJohn Scipione#include <StringList.h>
5202be5353SAxel Dörfler#include <Volume.h>
533798bf90SAugustin Cavalier#include <WindowPrivate.h>
5402be5353SAxel Dörfler
5502be5353SAxel Dörfler#include <fcntl.h>
5602be5353SAxel Dörfler#include <unistd.h>
5702be5353SAxel Dörfler
5802be5353SAxel Dörfler#include "Attributes.h"
5902be5353SAxel Dörfler#include "AutoLock.h"
6002be5353SAxel Dörfler#include "BackgroundImage.h"
6102be5353SAxel Dörfler#include "Commands.h"
6202be5353SAxel Dörfler#include "FSUtils.h"
6302be5353SAxel Dörfler#include "IconMenuItem.h"
64d058a4aeSPhilippe Saint-Pierre#include "KeyInfos.h"
6502be5353SAxel Dörfler#include "MountMenu.h"
6602be5353SAxel Dörfler#include "PoseView.h"
6702be5353SAxel Dörfler#include "Tracker.h"
6802be5353SAxel Dörfler#include "TemplatesMenu.h"
6902be5353SAxel Dörfler
7002be5353SAxel Dörfler
71b05aa8b5SJohn Scipioneconst char* kShelfPath = "tracker_shelf";
7202be5353SAxel Dörfler	// replicant support
7302be5353SAxel Dörfler
74d058a4aeSPhilippe Saint-Pierreconst char* kShortcutsSettings = "shortcuts_settings";
753fe41617SPhilippe Saint-Pierreconst char* kDefaultShortcut = "BEOS:default_shortcut";
76d058a4aeSPhilippe Saint-Pierreconst uint32 kDefaultModifiers = B_OPTION_KEY | B_COMMAND_KEY;
7702be5353SAxel Dörfler
786cf062b9SJohn Scipione
79d058a4aeSPhilippe Saint-Pierrestatic struct AddonShortcut*
80d058a4aeSPhilippe Saint-PierreMatchOne(struct AddonShortcut* item, void* castToName)
8132ac1033SAxel Dörfler{
82d058a4aeSPhilippe Saint-Pierre	if (strcmp(item->model->Name(), (const char*)castToName) == 0) {
83d058a4aeSPhilippe Saint-Pierre		// found match, bail out
84d058a4aeSPhilippe Saint-Pierre		return item;
8532ac1033SAxel Dörfler	}
8632ac1033SAxel Dörfler
87d058a4aeSPhilippe Saint-Pierre	return 0;
88d058a4aeSPhilippe Saint-Pierre}
8932ac1033SAxel Dörfler
9032ac1033SAxel Dörfler
91d058a4aeSPhilippe Saint-Pierrestatic void
92d058a4aeSPhilippe Saint-PierreAddOneShortcut(Model* model, char key, uint32 modifiers, BDeskWindow* window)
9332ac1033SAxel Dörfler{
94d058a4aeSPhilippe Saint-Pierre	if (key == '\0')
95d058a4aeSPhilippe Saint-Pierre		return;
966cf062b9SJohn Scipione
97b05aa8b5SJohn Scipione	BMessage* runAddon = new BMessage(kLoadAddOn);
9832ac1033SAxel Dörfler	runAddon->AddRef("refs", model->EntryRef());
99d058a4aeSPhilippe Saint-Pierre	window->AddShortcut(key, modifiers, runAddon);
100d058a4aeSPhilippe Saint-Pierre}
10132ac1033SAxel Dörfler
10232ac1033SAxel Dörfler
103d058a4aeSPhilippe Saint-Pierre
104d058a4aeSPhilippe Saint-Pierrestatic struct AddonShortcut*
105d058a4aeSPhilippe Saint-PierreRevertToDefault(struct AddonShortcut* item, void* castToWindow)
106d058a4aeSPhilippe Saint-Pierre{
107d058a4aeSPhilippe Saint-Pierre	if (item->key != item->defaultKey || item->modifiers != kDefaultModifiers) {
108d058a4aeSPhilippe Saint-Pierre		BDeskWindow* window = static_cast<BDeskWindow*>(castToWindow);
109d058a4aeSPhilippe Saint-Pierre		if (window != NULL) {
110d058a4aeSPhilippe Saint-Pierre			window->RemoveShortcut(item->key, item->modifiers);
111d058a4aeSPhilippe Saint-Pierre			item->key = item->defaultKey;
112d058a4aeSPhilippe Saint-Pierre			item->modifiers = kDefaultModifiers;
113d058a4aeSPhilippe Saint-Pierre			AddOneShortcut(item->model, item->key, item->modifiers, window);
114d058a4aeSPhilippe Saint-Pierre		}
115d058a4aeSPhilippe Saint-Pierre	}
1166cf062b9SJohn Scipione
117d058a4aeSPhilippe Saint-Pierre	return 0;
118d058a4aeSPhilippe Saint-Pierre}
119d058a4aeSPhilippe Saint-Pierre
120d058a4aeSPhilippe Saint-Pierre
121d058a4aeSPhilippe Saint-Pierrestatic struct AddonShortcut*
122d058a4aeSPhilippe Saint-PierreFindElement(struct AddonShortcut* item, void* castToOther)
123d058a4aeSPhilippe Saint-Pierre{
124d058a4aeSPhilippe Saint-Pierre	Model* other = static_cast<Model*>(castToOther);
125d058a4aeSPhilippe Saint-Pierre	if (*item->model->EntryRef() == *other->EntryRef())
126d058a4aeSPhilippe Saint-Pierre		return item;
127d058a4aeSPhilippe Saint-Pierre
128d058a4aeSPhilippe Saint-Pierre	return 0;
129d058a4aeSPhilippe Saint-Pierre}
130d058a4aeSPhilippe Saint-Pierre
131d058a4aeSPhilippe Saint-Pierre
132d058a4aeSPhilippe Saint-Pierrestatic void
1331f17f750SJohn ScipioneLoadAddOnDir(BDirectory directory, BDeskWindow* window,
134d058a4aeSPhilippe Saint-Pierre	LockingList<AddonShortcut>* list)
135d058a4aeSPhilippe Saint-Pierre{
1361f17f750SJohn Scipione	BEntry entry;
1371f17f750SJohn Scipione	while (directory.GetNextEntry(&entry) == B_OK) {
1381f17f750SJohn Scipione		Model* model = new Model(&entry);
1391f17f750SJohn Scipione		if (model->InitCheck() == B_OK && model->IsSymLink()) {
1401f17f750SJohn Scipione			// resolve symlinks
1411f17f750SJohn Scipione			Model* resolved = new Model(model->EntryRef(), true, true);
1421f17f750SJohn Scipione			if (resolved->InitCheck() == B_OK)
1431f17f750SJohn Scipione				model->SetLinkTo(resolved);
1441f17f750SJohn Scipione			else
1451f17f750SJohn Scipione				delete resolved;
1461f17f750SJohn Scipione		}
1471f17f750SJohn Scipione		if (model->InitCheck() != B_OK
1481f17f750SJohn Scipione			|| !model->ResolveIfLink()->IsExecutable()) {
1491f17f750SJohn Scipione			delete model;
1501f17f750SJohn Scipione			continue;
151d058a4aeSPhilippe Saint-Pierre		}
152d058a4aeSPhilippe Saint-Pierre
1531f17f750SJohn Scipione		char* name = strdup(model->Name());
1541f17f750SJohn Scipione		if (!list->EachElement(MatchOne, name)) {
1551f17f750SJohn Scipione			struct AddonShortcut* item = new struct AddonShortcut;
1561f17f750SJohn Scipione			item->model = model;
1571f17f750SJohn Scipione
1581f17f750SJohn Scipione			BResources resources(model->ResolveIfLink()->EntryRef());
1591f17f750SJohn Scipione			size_t size;
1601f17f750SJohn Scipione			char* shortcut = (char*)resources.LoadResource(B_STRING_TYPE,
1611f17f750SJohn Scipione				kDefaultShortcut, &size);
1621f17f750SJohn Scipione			if (shortcut == NULL || strlen(shortcut) > 1)
1631f17f750SJohn Scipione				item->key = '\0';
1641f17f750SJohn Scipione			else
1651f17f750SJohn Scipione				item->key = shortcut[0];
1661f17f750SJohn Scipione			AddOneShortcut(model, item->key, kDefaultModifiers, window);
1671f17f750SJohn Scipione			item->defaultKey = item->key;
1681f17f750SJohn Scipione			item->modifiers = kDefaultModifiers;
1691f17f750SJohn Scipione			list->AddItem(item);
1701f17f750SJohn Scipione		}
1711f17f750SJohn Scipione		free(name);
172d058a4aeSPhilippe Saint-Pierre	}
1731f17f750SJohn Scipione
1741f17f750SJohn Scipione	node_ref nodeRef;
1750546bdd5SJohn Scipione	directory.GetNodeRef(&nodeRef);
1761f17f750SJohn Scipione
1771f17f750SJohn Scipione	TTracker::WatchNode(&nodeRef, B_WATCH_DIRECTORY, window);
17832ac1033SAxel Dörfler}
17932ac1033SAxel Dörfler
18032ac1033SAxel Dörfler
1816cf062b9SJohn Scipione// #pragma mark - BDeskWindow
1826cf062b9SJohn Scipione
18332ac1033SAxel Dörfler
184546208a5SOliver Tappe#undef B_TRANSLATION_CONTEXT
185546208a5SOliver Tappe#define B_TRANSLATION_CONTEXT "DeskWindow"
18632ac1033SAxel Dörfler
1876cf062b9SJohn Scipione
188b05aa8b5SJohn ScipioneBDeskWindow::BDeskWindow(LockingList<BWindow>* windowList)
18932ac1033SAxel Dörfler	:
1903798bf90SAugustin Cavalier	BContainerWindow(windowList, 0, kDesktopWindowLook,
1913798bf90SAugustin Cavalier		kDesktopWindowFeel, B_NOT_MOVABLE | B_WILL_ACCEPT_FIRST_CLICK
19232ac1033SAxel Dörfler			| B_NOT_ZOOMABLE | B_NOT_CLOSABLE | B_NOT_MINIMIZABLE
193e7803cf1SAugustin Cavalier			| B_NOT_RESIZABLE | B_ASYNCHRONOUS_CONTROLS, B_ALL_WORKSPACES,
194e7803cf1SAugustin Cavalier			false, true),
1956cf062b9SJohn Scipione	fDeskShelf(NULL),
196d058a4aeSPhilippe Saint-Pierre	fNodeRef(NULL),
197d058a4aeSPhilippe Saint-Pierre	fShortcutsSettings(NULL)
19802be5353SAxel Dörfler{
19996da4b41SStephan Aßmus	// Add icon view switching shortcuts. These are displayed in the context
20096da4b41SStephan Aßmus	// menu, although they obviously don't work from those menu items.
20196da4b41SStephan Aßmus	BMessage* message = new BMessage(kIconMode);
20296da4b41SStephan Aßmus	AddShortcut('1', B_COMMAND_KEY, message, PoseView());
20396da4b41SStephan Aßmus
20496da4b41SStephan Aßmus	message = new BMessage(kMiniIconMode);
20596da4b41SStephan Aßmus	AddShortcut('2', B_COMMAND_KEY, message, PoseView());
20696da4b41SStephan Aßmus
20796da4b41SStephan Aßmus	message = new BMessage(kIconMode);
20896da4b41SStephan Aßmus	message->AddInt32("scale", 1);
20996da4b41SStephan Aßmus	AddShortcut('+', B_COMMAND_KEY, message, PoseView());
21096da4b41SStephan Aßmus
21196da4b41SStephan Aßmus	message = new BMessage(kIconMode);
21296da4b41SStephan Aßmus	message->AddInt32("scale", 0);
21396da4b41SStephan Aßmus	AddShortcut('-', B_COMMAND_KEY, message, PoseView());
21402be5353SAxel Dörfler}
21502be5353SAxel Dörfler
21602be5353SAxel Dörfler
21702be5353SAxel DörflerBDeskWindow::~BDeskWindow()
21802be5353SAxel Dörfler{
21902be5353SAxel Dörfler	SaveDesktopPoseLocations();
22002be5353SAxel Dörfler		// explicit call to SavePoseLocations so that extended pose info
22102be5353SAxel Dörfler		// gets committed properly
22202be5353SAxel Dörfler	PoseView()->DisableSaveLocation();
22302be5353SAxel Dörfler		// prevent double-saving, this would slow down quitting
22402be5353SAxel Dörfler	PoseView()->StopSettingsWatch();
22502be5353SAxel Dörfler	stop_watching(this);
22602be5353SAxel Dörfler}
22702be5353SAxel Dörfler
22802be5353SAxel Dörfler
22902be5353SAxel Dörflervoid
230b05aa8b5SJohn ScipioneBDeskWindow::Init(const BMessage*)
23102be5353SAxel Dörfler{
232ea001e58SJohn Scipione	// Set the size of the screen before calling the container window's
233ea001e58SJohn Scipione	// Init() because it will add volume poses to this window and
234ea001e58SJohn Scipione	// they will be clipped otherwise
235ea001e58SJohn Scipione
23602be5353SAxel Dörfler	BScreen screen(this);
23702be5353SAxel Dörfler	fOldFrame = screen.Frame();
23802be5353SAxel Dörfler
23902be5353SAxel Dörfler	PoseView()->SetShowHideSelection(false);
24002be5353SAxel Dörfler	ResizeTo(fOldFrame.Width(), fOldFrame.Height());
24102be5353SAxel Dörfler
242e7803cf1SAugustin Cavalier	InitKeyIndices();
243e7803cf1SAugustin Cavalier	InitAddonsList(false);
244e7803cf1SAugustin Cavalier	ApplyShortcutPreferences(false);
245e7803cf1SAugustin Cavalier
246e7803cf1SAugustin Cavalier	_inherited::Init();
247e7803cf1SAugustin Cavalier
24802be5353SAxel Dörfler	entry_ref ref;
24902be5353SAxel Dörfler	BPath path;
25002be5353SAxel Dörfler	if (!BootedInSafeMode() && FSFindTrackerSettingsDir(&path) == B_OK) {
25102be5353SAxel Dörfler		path.Append(kShelfPath);
2529437e677SJohn Scipione		close(open(path.Path(), O_RDONLY | O_CREAT, S_IRUSR | S_IWUSR
2539437e677SJohn Scipione			| S_IRGRP | S_IROTH));
25402be5353SAxel Dörfler		if (get_ref_for_path(path.Path(), &ref) == B_OK)
25502be5353SAxel Dörfler			fDeskShelf = new BShelf(&ref, fPoseView);
2569437e677SJohn Scipione
2579437e677SJohn Scipione		if (fDeskShelf != NULL)
25802be5353SAxel Dörfler			fDeskShelf->SetDisplaysZombies(true);
25902be5353SAxel Dörfler	}
26002be5353SAxel Dörfler}
26102be5353SAxel Dörfler
26202be5353SAxel Dörfler
26302be5353SAxel Dörflervoid
264d058a4aeSPhilippe Saint-PierreBDeskWindow::InitAddonsList(bool update)
26582d8aaf8SStephan Aßmus{
266d058a4aeSPhilippe Saint-Pierre	AutoLock<LockingList<AddonShortcut> > lock(fAddonsList);
267d058a4aeSPhilippe Saint-Pierre	if (lock.IsLocked()) {
268d058a4aeSPhilippe Saint-Pierre		if (update) {
269d058a4aeSPhilippe Saint-Pierre			for (int i = fAddonsList->CountItems() - 1; i >= 0; i--) {
270d058a4aeSPhilippe Saint-Pierre				AddonShortcut* item = fAddonsList->ItemAt(i);
271d058a4aeSPhilippe Saint-Pierre				RemoveShortcut(item->key, B_OPTION_KEY | B_COMMAND_KEY);
272d058a4aeSPhilippe Saint-Pierre			}
273d058a4aeSPhilippe Saint-Pierre			fAddonsList->MakeEmpty(true);
27402be5353SAxel Dörfler		}
27582d8aaf8SStephan Aßmus
2761f17f750SJohn Scipione		BStringList addOnPaths;
277784d5beaSJohn Scipione		BPathFinder::FindPaths(B_FIND_PATH_ADD_ONS_DIRECTORY, "Tracker",
2781f17f750SJohn Scipione			addOnPaths);
279784d5beaSJohn Scipione		int32 count = addOnPaths.CountStrings();
280784d5beaSJohn Scipione		for (int32 i = 0; i < count; i++) {
2811f17f750SJohn Scipione			LoadAddOnDir(BDirectory(addOnPaths.StringAt(i)), this,
2821f17f750SJohn Scipione				fAddonsList);
2831f17f750SJohn Scipione		}
284d058a4aeSPhilippe Saint-Pierre	}
285d058a4aeSPhilippe Saint-Pierre}
286d058a4aeSPhilippe Saint-Pierre
28702be5353SAxel Dörfler
288d058a4aeSPhilippe Saint-Pierrevoid
289d058a4aeSPhilippe Saint-PierreBDeskWindow::ApplyShortcutPreferences(bool update)
290d058a4aeSPhilippe Saint-Pierre{
291d058a4aeSPhilippe Saint-Pierre	AutoLock<LockingList<AddonShortcut> > lock(fAddonsList);
292d058a4aeSPhilippe Saint-Pierre	if (lock.IsLocked()) {
293d058a4aeSPhilippe Saint-Pierre		if (!update) {
294d058a4aeSPhilippe Saint-Pierre			BPath path;
295d058a4aeSPhilippe Saint-Pierre			if (find_directory(B_USER_SETTINGS_DIRECTORY, &path) == B_OK) {
2969437e677SJohn Scipione				BPathMonitor::StartWatching(path.Path(),
2979437e677SJohn Scipione					B_WATCH_STAT | B_WATCH_FILES_ONLY, this);
298d058a4aeSPhilippe Saint-Pierre				path.Append(kShortcutsSettings);
299d058a4aeSPhilippe Saint-Pierre				fShortcutsSettings = new char[strlen(path.Path()) + 1];
300d058a4aeSPhilippe Saint-Pierre				strcpy(fShortcutsSettings, path.Path());
301d058a4aeSPhilippe Saint-Pierre			}
302d058a4aeSPhilippe Saint-Pierre		}
30350d739deSPhilippe Saint-Pierre
304d058a4aeSPhilippe Saint-Pierre		fAddonsList->EachElement(RevertToDefault, this);
30550d739deSPhilippe Saint-Pierre
306d058a4aeSPhilippe Saint-Pierre		BFile shortcutSettings(fShortcutsSettings, B_READ_ONLY);
307d058a4aeSPhilippe Saint-Pierre		BMessage fileMsg;
308d058a4aeSPhilippe Saint-Pierre		if (shortcutSettings.InitCheck() != B_OK
309d058a4aeSPhilippe Saint-Pierre			|| fileMsg.Unflatten(&shortcutSettings) != B_OK) {
310d058a4aeSPhilippe Saint-Pierre			fNodeRef = NULL;
311d058a4aeSPhilippe Saint-Pierre			return;
312d058a4aeSPhilippe Saint-Pierre		}
313d058a4aeSPhilippe Saint-Pierre		shortcutSettings.GetNodeRef(fNodeRef);
314d058a4aeSPhilippe Saint-Pierre
3156cf062b9SJohn Scipione		int32 i = 0;
316d058a4aeSPhilippe Saint-Pierre		BMessage message;
317d058a4aeSPhilippe Saint-Pierre		while (fileMsg.FindMessage("spec", i++, &message) == B_OK) {
318d058a4aeSPhilippe Saint-Pierre			int32 key;
3194ba4d40bSPhilippe Saint-Pierre			if (message.FindInt32("key", &key) == B_OK) {
320d058a4aeSPhilippe Saint-Pierre				// only handle shortcuts referring add-ons
321d058a4aeSPhilippe Saint-Pierre				BString command;
3224ba4d40bSPhilippe Saint-Pierre				if (message.FindString("command", &command) != B_OK)
323d058a4aeSPhilippe Saint-Pierre					continue;
3249437e677SJohn Scipione
325d058a4aeSPhilippe Saint-Pierre				bool isInAddons = false;
3261f17f750SJohn Scipione
3271f17f750SJohn Scipione				BStringList addOnPaths;
3281f17f750SJohn Scipione				BPathFinder::FindPaths(B_FIND_PATH_ADD_ONS_DIRECTORY,
3291f17f750SJohn Scipione					"Tracker/", addOnPaths);
3301f17f750SJohn Scipione				for (int32 i = 0; i < addOnPaths.CountStrings(); i++) {
331ab97fc05SJohn Scipione					if (command.StartsWith(addOnPaths.StringAt(i))) {
3321f17f750SJohn Scipione						isInAddons = true;
3331f17f750SJohn Scipione						break;
3341f17f750SJohn Scipione					}
335cf70d345SIngo Weinhold				}
3361f17f750SJohn Scipione
337d058a4aeSPhilippe Saint-Pierre				if (!isInAddons)
338d058a4aeSPhilippe Saint-Pierre					continue;
339d058a4aeSPhilippe Saint-Pierre
340d058a4aeSPhilippe Saint-Pierre				BEntry entry(command);
341d058a4aeSPhilippe Saint-Pierre				if (entry.InitCheck() != B_OK)
342d058a4aeSPhilippe Saint-Pierre					continue;
343d058a4aeSPhilippe Saint-Pierre
344d058a4aeSPhilippe Saint-Pierre				const char* shortcut = GetKeyName(key);
345d058a4aeSPhilippe Saint-Pierre				if (strlen(shortcut) != 1)
346d058a4aeSPhilippe Saint-Pierre					continue;
3474ba4d40bSPhilippe Saint-Pierre
3484ba4d40bSPhilippe Saint-Pierre				uint32 modifiers = B_COMMAND_KEY;
3499437e677SJohn Scipione					// it's required by interface kit to at least
3509437e677SJohn Scipione					// have B_COMMAND_KEY
351d058a4aeSPhilippe Saint-Pierre				int32 value;
352d058a4aeSPhilippe Saint-Pierre				if (message.FindInt32("mcidx", 0, &value) == B_OK)
353d058a4aeSPhilippe Saint-Pierre					modifiers |= (value != 0 ? B_SHIFT_KEY : 0);
354d058a4aeSPhilippe Saint-Pierre
355d058a4aeSPhilippe Saint-Pierre				if (message.FindInt32("mcidx", 1, &value) == B_OK)
356d058a4aeSPhilippe Saint-Pierre					modifiers |= (value != 0 ? B_CONTROL_KEY : 0);
357d058a4aeSPhilippe Saint-Pierre
358d058a4aeSPhilippe Saint-Pierre				if (message.FindInt32("mcidx", 3, &value) == B_OK)
359d058a4aeSPhilippe Saint-Pierre					modifiers |= (value != 0 ? B_OPTION_KEY : 0);
360d058a4aeSPhilippe Saint-Pierre
361d058a4aeSPhilippe Saint-Pierre				Model model(&entry);
362d058a4aeSPhilippe Saint-Pierre				AddonShortcut* item = fAddonsList->EachElement(FindElement,
363d058a4aeSPhilippe Saint-Pierre					&model);
364d058a4aeSPhilippe Saint-Pierre				if (item != NULL) {
365d058a4aeSPhilippe Saint-Pierre					if (item->key != '\0')
366d058a4aeSPhilippe Saint-Pierre						RemoveShortcut(item->key, item->modifiers);
3679437e677SJohn Scipione
368d058a4aeSPhilippe Saint-Pierre					item->key = shortcut[0];
369d058a4aeSPhilippe Saint-Pierre					item->modifiers = modifiers;
370d058a4aeSPhilippe Saint-Pierre					AddOneShortcut(&model, item->key, item->modifiers, this);
371d058a4aeSPhilippe Saint-Pierre				}
372d058a4aeSPhilippe Saint-Pierre			}
373d058a4aeSPhilippe Saint-Pierre		}
37402be5353SAxel Dörfler	}
37502be5353SAxel Dörfler}
37602be5353SAxel Dörfler
37702be5353SAxel Dörfler
37802be5353SAxel Dörflervoid
37902be5353SAxel DörflerBDeskWindow::Quit()
38002be5353SAxel Dörfler{
3816cf062b9SJohn Scipione	if (fNavigationItem != NULL) {
38202be5353SAxel Dörfler		// this duplicates BContainerWindow::Quit because
38302be5353SAxel Dörfler		// fNavigationItem can be part of fTrashContextMenu
38402be5353SAxel Dörfler		// and would get deleted with it
385b05aa8b5SJohn Scipione		BMenu* menu = fNavigationItem->Menu();
3866cf062b9SJohn Scipione		if (menu != NULL)
38702be5353SAxel Dörfler			menu->RemoveItem(fNavigationItem);
3886cf062b9SJohn Scipione
38902be5353SAxel Dörfler		delete fNavigationItem;
39002be5353SAxel Dörfler		fNavigationItem = 0;
39102be5353SAxel Dörfler	}
39202be5353SAxel Dörfler
39329cfb630SPhilippe Saint-Pierre	fAddonsList->MakeEmpty(true);
394d058a4aeSPhilippe Saint-Pierre	delete fAddonsList;
395d058a4aeSPhilippe Saint-Pierre
39602be5353SAxel Dörfler	delete fDeskShelf;
39702be5353SAxel Dörfler	_inherited::Quit();
39802be5353SAxel Dörfler}
39902be5353SAxel Dörfler
40002be5353SAxel Dörfler
401b05aa8b5SJohn ScipioneBPoseView*
402e7803cf1SAugustin CavalierBDeskWindow::NewPoseView(Model* model, uint32 viewMode)
40302be5353SAxel Dörfler{
404e7803cf1SAugustin Cavalier	return new DesktopPoseView(model, viewMode);
40502be5353SAxel Dörfler}
40602be5353SAxel Dörfler
40702be5353SAxel Dörfler
40802be5353SAxel Dörflervoid
409b05aa8b5SJohn ScipioneBDeskWindow::CreatePoseView(Model* model)
41002be5353SAxel Dörfler{
411e7803cf1SAugustin Cavalier	fPoseView = NewPoseView(model, kIconMode);
41202be5353SAxel Dörfler	fPoseView->SetIconMapping(false);
41302be5353SAxel Dörfler	fPoseView->SetEnsurePosesVisible(true);
41402be5353SAxel Dörfler	fPoseView->SetAutoScroll(false);
41502be5353SAxel Dörfler
41602be5353SAxel Dörfler	BScreen screen(this);
41702be5353SAxel Dörfler	rgb_color desktopColor = screen.DesktopColor();
41802be5353SAxel Dörfler	if (desktopColor.alpha != 255) {
41902be5353SAxel Dörfler		desktopColor.alpha = 255;
420a615ec8fSAxel Dörfler#if B_BEOS_VERSION > B_BEOS_VERSION_5
421a615ec8fSAxel Dörfler		// This call seems to have the power to cause R5 to freeze!
422a615ec8fSAxel Dörfler		// Please report if commenting this out helped or helped not
423a615ec8fSAxel Dörfler		// on your system
42402be5353SAxel Dörfler		screen.SetDesktopColor(desktopColor);
425a615ec8fSAxel Dörfler#endif
42602be5353SAxel Dörfler	}
42702be5353SAxel Dörfler
42802be5353SAxel Dörfler	fPoseView->SetViewColor(desktopColor);
42902be5353SAxel Dörfler	fPoseView->SetLowColor(desktopColor);
43002be5353SAxel Dörfler
431e7803cf1SAugustin Cavalier	fPoseView->SetResizingMode(B_FOLLOW_ALL);
432e7803cf1SAugustin Cavalier	fPoseView->ResizeTo(Bounds().Size());
43302be5353SAxel Dörfler	AddChild(fPoseView);
43482d8aaf8SStephan Aßmus
43502be5353SAxel Dörfler	PoseView()->StartSettingsWatch();
43602be5353SAxel Dörfler}
43702be5353SAxel Dörfler
43802be5353SAxel Dörfler
43982d8aaf8SStephan Aßmusvoid
440b05aa8b5SJohn ScipioneBDeskWindow::AddWindowContextMenus(BMenu* menu)
44102be5353SAxel Dörfler{
4424ed28a57SAlexandre Deckner	TemplatesMenu* tempateMenu = new TemplatesMenu(PoseView(),
4434ed28a57SAlexandre Deckner		B_TRANSLATE("New"));
44402be5353SAxel Dörfler
44502be5353SAxel Dörfler	menu->AddItem(tempateMenu);
44602be5353SAxel Dörfler	tempateMenu->SetTargetForItems(PoseView());
44702be5353SAxel Dörfler	tempateMenu->SetFont(be_plain_font);
44802be5353SAxel Dörfler
44902be5353SAxel Dörfler	menu->AddSeparatorItem();
45059deaf10SStephan Aßmus
4514ed28a57SAlexandre Deckner	BMenu* iconSizeMenu = new BMenu(B_TRANSLATE("Icon view"));
45259deaf10SStephan Aßmus
45359deaf10SStephan Aßmus	BMessage* message = new BMessage(kIconMode);
45459deaf10SStephan Aßmus	message->AddInt32("size", 32);
4554ed28a57SAlexandre Deckner	BMenuItem* item = new BMenuItem(B_TRANSLATE("32 x 32"), message);
45659deaf10SStephan Aßmus	item->SetMarked(PoseView()->IconSizeInt() == 32);
45759deaf10SStephan Aßmus	item->SetTarget(PoseView());
45859deaf10SStephan Aßmus	iconSizeMenu->AddItem(item);
45959deaf10SStephan Aßmus
460e70b6d95SStephan Aßmus	message = new BMessage(kIconMode);
46159deaf10SStephan Aßmus	message->AddInt32("size", 40);
4624ed28a57SAlexandre Deckner	item = new BMenuItem(B_TRANSLATE("40 x 40"), message);
46359deaf10SStephan Aßmus	item->SetMarked(PoseView()->IconSizeInt() == 40);
46459deaf10SStephan Aßmus	item->SetTarget(PoseView());
46559deaf10SStephan Aßmus	iconSizeMenu->AddItem(item);
46659deaf10SStephan Aßmus
467e70b6d95SStephan Aßmus	message = new BMessage(kIconMode);
46859deaf10SStephan Aßmus	message->AddInt32("size", 48);
4694ed28a57SAlexandre Deckner	item = new BMenuItem(B_TRANSLATE("48 x 48"), message);
47059deaf10SStephan Aßmus	item->SetMarked(PoseView()->IconSizeInt() == 48);
47159deaf10SStephan Aßmus	item->SetTarget(PoseView());
47259deaf10SStephan Aßmus	iconSizeMenu->AddItem(item);
47359deaf10SStephan Aßmus
474e70b6d95SStephan Aßmus	message = new BMessage(kIconMode);
47559deaf10SStephan Aßmus	message->AddInt32("size", 64);
4764ed28a57SAlexandre Deckner	item = new BMenuItem(B_TRANSLATE("64 x 64"), message);
47759deaf10SStephan Aßmus	item->SetMarked(PoseView()->IconSizeInt() == 64);
47859deaf10SStephan Aßmus	item->SetTarget(PoseView());
47959deaf10SStephan Aßmus	iconSizeMenu->AddItem(item);
48059deaf10SStephan Aßmus
481e51854a1SJohn Scipione	message = new BMessage(kIconMode);
482e51854a1SJohn Scipione	message->AddInt32("size", 96);
483e51854a1SJohn Scipione	item = new BMenuItem(B_TRANSLATE("96 x 96"), message);
484e51854a1SJohn Scipione	item->SetMarked(PoseView()->IconSizeInt() == 96);
485e51854a1SJohn Scipione	item->SetTarget(PoseView());
486e51854a1SJohn Scipione	iconSizeMenu->AddItem(item);
487e51854a1SJohn Scipione
488e51854a1SJohn Scipione	message = new BMessage(kIconMode);
489e51854a1SJohn Scipione	message->AddInt32("size", 128);
490e51854a1SJohn Scipione	item = new BMenuItem(B_TRANSLATE("128 x 128"), message);
491e51854a1SJohn Scipione	item->SetMarked(PoseView()->IconSizeInt() == 128);
492e51854a1SJohn Scipione	item->SetTarget(PoseView());
493e51854a1SJohn Scipione	iconSizeMenu->AddItem(item);
494e51854a1SJohn Scipione
49596da4b41SStephan Aßmus	iconSizeMenu->AddSeparatorItem();
49696da4b41SStephan Aßmus
49796da4b41SStephan Aßmus	message = new BMessage(kIconMode);
49896da4b41SStephan Aßmus	message->AddInt32("scale", 0);
4994ed28a57SAlexandre Deckner	item = new BMenuItem(B_TRANSLATE("Decrease size"), message, '-');
50096da4b41SStephan Aßmus	item->SetTarget(PoseView());
50196da4b41SStephan Aßmus	iconSizeMenu->AddItem(item);
50296da4b41SStephan Aßmus
50396da4b41SStephan Aßmus	message = new BMessage(kIconMode);
50496da4b41SStephan Aßmus	message->AddInt32("scale", 1);
5054ed28a57SAlexandre Deckner	item = new BMenuItem(B_TRANSLATE("Increase size"), message, '+');
50696da4b41SStephan Aßmus	item->SetTarget(PoseView());
50796da4b41SStephan Aßmus	iconSizeMenu->AddItem(item);
50896da4b41SStephan Aßmus
50996da4b41SStephan Aßmus	// A sub menu where the super item can be invoked.
51059deaf10SStephan Aßmus	menu->AddItem(iconSizeMenu);
51196da4b41SStephan Aßmus	iconSizeMenu->Superitem()->SetShortcut('1', B_COMMAND_KEY);
51296da4b41SStephan Aßmus	iconSizeMenu->Superitem()->SetMessage(new BMessage(kIconMode));
51396da4b41SStephan Aßmus	iconSizeMenu->Superitem()->SetTarget(PoseView());
51496da4b41SStephan Aßmus	iconSizeMenu->Superitem()->SetMarked(PoseView()->ViewMode() == kIconMode);
51559deaf10SStephan Aßmus
5164ed28a57SAlexandre Deckner	item = new BMenuItem(B_TRANSLATE("Mini icon view"),
5174ed28a57SAlexandre Deckner		new BMessage(kMiniIconMode), '2');
51859deaf10SStephan Aßmus	item->SetMarked(PoseView()->ViewMode() == kMiniIconMode);
51959deaf10SStephan Aßmus	menu->AddItem(item);
52059deaf10SStephan Aßmus
52102be5353SAxel Dörfler	menu->AddSeparatorItem();
52259deaf10SStephan Aßmus
523fe49a8a3SAxel Dörfler#ifdef CUT_COPY_PASTE_IN_CONTEXT_MENU
5244ed28a57SAlexandre Deckner	BMenuItem* pasteItem = new BMenuItem(B_TRANSLATE("Paste"),
525d04d9b25SLee Mon		new BMessage(B_PASTE), 'V');
5264ed28a57SAlexandre Deckner	menu->AddItem(pasteItem);
52702be5353SAxel Dörfler	menu->AddSeparatorItem();
528fe49a8a3SAxel Dörfler#endif
529ea001e58SJohn Scipione	menu->AddItem(new BMenuItem(B_TRANSLATE("Clean up"),
530ea001e58SJohn Scipione		new BMessage(kCleanup), 'K'));
531991dadd6SHumdinger	menu->AddItem(new BMenuItem(B_TRANSLATE("Select" B_UTF8_ELLIPSIS),
53202be5353SAxel Dörfler		new BMessage(kShowSelectionWindow), 'A', B_SHIFT_KEY));
5334ed28a57SAlexandre Deckner	menu->AddItem(new BMenuItem(B_TRANSLATE("Select all"),
5344ed28a57SAlexandre Deckner		new BMessage(B_SELECT_ALL), 'A'));
53582d8aaf8SStephan Aßmus
53602be5353SAxel Dörfler	menu->AddSeparatorItem();
5374ed28a57SAlexandre Deckner	menu->AddItem(new MountMenu(B_TRANSLATE("Mount")));
53802be5353SAxel Dörfler
53902be5353SAxel Dörfler	menu->AddSeparatorItem();
5404ed28a57SAlexandre Deckner	menu->AddItem(new BMenu(B_TRANSLATE("Add-ons")));
54102be5353SAxel Dörfler
54202be5353SAxel Dörfler	// target items as needed
54302be5353SAxel Dörfler	menu->SetTargetForItems(PoseView());
544fe49a8a3SAxel Dörfler#ifdef CUT_COPY_PASTE_IN_CONTEXT_MENU
54502be5353SAxel Dörfler	pasteItem->SetTarget(this);
546fe49a8a3SAxel Dörfler#endif
54702be5353SAxel Dörfler}
54802be5353SAxel Dörfler
54902be5353SAxel Dörfler
55082d8aaf8SStephan Aßmusvoid
55102be5353SAxel DörflerBDeskWindow::WorkspaceActivated(int32 workspace, bool state)
55202be5353SAxel Dörfler{
55302be5353SAxel Dörfler	if (fBackgroundImage)
55402be5353SAxel Dörfler		fBackgroundImage->WorkspaceActivated(PoseView(), workspace, state);
55502be5353SAxel Dörfler}
55602be5353SAxel Dörfler
55702be5353SAxel Dörfler
55882d8aaf8SStephan Aßmusvoid
55902be5353SAxel DörflerBDeskWindow::SaveDesktopPoseLocations()
56002be5353SAxel Dörfler{
56102be5353SAxel Dörfler	PoseView()->SavePoseLocations(&fOldFrame);
56202be5353SAxel Dörfler}
56302be5353SAxel Dörfler
56402be5353SAxel Dörfler
56502be5353SAxel Dörflervoid
56602be5353SAxel DörflerBDeskWindow::ScreenChanged(BRect frame, color_space space)
56702be5353SAxel Dörfler{
56802be5353SAxel Dörfler	bool frameChanged = (frame != fOldFrame);
56902be5353SAxel Dörfler
57002be5353SAxel Dörfler	SaveDesktopPoseLocations();
57102be5353SAxel Dörfler	fOldFrame = frame;
57202be5353SAxel Dörfler	ResizeTo(frame.Width(), frame.Height());
57302be5353SAxel Dörfler
57402be5353SAxel Dörfler	if (fBackgroundImage)
57502be5353SAxel Dörfler		fBackgroundImage->ScreenChanged(frame, space);
57602be5353SAxel Dörfler
57702be5353SAxel Dörfler	PoseView()->CheckPoseVisibility(frameChanged ? &frame : 0);
57802be5353SAxel Dörfler		// if frame changed, pass new frame so that icons can
57902be5353SAxel Dörfler		// get rearranged based on old pose info for the frame
58002be5353SAxel Dörfler}
58102be5353SAxel Dörfler
58202be5353SAxel Dörfler
58382d8aaf8SStephan Aßmusvoid
58402be5353SAxel DörflerBDeskWindow::UpdateDesktopBackgroundImages()
58502be5353SAxel Dörfler{
58602be5353SAxel Dörfler	WindowStateNodeOpener opener(this, false);
58702be5353SAxel Dörfler	fBackgroundImage = BackgroundImage::Refresh(fBackgroundImage,
58802be5353SAxel Dörfler		opener.Node(), true, PoseView());
58902be5353SAxel Dörfler}
59002be5353SAxel Dörfler
59102be5353SAxel Dörfler
59202be5353SAxel Dörflervoid
59302be5353SAxel DörflerBDeskWindow::Show()
59402be5353SAxel Dörfler{
59502be5353SAxel Dörfler	if (fBackgroundImage)
59602be5353SAxel Dörfler		fBackgroundImage->Show(PoseView(), current_workspace());
59702be5353SAxel Dörfler
59802be5353SAxel Dörfler	PoseView()->CheckPoseVisibility();
59902be5353SAxel Dörfler
60002be5353SAxel Dörfler	_inherited::Show();
60102be5353SAxel Dörfler}
60202be5353SAxel Dörfler
60302be5353SAxel Dörfler
60402be5353SAxel Dörflerbool
60502be5353SAxel DörflerBDeskWindow::ShouldAddScrollBars() const
60602be5353SAxel Dörfler{
60702be5353SAxel Dörfler	return false;
60802be5353SAxel Dörfler}
60902be5353SAxel Dörfler
61002be5353SAxel Dörfler
61102be5353SAxel Dörflerbool
61202be5353SAxel DörflerBDeskWindow::ShouldAddMenus() const
61302be5353SAxel Dörfler{
61402be5353SAxel Dörfler	return false;
61502be5353SAxel Dörfler}
61602be5353SAxel Dörfler
61702be5353SAxel Dörfler
61802be5353SAxel Dörflerbool
61902be5353SAxel DörflerBDeskWindow::ShouldAddContainerView() const
62002be5353SAxel Dörfler{
62102be5353SAxel Dörfler	return false;
62202be5353SAxel Dörfler}
62302be5353SAxel Dörfler
62402be5353SAxel Dörfler
62502be5353SAxel Dörflervoid
626b05aa8b5SJohn ScipioneBDeskWindow::MessageReceived(BMessage* message)
62702be5353SAxel Dörfler{
62802be5353SAxel Dörfler	if (message->WasDropped()) {
629b05aa8b5SJohn Scipione		const rgb_color* color;
630adf8818eSAlex Smith		ssize_t size;
63102be5353SAxel Dörfler		// handle "roColour"-style color drops
63202be5353SAxel Dörfler		if (message->FindData("RGBColor", 'RGBC',
633b05aa8b5SJohn Scipione			(const void**)&color, &size) == B_OK) {
63402be5353SAxel Dörfler			BScreen(this).SetDesktopColor(*color);
63502be5353SAxel Dörfler			fPoseView->SetViewColor(*color);
63602be5353SAxel Dörfler			fPoseView->SetLowColor(*color);
63727c555cbSMarkus Himmel
63827c555cbSMarkus Himmel			// Notify the backgrounds app that the background changed
63927c555cbSMarkus Himmel			status_t initStatus;
64027c555cbSMarkus Himmel			BMessenger messenger("application/x-vnd.Haiku-Backgrounds", -1,
64127c555cbSMarkus Himmel				&initStatus);
64227c555cbSMarkus Himmel			if (initStatus == B_OK)
64327c555cbSMarkus Himmel				messenger.SendMessage(message);
64427c555cbSMarkus Himmel
64502be5353SAxel Dörfler			return;
64602be5353SAxel Dörfler		}
64702be5353SAxel Dörfler	}
64802be5353SAxel Dörfler
64902be5353SAxel Dörfler	switch (message->what) {
650d058a4aeSPhilippe Saint-Pierre		case B_PATH_MONITOR:
651d058a4aeSPhilippe Saint-Pierre		{
652d058a4aeSPhilippe Saint-Pierre			const char* path = "";
653d058a4aeSPhilippe Saint-Pierre			if (!(message->FindString("path", &path) == B_OK
654d058a4aeSPhilippe Saint-Pierre					&& strcmp(path, fShortcutsSettings) == 0)) {
655d058a4aeSPhilippe Saint-Pierre
656d058a4aeSPhilippe Saint-Pierre				dev_t device;
657d058a4aeSPhilippe Saint-Pierre				ino_t node;
658d058a4aeSPhilippe Saint-Pierre				if (fNodeRef == NULL
659d058a4aeSPhilippe Saint-Pierre					|| message->FindInt32("device", &device) != B_OK
660d058a4aeSPhilippe Saint-Pierre					|| message->FindInt64("node", &node) != B_OK
661d058a4aeSPhilippe Saint-Pierre					|| device != fNodeRef->device
662d058a4aeSPhilippe Saint-Pierre					|| node != fNodeRef->node)
663d058a4aeSPhilippe Saint-Pierre					break;
664d058a4aeSPhilippe Saint-Pierre			}
665d058a4aeSPhilippe Saint-Pierre			ApplyShortcutPreferences(true);
666d058a4aeSPhilippe Saint-Pierre			break;
667d058a4aeSPhilippe Saint-Pierre		}
66802be5353SAxel Dörfler		case B_NODE_MONITOR:
66902be5353SAxel Dörfler			PRINT(("will update addon shortcuts\n"));
670d058a4aeSPhilippe Saint-Pierre			InitAddonsList(true);
671d058a4aeSPhilippe Saint-Pierre			ApplyShortcutPreferences(true);
67202be5353SAxel Dörfler			break;
67302be5353SAxel Dörfler
67402be5353SAxel Dörfler		default:
67502be5353SAxel Dörfler			_inherited::MessageReceived(message);
67602be5353SAxel Dörfler			break;
67702be5353SAxel Dörfler	}
67802be5353SAxel Dörfler}
679