Ticket #5420: Shortcuts-HIG-Update.patch
File Shortcuts-HIG-Update.patch, 30.0 KB (added by , 13 years ago) |
---|
-
src/preferences/shortcuts/ResizableButton.h
1 /*2 * Copyright 1999-2009 Haiku Inc. All rights reserved.3 * Distributed under the terms of the MIT License.4 *5 * Authors:6 * Jeremy Friesner7 */8 #ifndef ResizableButton_h9 #define ResizableButton_h10 11 12 #include <Button.h>13 14 15 class ResizableButton : public BButton {16 public:17 ResizableButton(BRect parentFrame, BRect frame,18 const char* name, const char* label,19 BMessage* message);20 21 virtual void ChangeToNewSize(float newWidth, float newHeight);22 private:23 BRect fPercentages;24 };25 26 27 #endif28 -
src/preferences/shortcuts/Jamfile
6 6 Preference Shortcuts : 7 7 main.cpp 8 8 MetaKeyStateMap.cpp 9 ResizableButton.cpp10 9 ShortcutsApp.cpp 11 10 ShortcutsSpec.cpp 12 11 ShortcutsWindow.cpp … … 19 18 MouseWatcher.cpp 20 19 PrefilledBitmap.cpp 21 20 ScrollViewCorner.cpp 22 21 23 22 : be $(HAIKU_LOCALE_LIBS) tracker libshortcuts_shared.a $(TARGET_LIBSTDC++) 24 23 : Shortcuts.rdef 25 24 ; -
src/preferences/shortcuts/ShortcutsWindow.cpp
15 15 16 16 #include <Alert.h> 17 17 #include <Application.h> 18 #include <Button.h> 18 19 #include <Catalog.h> 19 20 #include <Clipboard.h> 20 21 #include <File.h> 22 #include <FilePanel.h> 21 23 #include <FindDirectory.h> 22 24 #include <Input.h> 23 25 #include <Locale.h> 26 #include <Message.h> 24 27 #include <Menu.h> 25 28 #include <MenuBar.h> 26 29 #include <MenuItem.h> 27 30 #include <MessageFilter.h> 28 31 #include <Path.h> 29 32 #include <PopUpMenu.h> 33 #include <Screen.h> 30 34 #include <ScrollBar.h> 31 35 #include <ScrollView.h> 32 36 #include <String.h> 37 #include <SupportDefs.h> 33 38 34 39 #include "ColumnListView.h" 35 40 … … 39 44 #include "ShortcutsFilterConstants.h" 40 45 #include "ShortcutsSpec.h" 41 46 47 #define MAX_WIDTH 10000 48 #define MAX_HEIGHT 10000 49 // SetSizeLimits does not provide a mechanism for specifying an 50 // unrestricted maximum. 10,000 seems to be the most common value used 51 // in other Haiku system applications. 52 #define SPACING 5 53 // Vertical and horizontal spacing between GUI components. 42 54 43 // Window sizing constraints44 #define MIN_WIDTH 60045 #define MIN_HEIGHT 13046 #define MAX_WIDTH 6553547 #define MAX_HEIGHT 6553548 49 // Default window position50 #define WINDOW_START_X 3051 #define WINDOW_START_Y 10052 53 55 #undef B_TRANSLATE_CONTEXT 54 56 #define B_TRANSLATE_CONTEXT "ShortcutsWindow" 55 57 56 58 #define ERROR "Shortcuts error" 57 59 #define WARNING "Shortcuts warning" 58 60 59 // Global constants for Shortcuts 60 #define V_SPACING 5 // vertical spacing between GUI components 61 #define WINDOW_SETTINGS_FILE_NAME "Shortcuts_window_settings" 62 // Because the "shortcuts_settings" file (SHORTCUTS_SETTING_FILE_NAME) is 63 // already used as a communications method between this configurator and 64 // the "shortcut_catcher" input_server filter, it should not be overloaded 65 // with window position information. Instead, a separate file is used. 61 66 62 63 // Creates a pop-up-menu that reflects the possible states of the specified 67 // Creates a pop-up-menu that reflects the possible states of the specified 64 68 // meta-key. 65 69 static BPopUpMenu* 66 70 CreateMetaPopUp(int col) … … 68 72 MetaKeyStateMap& map = GetNthKeyMap(col); 69 73 BPopUpMenu * popup = new BPopUpMenu(NULL, false); 70 74 int numStates = map.GetNumStates(); 71 72 for (int i = 0; i < numStates; i++) 75 76 for (int i = 0; i < numStates; i++) 73 77 popup->AddItem(new BMenuItem(map.GetNthStateDesc(i), NULL)); 74 78 75 79 return popup; 76 80 } 77 81 … … 84 88 int numKeys = GetNumKeyIndices(); 85 89 for (int i = 0; i < numKeys; i++) { 86 90 const char* next = GetKeyName(i); 87 88 if (next) 91 92 if (next) 89 93 popup->AddItem(new BMenuItem(next, NULL)); 90 94 } 91 95 return popup; … … 94 98 95 99 ShortcutsWindow::ShortcutsWindow() 96 100 : 97 BWindow(BRect(WINDOW_START_X, WINDOW_START_Y, WINDOW_START_X + MIN_WIDTH, 98 WINDOW_START_Y + MIN_HEIGHT * 2), B_TRANSLATE_SYSTEM_NAME("Shortcuts"), 99 B_DOCUMENT_WINDOW, 0L), 100 fSavePanel(NULL), 101 fOpenPanel(NULL), 102 fSelectPanel(NULL), 103 fKeySetModified(false), 101 BWindow(BRect(0, 0, 0, 0), B_TRANSLATE_SYSTEM_NAME("Shortcuts"), 102 B_TITLED_WINDOW, 0L), 103 fSavePanel(NULL), 104 fOpenPanel(NULL), 105 fSelectPanel(NULL), 106 fKeySetModified(false), 104 107 fLastOpenWasAppend(false) 105 108 { 106 109 ShortcutsSpec::InitializeMetaMaps(); 107 110 108 SetSizeLimits(MIN_WIDTH, MAX_WIDTH, MIN_HEIGHT, MAX_HEIGHT); 111 BView* top = new BView(Bounds(), NULL, B_FOLLOW_ALL_SIDES, 0); 112 top->SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR)); 113 AddChild(top); 114 109 115 BMenuBar* menuBar = new BMenuBar(BRect(0, 0, 0, 0), "Menu Bar"); 110 116 111 117 BMenu* fileMenu = new BMenu(B_TRANSLATE("File")); 112 fileMenu->AddItem(new BMenuItem(B_TRANSLATE("Open KeySet" B_UTF8_ELLIPSIS), 118 fileMenu->AddItem(new BMenuItem(B_TRANSLATE("Open KeySet" B_UTF8_ELLIPSIS), 113 119 new BMessage(OPEN_KEYSET), 'O')); 114 120 fileMenu->AddItem(new BMenuItem( 115 B_TRANSLATE("Append KeySet" B_UTF8_ELLIPSIS), 121 B_TRANSLATE("Append KeySet" B_UTF8_ELLIPSIS), 116 122 new BMessage(APPEND_KEYSET), 'A')); 117 fileMenu->AddItem(new BMenuItem(B_TRANSLATE("Revert to saved"), 123 fileMenu->AddItem(new BMenuItem(B_TRANSLATE("Revert to saved"), 118 124 new BMessage(REVERT_KEYSET), 'A')); 119 125 fileMenu->AddItem(new BSeparatorItem); 120 126 fileMenu->AddItem(new BMenuItem( 121 B_TRANSLATE("Save KeySet as" B_UTF8_ELLIPSIS), 127 B_TRANSLATE("Save KeySet as" B_UTF8_ELLIPSIS), 122 128 new BMessage(SAVE_KEYSET_AS), 'S')); 123 129 fileMenu->AddItem(new BSeparatorItem); 124 130 fileMenu->AddItem(new BMenuItem(B_TRANSLATE("Quit"), 125 131 new BMessage(B_QUIT_REQUESTED), 'Q')); 126 132 menuBar->AddItem(fileMenu); 127 133 128 AddChild(menuBar);134 top->AddChild(menuBar); 129 135 130 font_height fh;131 be_plain_font->GetHeight(&fh);132 float vButtonHeight = ceil(fh.ascent) + ceil(fh.descent) + 5.0f;133 134 136 BRect tableBounds = Bounds(); 135 137 tableBounds.top = menuBar->Bounds().bottom + 1; 136 138 tableBounds.right -= B_V_SCROLL_BAR_WIDTH; 137 tableBounds.bottom -= (B_H_SCROLL_BAR_HEIGHT + V_SPACING + vButtonHeight + 138 V_SPACING * 2); 139 139 tableBounds.bottom -= B_H_SCROLL_BAR_HEIGHT; 140 140 141 BScrollView* containerView; 141 fColumnListView = new ColumnListView(tableBounds, &containerView, NULL, 142 B_FOLLOW_ALL_SIDES, B_WILL_DRAW | B_FRAME_EVENTS | B_NAVIGABLE, 142 fColumnListView = new ColumnListView(tableBounds, &containerView, NULL, 143 B_FOLLOW_ALL_SIDES, B_WILL_DRAW | B_FRAME_EVENTS | B_NAVIGABLE, 143 144 B_SINGLE_SELECTION_LIST, true, true, true, B_NO_BORDER); 144 145 fColumnListView->SetEditMessage(new BMessage(HOTKEY_ITEM_MODIFIED), 145 146 fColumnListView->SetEditMessage(new BMessage(HOTKEY_ITEM_MODIFIED), 146 147 BMessenger(this)); 147 148 const float metaWidth = 50.0f;149 148 149 float minListWidth = 0; 150 // A running total is kept as the columns are created. 151 float cellWidth = be_plain_font->StringWidth("Either") + 20; 152 // ShortcutsSpec does not seem to translate the string "Either". 153 150 154 for (int i = 0; i < ShortcutsSpec::NUM_META_COLUMNS; i++) { 155 const char* name = ShortcutsSpec::GetColumnName(i); 156 float headerWidth = be_plain_font->StringWidth(name) + 20; 157 float width = max_c(headerWidth, cellWidth); 158 minListWidth += width + 1; 159 151 160 fColumnListView->AddColumn( 152 new CLVColumn(ShortcutsSpec::GetColumnName(i), CreateMetaPopUp(i), 153 metaWidth, CLV_SORT_KEYABLE)); 161 new CLVColumn(name, CreateMetaPopUp(i), width, CLV_SORT_KEYABLE)); 154 162 } 155 163 164 float keyCellWidth = be_plain_font->StringWidth("Caps Lock") + 20; 156 165 fColumnListView->AddColumn(new CLVColumn(B_TRANSLATE("Key"), 157 CreateKeysPopUp(), 60, CLV_SORT_KEYABLE)); 166 CreateKeysPopUp(), keyCellWidth, CLV_SORT_KEYABLE)); 167 minListWidth += keyCellWidth + 1; 158 168 159 169 BPopUpMenu* popup = new BPopUpMenu(NULL, false); 160 170 popup->AddItem(new BMenuItem( … … 177 187 popup->AddItem(new BMenuItem(B_TRANSLATE("*Beep"), NULL)); 178 188 fColumnListView->AddColumn(new CLVColumn(B_TRANSLATE("Application"), popup, 179 189 323.0, CLV_SORT_KEYABLE)); 190 minListWidth += 323.0 + 1; 191 minListWidth += B_V_SCROLL_BAR_WIDTH; 180 192 181 193 fColumnListView->SetSortFunction(ShortcutsSpec::MyCompare); 182 AddChild(containerView);194 top->AddChild(containerView); 183 195 184 196 fColumnListView->SetSelectionMessage(new BMessage(HOTKEY_ITEM_SELECTED)); 185 197 fColumnListView->SetTarget(this); 186 198 187 BRect buttonBounds = Bounds(); 188 buttonBounds.left += V_SPACING; 189 buttonBounds.right = ((buttonBounds.right - buttonBounds.left) / 2.0f) 190 + buttonBounds.left; 191 buttonBounds.bottom -= V_SPACING * 2; 192 buttonBounds.top = buttonBounds.bottom - vButtonHeight; 193 buttonBounds.right -= B_V_SCROLL_BAR_WIDTH; 194 float origRight = buttonBounds.right; 195 buttonBounds.right = (buttonBounds.left + origRight) * 0.40f - 196 (V_SPACING / 2); 197 AddChild(fAddButton = new ResizableButton(Bounds(), buttonBounds, "add", 198 B_TRANSLATE("Add new shortcut"), new BMessage(ADD_HOTKEY_ITEM))); 199 buttonBounds.left = buttonBounds.right + V_SPACING; 200 buttonBounds.right = origRight; 201 AddChild(fRemoveButton = new ResizableButton(Bounds(), buttonBounds, 202 "remove", B_TRANSLATE("Remove selected shortcut"), 203 new BMessage(REMOVE_HOTKEY_ITEM))); 204 199 fAddButton = new BButton(BRect(0, 0, 0, 0), "add", 200 B_TRANSLATE("Add new shortcut"), new BMessage(ADD_HOTKEY_ITEM), 201 B_FOLLOW_BOTTOM); 202 fAddButton->ResizeToPreferred(); 203 fAddButton->MoveBy(SPACING, 204 Bounds().bottom - fAddButton->Bounds().bottom - SPACING); 205 top->AddChild(fAddButton); 206 207 fRemoveButton = new BButton(BRect(0, 0, 0, 0), "remove", 208 B_TRANSLATE("Remove selected shortcut"), 209 new BMessage(REMOVE_HOTKEY_ITEM), B_FOLLOW_BOTTOM); 210 fRemoveButton->ResizeToPreferred(); 211 fRemoveButton->MoveBy(fAddButton->Frame().right + SPACING, 212 Bounds().bottom - fRemoveButton->Bounds().bottom - SPACING); 213 top->AddChild(fRemoveButton); 214 205 215 fRemoveButton->SetEnabled(false); 206 216 207 float offset = (buttonBounds.right - buttonBounds.left) / 2.0f; 208 BRect saveButtonBounds = buttonBounds; 209 saveButtonBounds.right = Bounds().right - B_V_SCROLL_BAR_WIDTH - offset; 210 saveButtonBounds.left = buttonBounds.right + V_SPACING + offset; 211 AddChild(fSaveButton = new ResizableButton(Bounds(), saveButtonBounds, 212 "save", B_TRANSLATE("Save & apply"), new BMessage(SAVE_KEYSET))); 213 217 fSaveButton = new BButton(BRect(0, 0, 0, 0), "save", 218 B_TRANSLATE("Save & apply"), new BMessage(SAVE_KEYSET), 219 B_FOLLOW_BOTTOM | B_FOLLOW_RIGHT); 220 fSaveButton->ResizeToPreferred(); 221 fSaveButton->MoveBy(Bounds().right - fSaveButton->Bounds().right - SPACING, 222 Bounds().bottom - fSaveButton->Bounds().bottom - SPACING); 223 top->AddChild(fSaveButton); 224 214 225 fSaveButton->SetEnabled(false); 215 226 216 entry_ref ref; 217 if (_GetSettingsFile(&ref)) { 227 containerView->ResizeBy(0, 228 -(fAddButton->Bounds().bottom + 2 * SPACING + 2)); 229 230 float minButtonBarWidth = fRemoveButton->Frame().right 231 + fSaveButton->Bounds().right + 2 * SPACING; 232 float minWidth = max_c(minListWidth, minButtonBarWidth); 233 234 float menuBarHeight = menuBar->Bounds().bottom; 235 float buttonBarHeight = Bounds().bottom - containerView->Frame().bottom; 236 float minHeight = menuBarHeight + 200 + buttonBarHeight; 237 238 SetSizeLimits(minWidth, MAX_WIDTH, minHeight, MAX_HEIGHT); 239 // SetSizeLimits() will resize the window to the minimum size. 240 241 CenterOnScreen(); 242 243 entry_ref windowSettingsRef; 244 if (_GetWindowSettingsFile(&windowSettingsRef)) { 245 // The window settings file is not accepted via B_REFS_RECEIVED; this 246 // is a behind-the-scenes file that the user will never see or 247 // interact with. 248 BFile windowSettingsFile(&windowSettingsRef, B_READ_ONLY); 249 BMessage loadMsg; 250 if (loadMsg.Unflatten(&windowSettingsFile) == B_OK) 251 _LoadWindowSettings(loadMsg); 252 } 253 254 entry_ref keySetRef; 255 if (_GetSettingsFile(&keySetRef)) { 218 256 BMessage msg(B_REFS_RECEIVED); 219 msg.AddRef("refs", & ref);257 msg.AddRef("refs", &keySetRef); 220 258 msg.AddString("startupRef", "please"); 221 PostMessage(&msg); // Tell ourself to load this file if it exists. 259 PostMessage(&msg); 260 // Tell ourselves to load this file if it exists. 222 261 } 223 262 Show(); 224 263 } … … 239 278 bool ret = true; 240 279 241 280 if (fKeySetModified) { 242 BAlert* alert = new BAlert(WARNING, 281 BAlert* alert = new BAlert(WARNING, 243 282 B_TRANSLATE("Really quit without saving your changes?"), 244 283 B_TRANSLATE("Don't save"), B_TRANSLATE("Cancel"), 245 284 B_TRANSLATE("Save")); … … 253 292 // up the file requester 254 293 if (fLastSaved.InitCheck() == B_OK) { 255 294 if (_SaveKeySet(fLastSaved) == false) { 256 (new BAlert(ERROR, 295 (new BAlert(ERROR, 257 296 B_TRANSLATE("Shortcuts was unable to save your " 258 "KeySet file!"), 297 "KeySet file!"), 259 298 B_TRANSLATE("Oh no")))->Go(); 260 299 ret = true; //quit anyway 261 300 } … … 270 309 } 271 310 } 272 311 273 if (ret) 312 if (ret) { 274 313 fColumnListView->DeselectAll(); 314 315 // Save the window position. 316 entry_ref ref; 317 if (_GetWindowSettingsFile(&ref)) { 318 BEntry entry(&ref); 319 _SaveWindowSettings(entry); 320 } 321 } 322 275 323 return ret; 276 324 } 277 325 … … 282 330 BPath path; 283 331 if (find_directory(B_USER_SETTINGS_DIRECTORY, &path) != B_OK) 284 332 return false; 285 else 333 else 286 334 path.Append(SHORTCUTS_SETTING_FILE_NAME); 287 335 288 336 if (BEntry(path.Path(), true).GetRef(eref) == B_OK) … … 303 351 BMessage saveMsg; 304 352 for (int i = 0; i < fColumnListView->CountItems(); i++) { 305 353 BMessage next; 306 if (((ShortcutsSpec*)fColumnListView->ItemAt(i))->Archive(&next) 354 if (((ShortcutsSpec*)fColumnListView->ItemAt(i))->Archive(&next) 307 355 == B_OK) 308 356 saveMsg.AddMessage("spec", &next); 309 357 else 310 358 printf("Error archiving ShortcutsSpec #%i!\n", i); 311 359 } 312 360 313 361 bool ret = (saveMsg.Flatten(&saveTo) == B_OK); 314 362 315 363 if (ret) { 316 364 fKeySetModified = false; 317 365 fSaveButton->SetEnabled(false); … … 321 369 } 322 370 323 371 324 // Appends new entries from the file specified in the "spec" entry of 372 // Appends new entries from the file specified in the "spec" entry of 325 373 // (loadMsg). Returns true iff successful. 326 374 bool 327 375 ShortcutsWindow::_LoadKeySet(const BMessage& loadMsg) … … 330 378 BMessage msg; 331 379 while (loadMsg.FindMessage("spec", i++, &msg) == B_OK) { 332 380 ShortcutsSpec* spec = (ShortcutsSpec*)ShortcutsSpec::Instantiate(&msg); 333 if (spec != NULL) 381 if (spec != NULL) 334 382 fColumnListView->AddItem(spec); 335 else 383 else 336 384 printf("_LoadKeySet: Error parsing spec!\n"); 337 385 } 338 386 return true; 339 387 } 340 388 341 389 342 // Creates a new entry and adds it to the GUI. (defaultCommand) will be the 390 bool 391 ShortcutsWindow::_GetWindowSettingsFile(entry_ref* eref) 392 { 393 BPath path; 394 if (find_directory(B_USER_SETTINGS_DIRECTORY, &path) != B_OK) 395 return false; 396 else 397 path.Append(WINDOW_SETTINGS_FILE_NAME); 398 399 return BEntry(path.Path(), true).GetRef(eref) == B_OK; 400 } 401 402 403 // Saves the application settings file to (saveEntry). Because this is a 404 // non-essential file, we ignore errors when writing the settings. 405 void 406 ShortcutsWindow::_SaveWindowSettings(BEntry& saveEntry) 407 { 408 BFile saveTo(&saveEntry, B_WRITE_ONLY | B_CREATE_FILE | B_ERASE_FILE); 409 if (saveTo.InitCheck() != B_OK) 410 return; 411 412 BMessage saveMsg; 413 saveMsg.AddRect("window frame", Frame()); 414 415 for (int i = 0; i < fColumnListView->CountColumns(); i++) { 416 CLVColumn* column = fColumnListView->ColumnAt(i); 417 saveMsg.AddFloat("column width", column->Width()); 418 } 419 420 saveMsg.Flatten(&saveTo); 421 } 422 423 424 // Loads the application settings file from (loadMsg) and resizes the interface 425 // to match the previously saved settings. Because this is a non-essential 426 // file, we ignore errors when loading the settings. 427 void 428 ShortcutsWindow::_LoadWindowSettings(const BMessage& loadMsg) 429 { 430 BRect frame; 431 if (loadMsg.FindRect("window frame", &frame) == B_OK) { 432 // Ensure the frame does not resize below the computed minimum. 433 float width = max_c(Bounds().right, frame.right - frame.left); 434 float height = max_c(Bounds().bottom, frame.bottom - frame.top); 435 ResizeTo(width, height); 436 437 // Ensure the frame is not placed outside of the screen. 438 BScreen screen(this); 439 float left = min_c(screen.Frame().right - width, frame.left); 440 float top = min_c(screen.Frame().bottom - height, frame.top); 441 MoveTo(left, top); 442 } 443 444 for (int i = 0; i < fColumnListView->CountColumns(); i++) { 445 CLVColumn* column = fColumnListView->ColumnAt(i); 446 float columnWidth; 447 if (loadMsg.FindFloat("column width", i, &columnWidth) == B_OK) 448 column->SetWidth(max_c(column->Width(), columnWidth)); 449 } 450 } 451 452 453 // Creates a new entry and adds it to the GUI. (defaultCommand) will be the 343 454 // text in the entry, or NULL if no text is desired. 344 455 void 345 456 ShortcutsWindow::_AddNewSpec(const char* defaultCommand) … … 354 465 355 466 if (defaultCommand) 356 467 spec->SetCommand(defaultCommand); 357 } else 468 } else 358 469 spec = new ShortcutsSpec(defaultCommand ? defaultCommand : ""); 359 470 360 471 fColumnListView->AddItem(spec); … … 367 478 ShortcutsWindow::MessageReceived(BMessage* msg) 368 479 { 369 480 switch(msg->what) { 370 case OPEN_KEYSET: 371 case APPEND_KEYSET: 481 case OPEN_KEYSET: 482 case APPEND_KEYSET: 372 483 fLastOpenWasAppend = (msg->what == APPEND_KEYSET); 373 if (fOpenPanel) 484 if (fOpenPanel) 374 485 fOpenPanel->Show(); 375 486 else { 376 487 BMessenger m(this); 377 488 fOpenPanel = new BFilePanel(B_OPEN_PANEL, &m, NULL, 0, false); 378 489 fOpenPanel->Show(); 379 490 } 380 fOpenPanel->SetButtonLabel(B_DEFAULT_BUTTON, fLastOpenWasAppend ? 491 fOpenPanel->SetButtonLabel(B_DEFAULT_BUTTON, fLastOpenWasAppend ? 381 492 B_TRANSLATE("Append") : B_TRANSLATE("Open")); 382 493 break; 383 494 … … 404 515 BEntry entry(&ref); 405 516 if (entry.InitCheck() == B_OK) { 406 517 BPath path(&entry); 407 518 408 519 if (path.InitCheck() == B_OK) { 409 520 // Add a new item with the given path. 410 521 BString str(path.Path()); … … 427 538 BMessage fileMsg; 428 539 { 429 540 BFile file(&ref, B_READ_ONLY); 430 if ((file.InitCheck() != B_OK) 541 if ((file.InitCheck() != B_OK) 431 542 || (fileMsg.Unflatten(&file) != B_OK)) { 432 543 if (isStartMsg) { 433 544 // use this to save to anyway 434 545 fLastSaved = BEntry(&ref); 435 546 break; 436 547 } else { 437 (new BAlert(ERROR, 548 (new BAlert(ERROR, 438 549 B_TRANSLATE("Shortcuts was couldn't open your " 439 550 "KeySet file!"), B_TRANSLATE("OK")))->Go(NULL); 440 551 break; 441 552 } 442 553 } 443 554 } 444 555 445 556 if (fLastOpenWasAppend == false) { 446 557 // Clear the menu... 447 558 while (ShortcutsSpec* item … … 454 565 if (isStartMsg) fLastSaved = BEntry(&ref); 455 566 fSaveButton->SetEnabled(isStartMsg == false); 456 567 457 // If we just loaded in the Shortcuts settings file, then 568 // If we just loaded in the Shortcuts settings file, then 458 569 // no need to tell the user to save on exit. 459 570 entry_ref eref; 460 571 _GetSettingsFile(&eref); 461 572 if (ref == eref) fKeySetModified = false; 462 573 } else { 463 (new BAlert(ERROR, 574 (new BAlert(ERROR, 464 575 B_TRANSLATE("Shortcuts was unable to parse your " 465 "KeySet file!"), 576 "KeySet file!"), 466 577 B_TRANSLATE("OK")))->Go(NULL); 467 578 break; 468 579 } … … 480 591 BEntry ent(&aref); 481 592 if (ent.InitCheck() == B_OK) { 482 593 BPath path; 483 if ((ent.GetPath(&path) == B_OK) 594 if ((ent.GetPath(&path) == B_OK) 484 595 && (((ShortcutsSpec *) 485 596 fColumnListView->ItemAt(csel))-> 486 597 ProcessColumnTextString(ShortcutsSpec:: 487 598 STRING_COLUMN_INDEX, path.Path()))) { 488 599 489 600 fColumnListView->InvalidateItem(csel); 490 601 _MarkKeySetModified(); 491 602 } … … 501 612 502 613 const char * name; 503 614 entry_ref entry; 504 if ((msg->FindString("name", &name) == B_OK) 615 if ((msg->FindString("name", &name) == B_OK) 505 616 && (msg->FindRef("directory", &entry) == B_OK)) { 506 617 BDirectory dir(&entry); 507 618 BEntry saveTo(&dir, name, true); 508 showSaveError = ((saveTo.InitCheck() != B_OK) 619 showSaveError = ((saveTo.InitCheck() != B_OK) 509 620 || (_SaveKeySet(saveTo) == false)); 510 621 } else if (fLastSaved.InitCheck() == B_OK) { 511 622 // We've saved this before, save over previous file. … … 513 624 } else PostMessage(SAVE_KEYSET_AS); // open the save requester... 514 625 515 626 if (showSaveError) { 516 (new BAlert(ERROR, 517 B_TRANSLATE("Shortcuts wasn't able to save your keyset."), 627 (new BAlert(ERROR, 628 B_TRANSLATE("Shortcuts wasn't able to save your keyset."), 518 629 B_TRANSLATE("OK")))->Go(NULL); 519 630 } 520 631 break; … … 527 638 else { 528 639 BMessage msg(SAVE_KEYSET); 529 640 BMessenger messenger(this); 530 fSavePanel = new BFilePanel(B_SAVE_PANEL, &messenger, NULL, 0, 641 fSavePanel = new BFilePanel(B_SAVE_PANEL, &messenger, NULL, 0, 531 642 false, &msg); 532 643 fSavePanel->Show(); 533 644 } … … 542 653 { 543 654 int index = fColumnListView->CurrentSelection(); 544 655 if (index >= 0) { 545 CLVListItem* item = (CLVListItem*) 656 CLVListItem* item = (CLVListItem*) 546 657 fColumnListView->ItemAt(index); 547 658 fColumnListView->RemoveItem(index); 548 659 delete item; 549 660 _MarkKeySetModified(); 550 661 551 662 // Rules for new selection: If there is an item at (index), 552 // select it. Otherwise, if there is an item at (index-1), 663 // select it. Otherwise, if there is an item at (index-1), 553 664 // select it. Otherwise, select nothing. 554 665 int num = fColumnListView->CountItems(); 555 666 if (num > 0) { … … 558 669 else { 559 670 if (index > 0) 560 671 index--; 561 if (index < num) 672 if (index < num) 562 673 fColumnListView->Select(index); 563 674 } 564 675 } … … 581 692 { 582 693 int32 row, column; 583 694 584 if ((msg->FindInt32("row", &row) == B_OK) 695 if ((msg->FindInt32("row", &row) == B_OK) 585 696 && (msg->FindInt32("column", &column) == B_OK)) { 586 697 int32 key; 587 698 const char* bytes; … … 595 706 repaintNeeded = item->ProcessColumnMouseClick(column); 596 707 } else if ((msg->FindString("bytes", &bytes) == B_OK) 597 708 && (msg->FindInt32("key", &key) == B_OK)) { 598 repaintNeeded = item->ProcessColumnKeyStroke(column, 709 repaintNeeded = item->ProcessColumnKeyStroke(column, 599 710 bytes, key); 600 } else if (msg->FindInt32("unmappedkey", &key) == 711 } else if (msg->FindInt32("unmappedkey", &key) == 601 712 B_OK) { 602 repaintNeeded = ((column == item->KEY_COLUMN_INDEX) 603 && ((key > 0xFF) || (GetKeyName(key) != NULL)) 604 && (item->ProcessColumnKeyStroke(column, NULL, 713 repaintNeeded = ((column == item->KEY_COLUMN_INDEX) 714 && ((key > 0xFF) || (GetKeyName(key) != NULL)) 715 && (item->ProcessColumnKeyStroke(column, NULL, 605 716 key))); 606 717 } else if (msg->FindString("text", &bytes) == B_OK) { 607 718 if ((bytes[0] == '(')&&(bytes[1] == 'C')) { … … 614 725 NULL, 0, false, &msg); 615 726 fSelectPanel->Show(); 616 727 } 617 fSelectPanel->SetButtonLabel(B_DEFAULT_BUTTON, 728 fSelectPanel->SetButtonLabel(B_DEFAULT_BUTTON, 618 729 B_TRANSLATE("Select")); 619 730 } else { 620 731 repaintNeeded = item->ProcessColumnTextString( 621 732 column, bytes); 622 733 } 623 734 } 624 735 625 736 if (repaintNeeded) { 626 737 fColumnListView->InvalidateItem(row); 627 738 _MarkKeySetModified(); … … 660 771 661 772 662 773 void 663 ShortcutsWindow::FrameResized(float w, float h)664 {665 fAddButton->ChangeToNewSize(w, h);666 fRemoveButton->ChangeToNewSize(w, h);667 fSaveButton->ChangeToNewSize(w, h);668 }669 670 671 void672 774 ShortcutsWindow::DispatchMessage(BMessage* msg, BHandler* handler) 673 775 { 674 776 switch(msg->what) { 675 777 case B_COPY: 676 778 case B_CUT: 677 779 if (be_clipboard->Lock()) { 678 int32 row = fColumnListView->CurrentSelection(); 780 int32 row = fColumnListView->CurrentSelection(); 679 781 int32 column = fColumnListView->GetSelectedColumn(); 680 if ((row >= 0) 782 if ((row >= 0) 681 783 && (column == ShortcutsSpec::STRING_COLUMN_INDEX)) { 682 784 ShortcutsSpec* spec = (ShortcutsSpec*) 683 785 fColumnListView->ItemAt(row); 684 786 if (spec) { 685 787 BMessage* data = be_clipboard->Data(); 686 788 data->RemoveName("text/plain"); 687 data->AddData("text/plain", B_MIME_TYPE, 688 spec->GetCellText(column), 789 data->AddData("text/plain", B_MIME_TYPE, 790 spec->GetCellText(column), 689 791 strlen(spec->GetCellText(column))); 690 792 be_clipboard->Commit(); 691 793 692 794 if (msg->what == B_CUT) { 693 795 spec->ProcessColumnTextString(column, ""); 694 796 _MarkKeySetModified(); … … 705 807 BMessage* data = be_clipboard->Data(); 706 808 const char* text; 707 809 ssize_t textLen; 708 if (data->FindData("text/plain", B_MIME_TYPE, (const void**) 810 if (data->FindData("text/plain", B_MIME_TYPE, (const void**) 709 811 &text, &textLen) == B_OK) { 710 int32 row = fColumnListView->CurrentSelection(); 812 int32 row = fColumnListView->CurrentSelection(); 711 813 int32 column = fColumnListView->GetSelectedColumn(); 712 if ((row >= 0) 814 if ((row >= 0) 713 815 && (column == ShortcutsSpec::STRING_COLUMN_INDEX)) { 714 ShortcutsSpec* spec = (ShortcutsSpec*) 816 ShortcutsSpec* spec = (ShortcutsSpec*) 715 817 fColumnListView->ItemAt(row); 716 818 if (spec) { 717 819 for (ssize_t i = 0; i < textLen; i++) { … … 726 828 be_clipboard->Unlock(); 727 829 } 728 830 break; 729 831 730 832 default: 731 833 BWindow::DispatchMessage(msg, handler); 732 834 break; -
src/preferences/shortcuts/ShortcutsSpec.cpp
360 360 if (text == NULL) 361 361 return; 362 362 363 _CacheViewFont(owner); 364 // Ensure that sViewFont is configured before using it to calculate 365 // widths. The lack of this call was causing the initial display of 366 // columns to be incorrect, with a "jump" as all the columns correct 367 // themselves upon the first column resize. 368 363 369 float textWidth = sViewFont.StringWidth(text); 364 370 BPoint point; 365 371 rgb_color lowColor = color; -
src/preferences/shortcuts/ShortcutsWindow.h
10 10 11 11 12 12 #include <Entry.h> 13 #include <FilePanel.h>14 #include <Message.h>15 #include <Point.h>16 13 #include <Window.h> 17 14 18 15 #include "ColumnListView.h" 19 #include "ResizableButton.h"20 16 17 class BButton; 18 class BFilePanel; 19 class BMessage; 21 20 21 22 22 // This class defines our preferences/configuration window. 23 23 class ShortcutsWindow : public BWindow { 24 24 public: … … 27 27 28 28 virtual void DispatchMessage(BMessage* msg, BHandler* handler); 29 29 virtual void Quit(); 30 virtual void FrameResized(float w, float h); 31 virtual void MessageReceived(BMessage * msg); 30 virtual void MessageReceived(BMessage* msg); 32 31 virtual bool QuitRequested(); 33 32 34 33 // BMessage 'what' codes, representing commands understood by this Window. 35 34 enum { 36 35 ADD_HOTKEY_ITEM = 'SpKy', // Add a new hotkey entry to the GUI list. 37 36 REMOVE_HOTKEY_ITEM, // Remove a hotkey entry from the GUI list. 38 HOTKEY_ITEM_SELECTED, // Give the "focus bar" to the specified 37 HOTKEY_ITEM_SELECTED, // Give the "focus bar" to the specified 39 38 // entry. 40 HOTKEY_ITEM_MODIFIED, // Update the state of an entry to reflect 39 HOTKEY_ITEM_MODIFIED, // Update the state of an entry to reflect 41 40 // user's changes. 42 OPEN_KEYSET, // Bring up a File requester to load new 41 OPEN_KEYSET, // Bring up a File requester to load new 43 42 // settings. 44 APPEND_KEYSET, // Bring up a File requester to append 43 APPEND_KEYSET, // Bring up a File requester to append 45 44 // settings. 46 REVERT_KEYSET, // Dump the current state and re-read 45 REVERT_KEYSET, // Dump the current state and re-read 47 46 // settings from disk. 48 47 SAVE_KEYSET, // Save the current settings to disk 49 SAVE_KEYSET_AS, // Bring up a File requester to save 48 SAVE_KEYSET_AS, // Bring up a File requester to save 50 49 // current settings. 51 SELECT_APPLICATION, // Set the current entry to point to the 50 SELECT_APPLICATION, // Set the current entry to point to the 52 51 // given file. 53 52 }; 54 53 private: … … 57 56 void _AddNewSpec(const char* defaultCommand); 58 57 void _MarkKeySetModified(); 59 58 bool _LoadKeySet(const BMessage& loadMsg); 60 bool _SaveKeySet(BEntry 59 bool _SaveKeySet(BEntry& saveEntry); 61 60 bool _GetSettingsFile(entry_ref* ref); 61 void _LoadWindowSettings(const BMessage& loadMsg); 62 void _SaveWindowSettings(BEntry& saveEntry); 63 bool _GetWindowSettingsFile(entry_ref* ref); 62 64 63 ResizableButton*fAddButton;64 ResizableButton*fRemoveButton;65 ResizableButton*fSaveButton;65 BButton* fAddButton; 66 BButton* fRemoveButton; 67 BButton* fSaveButton; 66 68 ColumnListView* fColumnListView; 67 69 BFilePanel* fSavePanel; // for saving settings 68 70 BFilePanel* fOpenPanel; // for loading settings 69 71 BFilePanel* fSelectPanel; // for selecting apps to launch 70 72 71 73 // Points to the settings file to save to 72 74 BEntry fLastSaved; 73 75 74 76 // true iff changes were made since last load or save 75 77 bool fKeySetModified; 76 78 77 79 // true iff the file-requester's ref should be appended to current 78 80 bool fLastOpenWasAppend; 79 81 }; -
src/preferences/shortcuts/ResizableButton.cpp
1 /*2 * Copyright 1999-2009 Haiku Inc. All rights reserved.3 * Distributed under the terms of the MIT License.4 *5 * Authors:6 * Jeremy Friesner7 */8 9 10 #include "ResizableButton.h"11 12 13 ResizableButton::ResizableButton(BRect parentFrame, BRect frame,14 const char* name, const char* label, BMessage* message)15 :16 BButton(frame, name, label, message, B_FOLLOW_BOTTOM)17 {18 float width = parentFrame.right - parentFrame.left;19 float height = parentFrame.bottom - parentFrame.top;20 fPercentages.left = frame.left / width;21 fPercentages.top = frame.top / height;22 fPercentages.right = frame.right / width;23 fPercentages.bottom = frame.bottom / height;24 }25 26 27 void28 ResizableButton::ChangeToNewSize(float newWidth, float newHeight)29 {30 float newX = fPercentages.left* newWidth;31 float newW = (fPercentages.right* newWidth) - newX;32 BRect b = Frame();33 MoveBy(newX - b.left, 0);34 ResizeTo(newW, b.bottom - b.top);35 Invalidate();36 }37