Previously, hrev55011 introduced localization for Cortex, which then prompted to close #7530. It has then been reopened, when it turns out that the translations for the container application (RouteApp) did not work, whereas the individual add-ons/modules were translated. The cause is that by default BCatalog looks up the translations based on the subtype part of the signature. This is x-vnd.Cortex.Route (without the application/ supertype). This change will place the translations in the right place of the file system. The add-ons were never affected, since they BCatalog is explicitly told to find the translations for the entire signature, like: static BCatalog sCatalog("application/x-vnd.Cortex.InfoView"); Even so, it was chosen to omit the `application` supertype from the signature for the shared code as well. This should fix #7530 for good. Change-Id: Iff18fabef7aba68602e49db1e98cfed2f486f545 Reviewed-on: https://review.haiku-os.org/c/haiku/+/4091 Reviewed-by: Niels Sascha Reedijk <[email protected]> Tested-by: Commit checker robot <[email protected]>
398 lines
11 KiB
C++
398 lines
11 KiB
C++
/*
|
|
* Copyright (c) 1999-2000, Eric Moon.
|
|
* All rights reserved.
|
|
*
|
|
* Redistribution and use in source and binary forms, with or without
|
|
* modification, are permitted provided that the following conditions
|
|
* are met:
|
|
*
|
|
* 1. Redistributions of source code must retain the above copyright
|
|
* notice, this list of conditions, and the following disclaimer.
|
|
*
|
|
* 2. Redistributions in binary form must reproduce the above copyright
|
|
* notice, this list of conditions, and the following disclaimer in the
|
|
* documentation and/or other materials provided with the distribution.
|
|
*
|
|
* 3. The name of the author may not be used to endorse or promote products
|
|
* derived from this software without specific prior written permission.
|
|
*
|
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR
|
|
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
|
* OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
|
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
|
|
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
|
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
|
|
* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
*/
|
|
|
|
|
|
// ParameterWindow.cpp
|
|
|
|
#include "ParameterWindow.h"
|
|
// ParameterWindow
|
|
#include "ParameterContainerView.h"
|
|
|
|
// Application Kit
|
|
#include <Message.h>
|
|
#include <Messenger.h>
|
|
// Interface Kit
|
|
#include <Alert.h>
|
|
#include <Menu.h>
|
|
#include <MenuBar.h>
|
|
#include <MenuItem.h>
|
|
#include <Screen.h>
|
|
#include <ScrollBar.h>
|
|
// Media Kit
|
|
#include <MediaRoster.h>
|
|
#include <MediaTheme.h>
|
|
#include <ParameterWeb.h>
|
|
// Storage Kit
|
|
#include <FilePanel.h>
|
|
#include <Path.h>
|
|
// Support Kit
|
|
#include <String.h>
|
|
// Locale Kit
|
|
#undef B_CATALOG
|
|
#define B_CATALOG (&sCatalog)
|
|
#include <Catalog.h>
|
|
|
|
#undef B_TRANSLATION_CONTEXT
|
|
#define B_TRANSLATION_CONTEXT "ParameterWindow"
|
|
|
|
__USE_CORTEX_NAMESPACE
|
|
|
|
#include <Debug.h>
|
|
#define D_ALLOC(x) //PRINT (x)
|
|
#define D_HOOK(x) //PRINT (x)
|
|
#define D_INTERNAL(x) //PRINT (x)
|
|
#define D_MESSAGE(x) //PRINT (x)
|
|
|
|
static BCatalog sCatalog("x-vnd.Cortex.ParameterView");
|
|
|
|
// -------------------------------------------------------- //
|
|
// ctor/dtor
|
|
// -------------------------------------------------------- //
|
|
|
|
ParameterWindow::ParameterWindow(
|
|
BPoint position,
|
|
live_node_info &nodeInfo,
|
|
BMessenger *notifyTarget)
|
|
: BWindow(BRect(position, position + BPoint(50.0, 50.0)),
|
|
"parameters", B_DOCUMENT_WINDOW,
|
|
B_WILL_ACCEPT_FIRST_CLICK | B_ASYNCHRONOUS_CONTROLS),
|
|
m_node(nodeInfo.node),
|
|
m_parameters(0),
|
|
m_notifyTarget(0),
|
|
m_zoomed(false),
|
|
m_zooming(false) {
|
|
D_ALLOC(("ParameterWindow::ParameterWindow()\n"));
|
|
|
|
// add the nodes name to the title
|
|
{
|
|
BString title = B_TRANSLATE("%nodeinfo% parameters");
|
|
title.ReplaceFirst("%nodeinfo%", nodeInfo.name);
|
|
SetTitle(title);
|
|
}
|
|
// add the menu bar
|
|
BMenuBar *menuBar = new BMenuBar(Bounds(), "ParameterWindow MenuBar");
|
|
|
|
BMenu *menu = new BMenu(B_TRANSLATE("Window"));
|
|
menu->AddItem(new BMenuItem(B_TRANSLATE("Start control panel"),
|
|
new BMessage(M_START_CONTROL_PANEL),
|
|
'P', B_COMMAND_KEY | B_SHIFT_KEY));
|
|
menu->AddSeparatorItem();
|
|
menu->AddItem(new BMenuItem(B_TRANSLATE("Close"),
|
|
new BMessage(B_QUIT_REQUESTED),
|
|
'W', B_COMMAND_KEY));
|
|
menuBar->AddItem(menu);
|
|
|
|
// future Media Theme selection capabilities go here
|
|
menu = new BMenu(B_TRANSLATE("Themes"));
|
|
BMessage *message = new BMessage(M_THEME_SELECTED);
|
|
BMediaTheme *theme = BMediaTheme::PreferredTheme();
|
|
message->AddInt32("themeID", theme->ID());
|
|
BMenuItem *item = new BMenuItem(theme->Name(), message);
|
|
item->SetMarked(true);
|
|
menu->AddItem(item);
|
|
menuBar->AddItem(menu);
|
|
AddChild(menuBar);
|
|
|
|
_updateParameterView();
|
|
_init();
|
|
|
|
// start watching for parameter web changes
|
|
BMediaRoster *roster = BMediaRoster::CurrentRoster();
|
|
roster->StartWatching(this, nodeInfo.node, B_MEDIA_WILDCARD);
|
|
|
|
if (notifyTarget) {
|
|
m_notifyTarget = new BMessenger(*notifyTarget);
|
|
}
|
|
}
|
|
|
|
ParameterWindow::~ParameterWindow() {
|
|
D_ALLOC(("ParameterWindow::~ParameterWindow()\n"));
|
|
|
|
if (m_notifyTarget) {
|
|
delete m_notifyTarget;
|
|
}
|
|
}
|
|
|
|
// -------------------------------------------------------- //
|
|
// BWindow impl
|
|
// -------------------------------------------------------- //
|
|
|
|
void ParameterWindow::FrameResized(
|
|
float width,
|
|
float height) {
|
|
D_HOOK(("ParameterWindow::FrameResized()\n"));
|
|
|
|
if (!m_zooming) {
|
|
m_zoomed = false;
|
|
}
|
|
else {
|
|
m_zooming = false;
|
|
}
|
|
}
|
|
|
|
void ParameterWindow::MessageReceived(
|
|
BMessage *message) {
|
|
D_MESSAGE(("ParameterWindow::MessageReceived()\n"));
|
|
|
|
switch (message->what) {
|
|
case M_START_CONTROL_PANEL: {
|
|
D_MESSAGE((" -> M_START_CONTROL_PANEL\n"));
|
|
status_t error = _startControlPanel();
|
|
if (error) {
|
|
BString s = B_TRANSLATE(
|
|
"Could not start control panel (%error%)");
|
|
s.ReplaceFirst("%error%", strerror(error));
|
|
BAlert *alert = new BAlert("", s.String(), B_TRANSLATE("OK"),
|
|
0, 0, B_WIDTH_AS_USUAL, B_WARNING_ALERT);
|
|
alert->SetFlags(alert->Flags() | B_CLOSE_ON_ESCAPE);
|
|
alert->Go(0);
|
|
}
|
|
bool replace = false;
|
|
if ((message->FindBool("replace", &replace) == B_OK)
|
|
&& (replace == true)) {
|
|
PostMessage(B_QUIT_REQUESTED);
|
|
}
|
|
break;
|
|
}
|
|
case M_THEME_SELECTED: {
|
|
D_MESSAGE((" -> M_THEME_SELECTED\n"));
|
|
int32 themeID;
|
|
if (message->FindInt32("themeID", &themeID) != B_OK) {
|
|
return;
|
|
}
|
|
// not yet implemented
|
|
break;
|
|
}
|
|
case B_MEDIA_WEB_CHANGED: {
|
|
D_MESSAGE((" -> B_MEDIA_WEB_CHANGED\n"));
|
|
_updateParameterView();
|
|
_constrainToScreen();
|
|
break;
|
|
}
|
|
default: {
|
|
BWindow::MessageReceived(message);
|
|
}
|
|
}
|
|
}
|
|
|
|
bool ParameterWindow::QuitRequested() {
|
|
D_HOOK(("ParameterWindow::QuitRequested()\n"));
|
|
|
|
// stop watching the MediaRoster
|
|
BMediaRoster *roster = BMediaRoster::CurrentRoster();
|
|
if (roster) {
|
|
roster->StopWatching(this, m_node, B_MEDIA_WILDCARD);
|
|
}
|
|
|
|
// tell the notification target to forget about us
|
|
if (m_notifyTarget && m_notifyTarget->IsValid()) {
|
|
BMessage message(M_CLOSED);
|
|
message.AddInt32("nodeID", m_node.node);
|
|
status_t error = m_notifyTarget->SendMessage(&message);
|
|
if (error) {
|
|
D_HOOK((" -> error sending message (%s) !\n", strerror(error)));
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
void ParameterWindow::Zoom(
|
|
BPoint origin,
|
|
float width,
|
|
float height) {
|
|
D_HOOK(("ParameterWindow::Zoom()\n"));
|
|
|
|
m_zooming = true;
|
|
|
|
BScreen screen(this);
|
|
if (!screen.Frame().Contains(Frame())) {
|
|
m_zoomed = false;
|
|
}
|
|
|
|
if (!m_zoomed) {
|
|
// resize to the ideal size
|
|
m_manualSize = Bounds();
|
|
ResizeTo(m_idealSize.Width(), m_idealSize.Height());
|
|
_constrainToScreen();
|
|
m_zoomed = true;
|
|
}
|
|
else {
|
|
// resize to the most recent manual size
|
|
ResizeTo(m_manualSize.Width(), m_manualSize.Height());
|
|
m_zoomed = false;
|
|
}
|
|
}
|
|
|
|
// -------------------------------------------------------- //
|
|
// internal operations
|
|
// -------------------------------------------------------- //
|
|
|
|
void ParameterWindow::_init() {
|
|
D_INTERNAL(("ParameterWindow::_init()\n"));
|
|
|
|
// offset to a new position
|
|
_constrainToScreen();
|
|
m_manualSize = Bounds().OffsetToCopy(0.0, 0.0);
|
|
|
|
// add the hidden option to close this window when the
|
|
// control panel has been started successfully
|
|
BMessage *message = new BMessage(M_START_CONTROL_PANEL);
|
|
message->AddBool("replace", true);
|
|
AddShortcut('P', B_COMMAND_KEY | B_SHIFT_KEY | B_OPTION_KEY,
|
|
message);
|
|
}
|
|
|
|
void ParameterWindow::_updateParameterView(
|
|
BMediaTheme *theme) {
|
|
D_INTERNAL(("ParameterWindow::_updateParameterView()\n"));
|
|
|
|
// clear the old version
|
|
if (m_parameters) {
|
|
ParameterContainerView *view = dynamic_cast<ParameterContainerView *>(FindView("ParameterContainerView"));
|
|
RemoveChild(view);
|
|
delete m_parameters;
|
|
m_parameters = 0;
|
|
delete view;
|
|
}
|
|
|
|
// fetch ParameterWeb from the MediaRoster
|
|
BMediaRoster *roster = BMediaRoster::CurrentRoster();
|
|
if (roster) {
|
|
BParameterWeb *web;
|
|
status_t error = roster->GetParameterWebFor(m_node, &web);
|
|
if (!error && (web->CountParameters() || web->CountGroups())) {
|
|
// if no theme was specified, use the preferred theme
|
|
if (!theme) {
|
|
theme = BMediaTheme::PreferredTheme();
|
|
}
|
|
// acquire the view
|
|
m_parameters = BMediaTheme::ViewFor(web, 0, theme);
|
|
if (m_parameters) {
|
|
BMenuBar *menuBar = KeyMenuBar();
|
|
m_idealSize = m_parameters->Bounds();
|
|
m_idealSize.right += B_V_SCROLL_BAR_WIDTH;
|
|
m_idealSize.bottom += B_H_SCROLL_BAR_HEIGHT;
|
|
if (menuBar) {
|
|
m_parameters->MoveTo(0.0, menuBar->Bounds().bottom + 1.0);
|
|
m_idealSize.bottom += menuBar->Bounds().bottom + 1.0;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// limit min size to avoid funny-looking scrollbars
|
|
float hMin = B_V_SCROLL_BAR_WIDTH*6, vMin = B_H_SCROLL_BAR_HEIGHT*3;
|
|
// limit max size to full extents of the parameter view
|
|
float hMax = m_idealSize.Width(), vMax = m_idealSize.Height();
|
|
SetSizeLimits(hMin, hMax, vMin, vMax);
|
|
|
|
// adapt the window to the new dimensions
|
|
ResizeTo(m_idealSize.Width(), m_idealSize.Height());
|
|
m_zoomed = true;
|
|
|
|
if (m_parameters) {
|
|
BRect paramRect = m_parameters->Bounds();
|
|
AddChild(new ParameterContainerView(paramRect, m_parameters));
|
|
}
|
|
}
|
|
|
|
void ParameterWindow::_constrainToScreen() {
|
|
D_INTERNAL(("ParameterWindow::_constrainToScreen()\n"));
|
|
|
|
BScreen screen(this);
|
|
BRect screenRect = screen.Frame();
|
|
BRect windowRect = Frame();
|
|
|
|
// if the window is outside the screen rect
|
|
// move it to the default position
|
|
if (!screenRect.Intersects(windowRect)) {
|
|
windowRect.OffsetTo(screenRect.LeftTop());
|
|
MoveTo(windowRect.LeftTop());
|
|
windowRect = Frame();
|
|
}
|
|
|
|
// if the window is larger than the screen rect
|
|
// resize it to fit at each side
|
|
if (!screenRect.Contains(windowRect)) {
|
|
if (windowRect.left < screenRect.left) {
|
|
windowRect.left = screenRect.left + 5.0;
|
|
MoveTo(windowRect.LeftTop());
|
|
windowRect = Frame();
|
|
}
|
|
if (windowRect.top < screenRect.top) {
|
|
windowRect.top = screenRect.top + 5.0;
|
|
MoveTo(windowRect.LeftTop());
|
|
windowRect = Frame();
|
|
}
|
|
if (windowRect.right > screenRect.right) {
|
|
windowRect.right = screenRect.right - 5.0;
|
|
}
|
|
if (windowRect.bottom > screenRect.bottom) {
|
|
windowRect.bottom = screenRect.bottom - 5.0;
|
|
}
|
|
ResizeTo(windowRect.Width(), windowRect.Height());
|
|
}
|
|
}
|
|
|
|
status_t ParameterWindow::_startControlPanel() {
|
|
D_INTERNAL(("ParameterWindow::_startControlPanel()\n"));
|
|
|
|
// get roster instance
|
|
BMediaRoster *roster = BMediaRoster::CurrentRoster();
|
|
if (!roster) {
|
|
D_INTERNAL((" -> MediaRoster not available\n"));
|
|
return B_ERROR;
|
|
}
|
|
|
|
// try to StartControlPanel()
|
|
BMessenger messenger;
|
|
status_t error = roster->StartControlPanel(m_node, &messenger);
|
|
if (error) {
|
|
D_INTERNAL((" -> StartControlPanel() failed (%s)\n", strerror(error)));
|
|
return error;
|
|
}
|
|
|
|
// notify the notification target, if any
|
|
if (m_notifyTarget) {
|
|
BMessage message(M_CONTROL_PANEL_STARTED);
|
|
message.AddInt32("nodeID", m_node.node);
|
|
message.AddMessenger("messenger", messenger);
|
|
error = m_notifyTarget->SendMessage(&message);
|
|
if (error) {
|
|
D_INTERNAL((" -> failed to notify target\n"));
|
|
}
|
|
}
|
|
|
|
return B_OK;
|
|
}
|
|
|
|
// END -- ParameterWindow.cpp --
|