1 /* 2 * Copyright 2004-2006, Jérôme DUVAL. All rights reserved. 3 * Copyright 2010, Karsten Heimrich. All rights reserved. 4 * Distributed under the terms of the MIT License. 5 */ 6 7 8 #include "ExpanderWindow.h" 9 10 #include <Alert.h> 11 #include <Box.h> 12 #include <Button.h> 13 #include <Catalog.h> 14 #include <CheckBox.h> 15 #include <ControlLook.h> 16 #include <Entry.h> 17 #include <File.h> 18 #include <GroupLayout.h> 19 #include <GroupLayoutBuilder.h> 20 #include <Locale.h> 21 #include <Menu.h> 22 #include <MenuBar.h> 23 #include <MenuItem.h> 24 #include <Path.h> 25 #include <Screen.h> 26 #include <ScrollView.h> 27 #include <StringView.h> 28 #include <TextView.h> 29 30 #include "ExpanderApp.h" 31 #include "ExpanderThread.h" 32 #include "ExpanderPreferences.h" 33 #include "PasswordAlert.h" 34 35 36 const uint32 MSG_SOURCE = 'mSOU'; 37 const uint32 MSG_DEST = 'mDES'; 38 const uint32 MSG_EXPAND = 'mEXP'; 39 const uint32 MSG_SHOW = 'mSHO'; 40 const uint32 MSG_STOP = 'mSTO'; 41 const uint32 MSG_PREFERENCES = 'mPRE'; 42 const uint32 MSG_SOURCETEXT = 'mSTX'; 43 const uint32 MSG_DESTTEXT = 'mDTX'; 44 const uint32 MSG_SHOWCONTENTS = 'mSCT'; 45 46 47 #undef B_TRANSLATE_CONTEXT 48 #define B_TRANSLATE_CONTEXT "ExpanderWindow" 49 50 ExpanderWindow::ExpanderWindow(BRect frame, const entry_ref* ref, 51 BMessage* settings) 52 : 53 BWindow(frame, B_TRANSLATE_COMMENT("Expander", "!! Window Title !!"), 54 B_TITLED_WINDOW, B_NORMAL_WINDOW_FEEL), 55 fSourcePanel(NULL), 56 fDestPanel(NULL), 57 fSourceChanged(true), 58 fListingThread(NULL), 59 fListingStarted(false), 60 fExpandingThread(NULL), 61 fExpandingStarted(false), 62 fSettings(*settings), 63 fPreferences(NULL) 64 { 65 BGroupLayout* layout = new BGroupLayout(B_VERTICAL, 0); 66 SetLayout(layout); 67 68 _AddMenuBar(layout); 69 70 fDestButton = new BButton(B_TRANSLATE("Destination"), 71 new BMessage(MSG_DEST)); 72 fSourceButton = new BButton(B_TRANSLATE("Source"), 73 new BMessage(MSG_SOURCE)); 74 fExpandButton = new BButton(B_TRANSLATE("Expand"), 75 new BMessage(MSG_EXPAND)); 76 77 BSize size = fDestButton->PreferredSize(); 78 size.width = max_c(size.width, fSourceButton->PreferredSize().width); 79 size.width = max_c(size.width, fExpandButton->PreferredSize().width); 80 81 fDestButton->SetExplicitMaxSize(size); 82 fSourceButton->SetExplicitMaxSize(size); 83 fExpandButton->SetExplicitMaxSize(size); 84 85 fListingText = new BTextView("listingText"); 86 fListingText->SetText(""); 87 fListingText->MakeEditable(false); 88 fListingText->SetStylable(false); 89 fListingText->SetWordWrap(false); 90 BFont font = be_fixed_font; 91 fListingText->SetFontAndColor(&font); 92 BScrollView* scrollView = new BScrollView("", fListingText, 93 B_INVALIDATE_AFTER_LAYOUT, true, true); 94 95 BView* topView = layout->View(); 96 const float spacing = be_control_look->DefaultItemSpacing(); 97 topView->AddChild(BGroupLayoutBuilder(B_VERTICAL, spacing) 98 .AddGroup(B_HORIZONTAL, spacing) 99 .AddGroup(B_VERTICAL, 5.0) 100 .Add(fSourceButton) 101 .Add(fDestButton) 102 .Add(fExpandButton) 103 .End() 104 .AddGroup(B_VERTICAL, spacing) 105 .Add(fSourceText = new BTextControl(NULL, NULL, 106 new BMessage(MSG_SOURCETEXT))) 107 .Add(fDestText = new BTextControl(NULL, NULL, 108 new BMessage(MSG_DESTTEXT))) 109 .AddGroup(B_HORIZONTAL, spacing) 110 .Add(fShowContents = new BCheckBox( 111 B_TRANSLATE("Show contents"), 112 new BMessage(MSG_SHOWCONTENTS))) 113 .Add(fStatusView = new BStringView(NULL, NULL)) 114 .End() 115 .End() 116 .End() 117 .Add(scrollView) 118 .SetInsets(spacing, spacing, spacing, spacing) 119 ); 120 121 size = topView->PreferredSize(); 122 fSizeLimit = size.Height() - scrollView->PreferredSize().height - spacing; 123 124 ResizeTo(Bounds().Width(), fSizeLimit); 125 SetSizeLimits(size.Width(), 32767.0f, fSizeLimit, fSizeLimit); 126 SetZoomLimits(Bounds().Width(), fSizeLimit); 127 fPreviousHeight = -1; 128 129 Show(); 130 } 131 132 133 ExpanderWindow::~ExpanderWindow() 134 { 135 if (fDestPanel && fDestPanel->RefFilter()) 136 delete fDestPanel->RefFilter(); 137 138 if (fSourcePanel && fSourcePanel->RefFilter()) 139 delete fSourcePanel->RefFilter(); 140 141 delete fDestPanel; 142 delete fSourcePanel; 143 } 144 145 146 bool 147 ExpanderWindow::ValidateDest() 148 { 149 BEntry entry(fDestText->Text(), true); 150 BVolume volume; 151 if (!entry.Exists()) { 152 BAlert* alert = new BAlert("destAlert", 153 B_TRANSLATE("The destination folder does not exist."), 154 B_TRANSLATE("Cancel"), NULL, NULL, 155 B_WIDTH_AS_USUAL, B_EVEN_SPACING, B_WARNING_ALERT); 156 alert->Go(); 157 return false; 158 } else if (!entry.IsDirectory()) { 159 (new BAlert("destAlert", 160 B_TRANSLATE("The destination is not a folder."), 161 B_TRANSLATE("Cancel"), NULL, NULL, 162 B_WIDTH_AS_USUAL, B_EVEN_SPACING, B_WARNING_ALERT))->Go(); 163 return false; 164 } else if (entry.GetVolume(&volume) != B_OK || volume.IsReadOnly()) { 165 (new BAlert("destAlert", 166 B_TRANSLATE("The destination is read only."), 167 B_TRANSLATE("Cancel"), NULL, NULL, B_WIDTH_AS_USUAL, 168 B_EVEN_SPACING, B_WARNING_ALERT))->Go(); 169 return false; 170 } else { 171 entry.GetRef(&fDestRef); 172 return true; 173 } 174 } 175 176 177 void 178 ExpanderWindow::MessageReceived(BMessage* msg) 179 { 180 switch (msg->what) { 181 case MSG_SOURCE: 182 { 183 BEntry entry(fSourceText->Text(), true); 184 entry_ref srcRef; 185 if (entry.Exists() && entry.IsDirectory()) 186 entry.GetRef(&srcRef); 187 if (!fSourcePanel) { 188 BMessenger messenger(this); 189 fSourcePanel = new BFilePanel(B_OPEN_PANEL, &messenger, &srcRef, 190 B_FILE_NODE, false, NULL, new RuleRefFilter(fRules), true); 191 (fSourcePanel->Window())->SetTitle( 192 B_TRANSLATE("Expander: Open")); 193 } else 194 fSourcePanel->SetPanelDirectory(&srcRef); 195 fSourcePanel->Show(); 196 break; 197 } 198 199 case MSG_DEST: 200 { 201 BEntry entry(fDestText->Text(), true); 202 entry_ref destRef; 203 if (entry.Exists() && entry.IsDirectory()) 204 entry.GetRef(&destRef); 205 if (!fDestPanel) { 206 BMessenger messenger(this); 207 fDestPanel = new DirectoryFilePanel(B_OPEN_PANEL, &messenger, 208 &destRef, B_DIRECTORY_NODE, false, NULL, 209 new DirectoryRefFilter(), true); 210 } else 211 fDestPanel->SetPanelDirectory(&destRef); 212 fDestPanel->Show(); 213 break; 214 } 215 216 case MSG_DIRECTORY: 217 { 218 entry_ref ref; 219 fDestPanel->GetPanelDirectory(&ref); 220 fDestRef = ref; 221 BEntry entry(&ref); 222 BPath path(&entry); 223 fDestText->SetText(path.Path()); 224 fDestPanel->Hide(); 225 break; 226 } 227 228 case B_SIMPLE_DATA: 229 case B_REFS_RECEIVED: 230 RefsReceived(msg); 231 break; 232 233 case MSG_EXPAND: 234 if (!ValidateDest()) 235 break; 236 if (!fExpandingStarted) { 237 StartExpanding(); 238 break; 239 } 240 // supposed to fall through 241 case MSG_STOP: 242 if (fExpandingStarted) { 243 fExpandingThread->SuspendExternalExpander(); 244 BAlert* alert = new BAlert("stopAlert", 245 B_TRANSLATE("Are you sure you want to stop expanding this\n" 246 "archive? The expanded items may not be complete."), 247 B_TRANSLATE("Stop"), B_TRANSLATE("Continue"), NULL, 248 B_WIDTH_AS_USUAL, B_EVEN_SPACING, B_WARNING_ALERT); 249 if (alert->Go() == 0) { 250 fExpandingThread->ResumeExternalExpander(); 251 StopExpanding(); 252 } else 253 fExpandingThread->ResumeExternalExpander(); 254 } 255 break; 256 257 case MSG_SHOW: 258 fShowContents->SetValue(fShowContents->Value() == B_CONTROL_OFF 259 ? B_CONTROL_ON : B_CONTROL_OFF); 260 // supposed to fall through 261 case MSG_SHOWCONTENTS: 262 // change menu item label 263 fShowItem->SetLabel(fShowContents->Value() == B_CONTROL_OFF 264 ? B_TRANSLATE("Show contents") : B_TRANSLATE("Hide contents")); 265 266 if (fShowContents->Value() == B_CONTROL_OFF) { 267 if (fListingStarted) 268 StopListing(); 269 270 _UpdateWindowSize(false); 271 } else 272 StartListing(); 273 break; 274 275 case MSG_SOURCETEXT: 276 { 277 BEntry entry(fSourceText->Text(), true); 278 if (!entry.Exists()) { 279 BAlert* alert = new BAlert("srcAlert", 280 B_TRANSLATE("The file doesn't exist"), 281 B_TRANSLATE("Cancel"), NULL, NULL, 282 B_WIDTH_AS_USUAL, B_EVEN_SPACING, B_WARNING_ALERT); 283 alert->Go(); 284 break; 285 } 286 287 entry_ref ref; 288 entry.GetRef(&ref); 289 ExpanderRule* rule = fRules.MatchingRule(&ref); 290 if (rule) { 291 fSourceChanged = true; 292 fSourceRef = ref; 293 fShowContents->SetEnabled(true); 294 fExpandButton->SetEnabled(true); 295 fExpandItem->SetEnabled(true); 296 fShowItem->SetEnabled(true); 297 break; 298 } 299 300 BString string = "The file : "; 301 string += fSourceText->Text(); 302 string += B_TRANSLATE_MARK(" is not supported"); 303 BAlert* alert = new BAlert("srcAlert", string.String(), 304 B_TRANSLATE("Cancel"), 305 NULL, NULL, B_WIDTH_AS_USUAL, B_EVEN_SPACING, B_INFO_ALERT); 306 alert->Go(); 307 308 fShowContents->SetEnabled(false); 309 fExpandButton->SetEnabled(false); 310 fExpandItem->SetEnabled(false); 311 fShowItem->SetEnabled(false); 312 } 313 break; 314 315 case MSG_DESTTEXT: 316 ValidateDest(); 317 break; 318 319 case MSG_PREFERENCES: 320 if (!fPreferences) 321 fPreferences = new ExpanderPreferences(&fSettings); 322 fPreferences->Show(); 323 break; 324 325 case 'outp': 326 if (!fExpandingStarted && fListingStarted) { 327 BString string; 328 int32 i = 0; 329 while (msg->FindString("output", i++, &string) == B_OK) { 330 float length = fListingText->StringWidth(string.String()); 331 332 if (length > fLongestLine) 333 fLongestLine = length; 334 335 fListingText->Insert(string.String()); 336 } 337 fListingText->ScrollToSelection(); 338 } 339 break; 340 341 case 'errp': 342 { 343 BString string; 344 if (msg->FindString("error", &string) == B_OK 345 && fExpandingStarted) { 346 fExpandingThread->SuspendExternalExpander(); 347 if (strstr(string.String(), "password") != NULL) { 348 BString password; 349 PasswordAlert* alert = new PasswordAlert("passwordAlert", string); 350 alert->Go(password); 351 fExpandingThread->ResumeExternalExpander(); 352 fExpandingThread->PushInput(password); 353 } else { 354 BAlert* alert = new BAlert("stopAlert", string, 355 B_TRANSLATE("Stop"), B_TRANSLATE("Continue"), NULL, 356 B_WIDTH_AS_USUAL, B_EVEN_SPACING, B_WARNING_ALERT); 357 if (alert->Go() == 0) { 358 fExpandingThread->ResumeExternalExpander(); 359 StopExpanding(); 360 } else 361 fExpandingThread->ResumeExternalExpander(); 362 } 363 } 364 break; 365 } 366 case 'exit': 367 // thread has finished (finished, quit, killed, we don't know) 368 // reset window state 369 if (fExpandingStarted) { 370 fStatusView->SetText(B_TRANSLATE("File expanded")); 371 StopExpanding(); 372 OpenDestFolder(); 373 CloseWindowOrKeepOpen(); 374 } else if (fListingStarted) { 375 fSourceChanged = false; 376 StopListing(); 377 _ExpandListingText(); 378 } else 379 fStatusView->SetText(""); 380 break; 381 382 case 'exrr': // thread has finished 383 // reset window state 384 385 fStatusView->SetText(B_TRANSLATE("Error when expanding archive")); 386 CloseWindowOrKeepOpen(); 387 break; 388 389 default: 390 BWindow::MessageReceived(msg); 391 break; 392 } 393 } 394 395 396 bool 397 ExpanderWindow::CanQuit() 398 { 399 if ((fSourcePanel && fSourcePanel->IsShowing()) 400 || (fDestPanel && fDestPanel->IsShowing())) 401 return false; 402 403 if (fExpandingStarted) { 404 fExpandingThread->SuspendExternalExpander(); 405 BAlert* alert = new BAlert("stopAlert", 406 B_TRANSLATE("Are you sure you want to stop expanding this\n" 407 "archive? The expanded items may not be complete."), 408 B_TRANSLATE("Stop"), B_TRANSLATE("Continue"), NULL, 409 B_WIDTH_AS_USUAL, B_EVEN_SPACING, B_WARNING_ALERT); 410 if (alert->Go() == 0) { 411 fExpandingThread->ResumeExternalExpander(); 412 StopExpanding(); 413 } else { 414 fExpandingThread->ResumeExternalExpander(); 415 return false; 416 } 417 } 418 return true; 419 } 420 421 422 bool 423 ExpanderWindow::QuitRequested() 424 { 425 if (!CanQuit()) 426 return false; 427 428 if (fListingStarted) 429 StopListing(); 430 431 be_app->PostMessage(B_QUIT_REQUESTED); 432 fSettings.ReplacePoint("window_position", Frame().LeftTop()); 433 ((ExpanderApp*)(be_app))->UpdateSettingsFrom(&fSettings); 434 return true; 435 } 436 437 438 void 439 ExpanderWindow::RefsReceived(BMessage* msg) 440 { 441 entry_ref ref; 442 int32 i = 0; 443 int8 destination_folder = 0x63; 444 fSettings.FindInt8("destination_folder", &destination_folder); 445 446 while (msg->FindRef("refs", i++, &ref) == B_OK) { 447 BEntry entry(&ref, true); 448 BPath path(&entry); 449 BNode node(&entry); 450 451 if (node.IsFile()) { 452 fSourceChanged = true; 453 fSourceRef = ref; 454 fSourceText->SetText(path.Path()); 455 if (destination_folder == 0x63) { 456 BPath parent; 457 path.GetParent(&parent); 458 fDestText->SetText(parent.Path()); 459 get_ref_for_path(parent.Path(), &fDestRef); 460 } else if (destination_folder == 0x65) { 461 fSettings.FindRef("destination_folder_use", &fDestRef); 462 BEntry dEntry(&fDestRef, true); 463 BPath dPath(&dEntry); 464 fDestText->SetText(dPath.Path()); 465 } 466 467 BEntry dEntry(&fDestRef, true); 468 if (dEntry.Exists()) { 469 fExpandButton->SetEnabled(true); 470 fExpandItem->SetEnabled(true); 471 } 472 473 if (fShowContents->Value() == B_CONTROL_ON) { 474 StopListing(); 475 StartListing(); 476 } else { 477 fShowContents->SetEnabled(true); 478 fShowItem->SetEnabled(true); 479 } 480 481 bool fromApp; 482 if (msg->FindBool("fromApp", &fromApp) == B_OK) { 483 AutoExpand(); 484 } else 485 AutoListing(); 486 } else if (node.IsDirectory()) { 487 fDestRef = ref; 488 fDestText->SetText(path.Path()); 489 } 490 } 491 } 492 493 494 #undef B_TRANSLATE_CONTEXT 495 #define B_TRANSLATE_CONTEXT "ExpanderMenu" 496 497 void 498 ExpanderWindow::_AddMenuBar(BLayout* layout) 499 { 500 fBar = new BMenuBar("menu_bar", B_ITEMS_IN_ROW, B_INVALIDATE_AFTER_LAYOUT); 501 BMenu* menu = new BMenu(B_TRANSLATE("File")); 502 BMenuItem* item; 503 menu->AddItem(item = new BMenuItem(B_TRANSLATE("About Expander…"), 504 new BMessage(B_ABOUT_REQUESTED))); 505 item->SetTarget(be_app_messenger); 506 menu->AddSeparatorItem(); 507 menu->AddItem(fSourceItem = new BMenuItem(B_TRANSLATE("Set source…"), 508 new BMessage(MSG_SOURCE), 'O')); 509 menu->AddItem(fDestItem = new BMenuItem(B_TRANSLATE("Set destination…"), 510 new BMessage(MSG_DEST), 'D')); 511 menu->AddSeparatorItem(); 512 menu->AddItem(fExpandItem = new BMenuItem(B_TRANSLATE("Expand"), 513 new BMessage(MSG_EXPAND), 'E')); 514 fExpandItem->SetEnabled(false); 515 menu->AddItem(fShowItem = new BMenuItem(B_TRANSLATE("Show contents"), 516 new BMessage(MSG_SHOW), 'L')); 517 fShowItem->SetEnabled(false); 518 menu->AddSeparatorItem(); 519 menu->AddItem(fStopItem = new BMenuItem(B_TRANSLATE("Stop"), 520 new BMessage(MSG_STOP), 'K')); 521 fStopItem->SetEnabled(false); 522 menu->AddSeparatorItem(); 523 menu->AddItem(new BMenuItem(B_TRANSLATE("Close"), 524 new BMessage(B_QUIT_REQUESTED), 'W')); 525 fBar->AddItem(menu); 526 527 menu = new BMenu(B_TRANSLATE("Settings")); 528 menu->AddItem(fPreferencesItem = new BMenuItem(B_TRANSLATE("Settings…"), 529 new BMessage(MSG_PREFERENCES), 'S')); 530 fBar->AddItem(menu); 531 layout->AddView(fBar); 532 } 533 534 535 #undef B_TRANSLATE_CONTEXT 536 #define B_TRANSLATE_CONTEXT "ExpanderWindow" 537 538 void 539 ExpanderWindow::StartExpanding() 540 { 541 ExpanderRule* rule = fRules.MatchingRule(&fSourceRef); 542 if (!rule) 543 return; 544 545 BEntry destEntry(fDestText->Text(), true); 546 if (!destEntry.Exists()) { 547 BAlert* alert = new BAlert("destAlert", 548 B_TRANSLATE("The folder was either moved, renamed or not\nsupported."), 549 B_TRANSLATE("Cancel"), NULL, NULL, 550 B_WIDTH_AS_USUAL, B_EVEN_SPACING, B_WARNING_ALERT); 551 alert->Go(); 552 return; 553 } 554 555 BMessage message; 556 message.AddString("cmd", rule->ExpandCmd()); 557 message.AddRef("srcRef", &fSourceRef); 558 message.AddRef("destRef", &fDestRef); 559 560 fExpandButton->SetLabel(B_TRANSLATE("Stop")); 561 fSourceButton->SetEnabled(false); 562 fDestButton->SetEnabled(false); 563 fShowContents->SetEnabled(false); 564 fSourceItem->SetEnabled(false); 565 fDestItem->SetEnabled(false); 566 fExpandItem->SetEnabled(false); 567 fShowItem->SetEnabled(false); 568 fStopItem->SetEnabled(true); 569 fPreferencesItem->SetEnabled(false); 570 571 BEntry entry(&fSourceRef); 572 BPath path(&entry); 573 BString text(B_TRANSLATE("Expanding file ")); 574 text.Append(path.Leaf()); 575 fStatusView->SetText(text.String()); 576 577 fExpandingThread = new ExpanderThread(&message, new BMessenger(this)); 578 fExpandingThread->Start(); 579 580 fExpandingStarted = true; 581 } 582 583 584 void 585 ExpanderWindow::StopExpanding(void) 586 { 587 if (fExpandingThread) { 588 fExpandingThread->InterruptExternalExpander(); 589 fExpandingThread = NULL; 590 } 591 592 fExpandingStarted = false; 593 594 fExpandButton->SetLabel(B_TRANSLATE("Expand")); 595 fSourceButton->SetEnabled(true); 596 fDestButton->SetEnabled(true); 597 fShowContents->SetEnabled(true); 598 fSourceItem->SetEnabled(true); 599 fDestItem->SetEnabled(true); 600 fExpandItem->SetEnabled(true); 601 fShowItem->SetEnabled(true); 602 fStopItem->SetEnabled(false); 603 fPreferencesItem->SetEnabled(true); 604 } 605 606 607 void 608 ExpanderWindow::_ExpandListingText() 609 { 610 float delta = fLongestLine - fListingText->Frame().Width(); 611 612 if (delta > 0) { 613 BScreen screen; 614 BRect screenFrame = screen.Frame(); 615 616 if (Frame().right + delta > screenFrame.right) 617 delta = screenFrame.right - Frame().right - 4.0f; 618 619 ResizeBy(delta, 0.0f); 620 } 621 622 float minWidth, maxWidth, minHeight, maxHeight; 623 GetSizeLimits(&minWidth, &maxWidth, &minHeight, &maxHeight); 624 625 if (minWidth < Frame().Width() + delta) { 626 // set the Zoom limit as the minimal required size 627 SetZoomLimits(Frame().Width() + delta, 628 min_c(fSizeLimit + fListingText->TextRect().Height() 629 + fLineHeight + B_H_SCROLL_BAR_HEIGHT + 1.0f, 630 maxHeight)); 631 } else { 632 // set the zoom limit based on minimal window size allowed 633 SetZoomLimits(minWidth, 634 min_c(fSizeLimit + fListingText->TextRect().Height() 635 + fLineHeight + B_H_SCROLL_BAR_HEIGHT + 1.0f, 636 maxHeight)); 637 } 638 } 639 640 641 void 642 ExpanderWindow::_UpdateWindowSize(bool showContents) 643 { 644 float minWidth, maxWidth, minHeight, maxHeight; 645 GetSizeLimits(&minWidth, &maxWidth, &minHeight, &maxHeight); 646 647 float bottom = fSizeLimit; 648 649 if (showContents) { 650 if (fPreviousHeight < 0.0) { 651 BFont font; 652 font_height fontHeight; 653 fListingText->GetFont(&font); 654 font.GetHeight(&fontHeight); 655 fLineHeight = ceilf(fontHeight.ascent + fontHeight.descent 656 + fontHeight.leading); 657 fPreviousHeight = bottom + 10.0 * fLineHeight; 658 } 659 minHeight = bottom + 5.0 * fLineHeight; 660 maxHeight = 32767.0; 661 662 bottom = max_c(fPreviousHeight, minHeight); 663 } else { 664 minHeight = fSizeLimit; 665 maxHeight = fSizeLimit; 666 fPreviousHeight = Frame().Height(); 667 } 668 669 SetSizeLimits(minWidth, maxWidth, minHeight, maxHeight); 670 ResizeTo(Frame().Width(), bottom); 671 } 672 673 674 void 675 ExpanderWindow::StartListing() 676 { 677 _UpdateWindowSize(true); 678 679 if (!fSourceChanged) 680 return; 681 682 fPreviousHeight = -1.0; 683 684 fLongestLine = 0.0f; 685 686 ExpanderRule* rule = fRules.MatchingRule(&fSourceRef); 687 if (!rule) 688 return; 689 690 BMessage message; 691 message.AddString("cmd", rule->ListingCmd()); 692 message.AddRef("srcRef", &fSourceRef); 693 694 fShowContents->SetEnabled(true); 695 fSourceItem->SetEnabled(false); 696 fDestItem->SetEnabled(false); 697 fExpandItem->SetEnabled(false); 698 fShowItem->SetEnabled(true); 699 fShowItem->SetLabel(B_TRANSLATE("Hide contents")); 700 fStopItem->SetEnabled(false); 701 fPreferencesItem->SetEnabled(false); 702 703 fSourceButton->SetEnabled(false); 704 fDestButton->SetEnabled(false); 705 fExpandButton->SetEnabled(false); 706 707 BEntry entry(&fSourceRef); 708 BPath path(&entry); 709 BString text(B_TRANSLATE("Creating listing for ")); 710 text.Append(path.Leaf()); 711 fStatusView->SetText(text.String()); 712 fListingText->SetText(""); 713 714 fListingThread = new ExpanderThread(&message, new BMessenger(this)); 715 fListingThread->Start(); 716 717 fListingStarted = true; 718 } 719 720 721 void 722 ExpanderWindow::StopListing(void) 723 { 724 if (fListingThread) { 725 fListingThread->InterruptExternalExpander(); 726 fListingThread = NULL; 727 } 728 729 fListingStarted = false; 730 731 fShowContents->SetEnabled(true); 732 fSourceItem->SetEnabled(true); 733 fDestItem->SetEnabled(true); 734 fExpandItem->SetEnabled(true); 735 fShowItem->SetEnabled(true); 736 fStopItem->SetEnabled(false); 737 fPreferencesItem->SetEnabled(true); 738 739 fSourceButton->SetEnabled(true); 740 fDestButton->SetEnabled(true); 741 fExpandButton->SetEnabled(true); 742 fStatusView->SetText(""); 743 } 744 745 746 void 747 ExpanderWindow::CloseWindowOrKeepOpen() 748 { 749 bool expandFiles = false; 750 fSettings.FindBool("automatically_expand_files", &expandFiles); 751 752 bool closeWhenDone = false; 753 fSettings.FindBool("close_when_done", &closeWhenDone); 754 755 if (expandFiles || closeWhenDone) 756 PostMessage(B_QUIT_REQUESTED); 757 } 758 759 760 void 761 ExpanderWindow::OpenDestFolder() 762 { 763 bool openFolder = true; 764 fSettings.FindBool("open_destination_folder", &openFolder); 765 766 if (!openFolder) 767 return; 768 769 BMessage* message = new BMessage(B_REFS_RECEIVED); 770 message->AddRef("refs", &fDestRef); 771 BPath path(&fDestRef); 772 BMessenger tracker("application/x-vnd.Be-TRAK"); 773 tracker.SendMessage(message); 774 } 775 776 777 void 778 ExpanderWindow::AutoListing() 779 { 780 bool showContents = false; 781 fSettings.FindBool("show_contents_listing", &showContents); 782 783 if (!showContents) 784 return; 785 786 fShowContents->SetValue(B_CONTROL_ON); 787 fShowContents->Invoke(); 788 } 789 790 791 void 792 ExpanderWindow::AutoExpand() 793 { 794 bool expandFiles = false; 795 fSettings.FindBool("automatically_expand_files", &expandFiles); 796 797 if (!expandFiles) { 798 AutoListing(); 799 return; 800 } 801 802 fExpandButton->Invoke(); 803 } 804