forked from phoudoin/sanity
-
Notifications
You must be signed in to change notification settings - Fork 4
/
TranslatorSavePanel.cpp
187 lines (160 loc) · 6.32 KB
/
TranslatorSavePanel.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
#include "TranslatorSavePanel.h"
#include <Window.h>
#include <View.h>
#include <Alert.h>
#include <ScrollBar.h>
#include <Button.h>
#include <Catalog.h>
#include <TranslationKit.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#undef B_TRANSLATION_CONTEXT
#define B_TRANSLATION_CONTEXT "ScannerWindow"
TranslatorMenuItem::TranslatorMenuItem(const char *name, BMessage *message,
translator_id id, uint32 format) : BMenuItem(name, message) {
this->id = id;
this->format = format;
}
TranslatorSavePanel::TranslatorSavePanel(const char *name, BMessenger *target, entry_ref *start_directory,
uint32 node_flavors, bool allow_multiple_selection, BMessage *message, BRefFilter *filter, bool modal,
bool hide_when_done) :
BFilePanel(B_SAVE_PANEL, target, start_directory, node_flavors, allow_multiple_selection, message, filter,
modal, hide_when_done), BHandler(name) {
configwindow = NULL;
if (Window()->Lock()) {
Window()->SetTitle(B_TRANSLATE( "Save image" ));
// Find all the views that are in the way and move up them up 10 pixels
BView *background = Window()->ChildAt(0);
BView *poseview = background->FindView("PoseView");
if (poseview) poseview->ResizeBy(0, -10);
BButton *cancel = (BButton *)background->FindView("cancel button");
if (cancel) cancel->MoveBy(0, -10);
BButton *insert = (BButton *)background->FindView("default button");
if (insert) insert->MoveBy(0, -10);
BView *textview = (BView *)background->FindView("text view");
if (textview) textview->MoveBy(0, 10);
// Add the new BHandler to the window's looper
Window()->AddHandler(this);
if (!cancel || !textview || !poseview) {
printf("Couldn't find necessary controls.\n");
return;
}
// Build the "Settings" button relative to the cancel button
BRect rect = cancel->Frame();
rect.right = rect.left - 10;
float width = be_plain_font->StringWidth(B_TRANSLATE("Settings" B_UTF8_ELLIPSIS)) + 20;
rect.left = (width > 75) ? rect.right - width : rect.right - 75;
BButton *settings = new BButton(rect, "Settings", B_TRANSLATE("Settings" B_UTF8_ELLIPSIS), new BMessage(SAVE_FILE_PANEL_SETTINGS),
B_FOLLOW_RIGHT | B_FOLLOW_BOTTOM, B_WILL_DRAW | B_NAVIGABLE);
background->AddChild(settings);
settings->SetTarget(this);
BuildMenu();
// Position the menu field relative to the other GUI elements, and make it the
// same length as the textview
rect = textview->Frame();
rect.top = poseview->Frame().bottom + 5;
rect.bottom = rect.top + 10;
formatmenufield = new BMenuField(rect, "FormatMenuField", B_TRANSLATE( "Format:"), formatpopupmenu,
B_FOLLOW_LEFT | B_FOLLOW_BOTTOM, B_WILL_DRAW | B_NAVIGABLE);
background->AddChild(formatmenufield);
formatmenufield->SetDivider(be_plain_font->StringWidth(B_TRANSLATE("Format:")) + 7);
// Set the file panel's message to the first available translator
// Use the 'what' field of the supplied message as a model
what = message->what;
BMessage *m = new BMessage(what);
TranslatorMenuItem *item = GetCurrentMenuItem();
if (item != NULL) {
m->AddData("translator_id", B_RAW_TYPE, &(item->id), sizeof(translator_id));
m->AddInt32("translator_format", item->format);
}
SetMessage(m);
// Make sure the smallest window won't draw the "Settings" button over anything else
float min_window_width = Window()->Bounds().right - settings->Frame().left + 10 + textview->Frame().right;
Window()->SetSizeLimits(min_window_width, 10000, 250, 10000);
if (Window()->Bounds().IntegerWidth() + 1 < min_window_width)
Window()->ResizeTo(min_window_width, 300);
Window()->Unlock();
}
}
// Handle messages from controls we've added
void TranslatorSavePanel::MessageReceived(BMessage *message) {
switch (message->what) {
case SAVE_FILE_PANEL_FORMAT: {
BMessage *message = new BMessage(what);
TranslatorMenuItem *item = GetCurrentMenuItem();
if (item != NULL) {
message->AddData("translator_id", B_RAW_TYPE, &(item->id), sizeof(translator_id));
message->AddInt32("translator_format", item->format);
}
SetMessage(message);
break;
}
case SAVE_FILE_PANEL_SETTINGS:
TranslatorSettings();
break;
default:
BHandler::MessageReceived(message);
break;
}
}
TranslatorMenuItem *TranslatorSavePanel::GetCurrentMenuItem() {
return (TranslatorMenuItem *)formatpopupmenu->FindMarked();
}
void TranslatorSavePanel::TranslatorSettings() {
TranslatorMenuItem *item = GetCurrentMenuItem();
if (item == NULL) return;
BTranslatorRoster *roster = BTranslatorRoster::Default();
BView *view;
BRect rect(0, 0, 239, 239);
// Build a window around this translator's configuration view
status_t err = roster->MakeConfigurationView(item->id, NULL, &view, &rect);
if (err != B_OK || view == NULL) {
BAlert *alert = new BAlert(NULL, strerror(err), "OK");
alert->Go();
} else {
if (configwindow != NULL) {
if (configwindow->Lock()) configwindow->Quit();
}
configwindow = new BWindow(rect, "Translator Settings", B_TITLED_WINDOW_LOOK,
B_NORMAL_WINDOW_FEEL, B_NOT_ZOOMABLE | B_NOT_RESIZABLE);
configwindow->AddChild(view);
// Just to make sure
view->MoveTo(0, 0);
view->ResizeTo(rect.Width(), rect.Height());
configwindow->MoveTo(100, 100);
configwindow->Show();
}
}
void TranslatorSavePanel::BuildMenu() {
formatpopupmenu = new BPopUpMenu("FormatPopUpMenu");
BTranslatorRoster *roster = BTranslatorRoster::Default();
translator_id *translators;
int32 count;
// Find all translators on the system
roster->GetAllTranslators(&translators, &count);
const translation_format *format;
int32 format_count;
for (int x = 0; x < count; x++) {
// Determine which formats this one can write
roster->GetOutputFormats(translators[x], &format, &format_count);
for (int y = 0; y < format_count; y++) {
// Check if this is an image translator
if (format[y].group == B_TRANSLATOR_BITMAP) {
// If this format saves to some native format build a menu item for it
if (format[y].type == B_TRANSLATOR_BITMAP) continue;
TranslatorMenuItem *item = new TranslatorMenuItem(format[y].name,
new BMessage(SAVE_FILE_PANEL_FORMAT), translators[x], format[y].type);
item->SetTarget(this);
formatpopupmenu->AddItem(item);
break;
}
}
}
delete [] translators;
// Pick the first translator in the list
TranslatorMenuItem *item = (TranslatorMenuItem *)formatpopupmenu->ItemAt(0);
if (item != NULL) item->SetMarked(true);
}
TranslatorSavePanel::~TranslatorSavePanel() {
}