2 * Copyright 2005-2010, Haiku, Inc. All rights reserved.
3 * Distributed under the terms of the MIT license.
7 * Stephan Aßmus <superstippi@gmx.de>
9 * Copyright 1999, Be Incorporated. All Rights Reserved.
10 * This file may be used under the terms of the Be Sample Code License.
13 #include "PersonWindow.h"
20 #include <Clipboard.h>
21 #include <ControlLook.h>
22 #include <FilePanel.h>
23 #include <FindDirectory.h>
25 #include <LayoutBuilder.h>
30 #include <NodeMonitor.h>
36 #include "PeopleApp.h"
37 #include "PersonView.h"
40 #undef B_TRANSLATION_CONTEXT
41 #define B_TRANSLATION_CONTEXT "People"
44 PersonWindow::PersonWindow(BRect frame
, const char* title
,
45 const char* nameAttribute
, const char* categoryAttribute
,
48 BWindow(frame
, title
, B_TITLED_WINDOW
, B_NOT_ZOOMABLE
49 | B_AUTO_UPDATE_SIZE_LIMITS
),
52 fNameAttribute(nameAttribute
)
57 BMenuBar
* menuBar
= new BMenuBar("");
58 menu
= new BMenu(B_TRANSLATE("File"));
59 menu
->AddItem(item
= new BMenuItem(
60 B_TRANSLATE("New person" B_UTF8_ELLIPSIS
),
61 new BMessage(M_NEW
), 'N'));
62 item
->SetTarget(be_app
);
63 menu
->AddItem(new BMenuItem(B_TRANSLATE("Close"),
64 new BMessage(B_QUIT_REQUESTED
), 'W'));
65 menu
->AddSeparatorItem();
66 menu
->AddItem(fSave
= new BMenuItem(B_TRANSLATE("Save"),
67 new BMessage(M_SAVE
), 'S'));
68 fSave
->SetEnabled(FALSE
);
69 menu
->AddItem(new BMenuItem(
70 B_TRANSLATE("Save as" B_UTF8_ELLIPSIS
),
71 new BMessage(M_SAVE_AS
)));
72 menu
->AddItem(fRevert
= new BMenuItem(B_TRANSLATE("Revert"),
73 new BMessage(M_REVERT
), 'R'));
74 fRevert
->SetEnabled(FALSE
);
75 menu
->AddSeparatorItem();
76 item
= new BMenuItem(B_TRANSLATE("Quit"),
77 new BMessage(B_QUIT_REQUESTED
), 'Q');
78 item
->SetTarget(be_app
);
80 menuBar
->AddItem(menu
);
82 menu
= new BMenu(B_TRANSLATE("Edit"));
83 menu
->AddItem(fUndo
= new BMenuItem(B_TRANSLATE("Undo"),
84 new BMessage(B_UNDO
), 'Z'));
85 fUndo
->SetEnabled(false);
86 menu
->AddSeparatorItem();
87 menu
->AddItem(fCut
= new BMenuItem(B_TRANSLATE("Cut"),
88 new BMessage(B_CUT
), 'X'));
89 menu
->AddItem(fCopy
= new BMenuItem(B_TRANSLATE("Copy"),
90 new BMessage(B_COPY
), 'C'));
91 menu
->AddItem(fPaste
= new BMenuItem(B_TRANSLATE("Paste"),
92 new BMessage(B_PASTE
), 'V'));
93 BMenuItem
* selectAllItem
= new BMenuItem(B_TRANSLATE("Select all"),
94 new BMessage(M_SELECT
), 'A');
95 menu
->AddItem(selectAllItem
);
96 menu
->AddSeparatorItem();
97 menu
->AddItem(item
= new BMenuItem(B_TRANSLATE("Configure attributes"),
98 new BMessage(M_CONFIGURE_ATTRIBUTES
), 'F'));
99 item
->SetTarget(be_app
);
100 menuBar
->AddItem(menu
);
104 _SetToRef(new entry_ref(*ref
));
108 fView
= new PersonView("PeopleView", categoryAttribute
, fRef
);
110 BLayoutBuilder::Group
<>(this, B_VERTICAL
, 0)
114 fRevert
->SetTarget(fView
);
115 selectAllItem
->SetTarget(fView
);
119 PersonWindow::~PersonWindow()
126 PersonWindow::MenusBeginning()
128 bool enabled
= !fView
->IsSaved();
129 fSave
->SetEnabled(enabled
);
130 fRevert
->SetEnabled(enabled
);
133 bool undoEnabled
= false;
134 bool cutAndCopyEnabled
= false;
136 BTextView
* textView
= dynamic_cast<BTextView
*>(CurrentFocus());
137 if (textView
!= NULL
) {
138 undo_state state
= textView
->UndoState(&isRedo
);
139 undoEnabled
= state
!= B_UNDO_UNAVAILABLE
;
141 cutAndCopyEnabled
= fView
->IsTextSelected();
145 fUndo
->SetLabel(B_TRANSLATE("Redo"));
147 fUndo
->SetLabel(B_TRANSLATE("Undo"));
148 fUndo
->SetEnabled(undoEnabled
);
149 fCut
->SetEnabled(cutAndCopyEnabled
);
150 fCopy
->SetEnabled(cutAndCopyEnabled
);
152 be_clipboard
->Lock();
153 fPaste
->SetEnabled(be_clipboard
->Data()->HasData("text/plain", B_MIME_TYPE
));
154 be_clipboard
->Unlock();
156 fView
->BuildGroupMenu();
161 PersonWindow::MessageReceived(BMessage
* msg
)
164 BDirectory directory
;
175 // supposed to fall through
178 fView
->MessageReceived(msg
);
185 case B_UNDO
: // fall through
190 BView
* view
= CurrentFocus();
192 view
->MessageReceived(msg
);
196 case B_SAVE_REQUESTED
:
199 if (msg
->FindRef("directory", &dir
) == B_OK
) {
200 const char* name
= NULL
;
201 msg
->FindString("name", &name
);
202 directory
.SetTo(&dir
);
203 if (directory
.InitCheck() == B_NO_ERROR
) {
204 directory
.CreateFile(name
, &file
);
205 if (file
.InitCheck() == B_NO_ERROR
) {
206 node
= new BNodeInfo(&file
);
207 node
->SetType("application/x-person");
210 directory
.FindEntry(name
, &entry
);
212 _SetToRef(new entry_ref(dir
));
213 SetTitle(fRef
->name
);
214 fView
->CreateFile(fRef
);
217 sprintf(str
, B_TRANSLATE("Could not create %s."), name
);
218 BAlert
* alert
= new BAlert("", str
, B_TRANSLATE("Sorry"));
219 alert
->SetFlags(alert
->Flags() | B_CLOSE_ON_ESCAPE
);
230 if (msg
->FindInt32("opcode", &opcode
) == B_OK
) {
232 case B_ENTRY_REMOVED
:
233 // We lost our file. Close the window.
234 PostMessage(B_QUIT_REQUESTED
);
239 // We may have renamed our entry. Obtain relevant data
242 msg
->FindString("name", &name
);
245 msg
->FindInt64("to directory", &directory
);
248 msg
->FindInt32("device", &device
);
252 fRef
= new entry_ref(device
, directory
, name
.String());
254 // And our window title.
257 // If moved to Trash, close window.
258 BVolume
volume(device
);
260 find_directory(B_TRASH_DIRECTORY
, &trash
, false,
263 folder
.GetParent(&folder
);
265 PostMessage(B_QUIT_REQUESTED
);
272 // An attribute was updated.
274 if (msg
->FindString("attr", &attr
) == B_OK
)
275 fView
->SetAttribute(attr
.String(), true);
279 fView
->UpdatePicture(fRef
);
287 BWindow::MessageReceived(msg
);
293 PersonWindow::QuitRequested()
297 if (!fView
->IsSaved()) {
298 BAlert
* alert
= new BAlert("",
299 B_TRANSLATE("Save changes before closing?"), B_TRANSLATE("Cancel"),
300 B_TRANSLATE("Don't save"), B_TRANSLATE("Save"),
301 B_WIDTH_AS_USUAL
, B_OFFSET_SPACING
, B_WARNING_ALERT
);
302 alert
->SetShortcut(0, B_ESCAPE
);
303 alert
->SetShortcut(1, 'd');
304 alert
->SetShortcut(2, 's');
305 result
= alert
->Go();
314 } else if (result
== 0)
320 BMessage
message(M_WINDOW_QUITS
);
321 message
.AddRect("frame", Frame());
322 if (be_app
->Lock()) {
323 be_app
->PostMessage(&message
);
340 PersonWindow::AddAttribute(const char* label
, const char* attribute
)
342 fView
->AddAttribute(label
, attribute
);
347 PersonWindow::SaveAs()
349 char name
[B_FILE_NAME_LENGTH
];
350 _GetDefaultFileName(name
);
352 if (fPanel
== NULL
) {
353 BMessenger
target(this);
354 fPanel
= new BFilePanel(B_SAVE_PANEL
, &target
);
357 find_directory(B_USER_DIRECTORY
, &path
, true);
360 dir
.SetTo(path
.Path());
363 if (dir
.FindEntry("people", &entry
) == B_OK
364 || (dir
.CreateDirectory("people", &dir
) == B_OK
365 && dir
.GetEntry(&entry
) == B_OK
)) {
366 fPanel
->SetPanelDirectory(&entry
);
370 if (fPanel
->Window()->Lock()) {
371 fPanel
->SetSaveText(name
);
372 if (fPanel
->Window()->IsHidden())
373 fPanel
->Window()->Show();
375 fPanel
->Window()->Activate();
376 fPanel
->Window()->Unlock();
382 PersonWindow::RefersPersonFile(const entry_ref
& ref
) const
391 PersonWindow::_GetDefaultFileName(char* name
)
393 strncpy(name
, fView
->AttributeValue(fNameAttribute
), B_FILE_NAME_LENGTH
);
403 PersonWindow::_SetToRef(entry_ref
* ref
)
406 _WatchChanges(false);
417 PersonWindow::_WatchChanges(bool enable
)
425 node
.GetNodeRef(&nodeRef
);
436 flags
= B_STOP_WATCHING
;
440 if (watch_node(&nodeRef
, flags
, this) != B_OK
) {
441 printf("Error %s node monitor.\n", action
.String());