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 "ExpanderApp.h" 9 #include "ExpanderWindow.h" 10 #include "ExpanderThread.h" 11 #include "ExpanderPreferences.h" 12 13 14 #include <Alert.h> 15 #include <Application.h> 16 #include <Box.h> 17 #include <Button.h> 18 #include <Catalog.h> 19 #include <CheckBox.h> 20 #include <ControlLook.h> 21 #include <Entry.h> 22 #include <File.h> 23 #include <GroupLayout.h> 24 #include <GroupLayoutBuilder.h> 25 #include <Locale.h> 26 #include <Menu.h> 27 #include <MenuBar.h> 28 #include <MenuItem.h> 29 #include <Path.h> 30 #include <Screen.h> 31 #include <ScrollView.h> 32 #include <StringView.h> 33 #include <TextView.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); 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 'exit': 342 // thread has finished (finished, quit, killed, we don't know) 343 // reset window state 344 if (fExpandingStarted) { 345 fStatusView->SetText(B_TRANSLATE("File expanded")); 346 StopExpanding(); 347 OpenDestFolder(); 348 CloseWindowOrKeepOpen(); 349 } else if (fListingStarted) { 350 fSourceChanged = false; 351 StopListing(); 352 _ExpandListingText(); 353 } else 354 fStatusView->SetText(""); 355 break; 356 357 case 'exrr': // thread has finished 358 // reset window state 359 360 fStatusView->SetText(B_TRANSLATE("Error when expanding archive")); 361 CloseWindowOrKeepOpen(); 362 break; 363 364 default: 365 BWindow::MessageReceived(msg); 366 break; 367 } 368 } 369 370 371 bool 372 ExpanderWindow::CanQuit() 373 { 374 if ((fSourcePanel && fSourcePanel->IsShowing()) 375 || (fDestPanel && fDestPanel->IsShowing())) 376 return false; 377 378 if (fExpandingStarted) { 379 fExpandingThread->SuspendExternalExpander(); 380 BAlert* alert = new BAlert("stopAlert", 381 B_TRANSLATE("Are you sure you want to stop expanding this\n" 382 "archive? The expanded items may not be complete."), 383 B_TRANSLATE("Stop"), B_TRANSLATE("Continue"), NULL, 384 B_WIDTH_AS_USUAL, B_EVEN_SPACING, B_WARNING_ALERT); 385 if (alert->Go() == 0) { 386 fExpandingThread->ResumeExternalExpander(); 387 StopExpanding(); 388 } else { 389 fExpandingThread->ResumeExternalExpander(); 390 return false; 391 } 392 } 393 return true; 394 } 395 396 397 bool 398 ExpanderWindow::QuitRequested() 399 { 400 if (!CanQuit()) 401 return false; 402 403 if (fListingStarted) 404 StopListing(); 405 406 be_app->PostMessage(B_QUIT_REQUESTED); 407 fSettings.ReplacePoint("window_position", Frame().LeftTop()); 408 ((ExpanderApp*)(be_app))->UpdateSettingsFrom(&fSettings); 409 return true; 410 } 411 412 413 void 414 ExpanderWindow::RefsReceived(BMessage* msg) 415 { 416 entry_ref ref; 417 int32 i = 0; 418 int8 destination_folder = 0x63; 419 fSettings.FindInt8("destination_folder", &destination_folder); 420 421 while (msg->FindRef("refs", i++, &ref) == B_OK) { 422 BEntry entry(&ref, true); 423 BPath path(&entry); 424 BNode node(&entry); 425 426 if (node.IsFile()) { 427 fSourceChanged = true; 428 fSourceRef = ref; 429 fSourceText->SetText(path.Path()); 430 if (destination_folder == 0x63) { 431 BPath parent; 432 path.GetParent(&parent); 433 fDestText->SetText(parent.Path()); 434 get_ref_for_path(parent.Path(), &fDestRef); 435 } else if (destination_folder == 0x65) { 436 fSettings.FindRef("destination_folder_use", &fDestRef); 437 BEntry dEntry(&fDestRef, true); 438 BPath dPath(&dEntry); 439 fDestText->SetText(dPath.Path()); 440 } 441 442 BEntry dEntry(&fDestRef, true); 443 if (dEntry.Exists()) { 444 fExpandButton->SetEnabled(true); 445 fExpandItem->SetEnabled(true); 446 } 447 448 if (fShowContents->Value() == B_CONTROL_ON) { 449 StopListing(); 450 StartListing(); 451 } else { 452 fShowContents->SetEnabled(true); 453 fShowItem->SetEnabled(true); 454 } 455 456 bool fromApp; 457 if (msg->FindBool("fromApp", &fromApp) == B_OK) { 458 AutoExpand(); 459 } else 460 AutoListing(); 461 } else if (node.IsDirectory()) { 462 fDestRef = ref; 463 fDestText->SetText(path.Path()); 464 } 465 } 466 } 467 468 469 #undef B_TRANSLATE_CONTEXT 470 #define B_TRANSLATE_CONTEXT "ExpanderMenu" 471 472 void 473 ExpanderWindow::_AddMenuBar(BLayout* layout) 474 { 475 fBar = new BMenuBar("menu_bar", B_ITEMS_IN_ROW, B_INVALIDATE_AFTER_LAYOUT); 476 BMenu* menu = new BMenu(B_TRANSLATE("File")); 477 BMenuItem* item; 478 menu->AddItem(item = new BMenuItem(B_TRANSLATE("About Expander…"), 479 new BMessage(B_ABOUT_REQUESTED))); 480 item->SetTarget(be_app_messenger); 481 menu->AddSeparatorItem(); 482 menu->AddItem(fSourceItem = new BMenuItem(B_TRANSLATE("Set source…"), 483 new BMessage(MSG_SOURCE), 'O')); 484 menu->AddItem(fDestItem = new BMenuItem(B_TRANSLATE("Set destination…"), 485 new BMessage(MSG_DEST), 'D')); 486 menu->AddSeparatorItem(); 487 menu->AddItem(fExpandItem = new BMenuItem(B_TRANSLATE("Expand"), 488 new BMessage(MSG_EXPAND), 'E')); 489 fExpandItem->SetEnabled(false); 490 menu->AddItem(fShowItem = new BMenuItem(B_TRANSLATE("Show contents"), 491 new BMessage(MSG_SHOW), 'L')); 492 fShowItem->SetEnabled(false); 493 menu->AddSeparatorItem(); 494 menu->AddItem(fStopItem = new BMenuItem(B_TRANSLATE("Stop"), 495 new BMessage(MSG_STOP), 'K')); 496 fStopItem->SetEnabled(false); 497 menu->AddSeparatorItem(); 498 menu->AddItem(new BMenuItem(B_TRANSLATE("Close"), 499 new BMessage(B_QUIT_REQUESTED), 'W')); 500 fBar->AddItem(menu); 501 502 menu = new BMenu(B_TRANSLATE("Settings")); 503 menu->AddItem(fPreferencesItem = new BMenuItem(B_TRANSLATE("Settings…"), 504 new BMessage(MSG_PREFERENCES), 'S')); 505 fBar->AddItem(menu); 506 layout->AddView(fBar); 507 } 508 509 510 #undef B_TRANSLATE_CONTEXT 511 #define B_TRANSLATE_CONTEXT "ExpanderWindow" 512 513 void 514 ExpanderWindow::StartExpanding() 515 { 516 ExpanderRule* rule = fRules.MatchingRule(&fSourceRef); 517 if (!rule) 518 return; 519 520 BEntry destEntry(fDestText->Text(), true); 521 if (!destEntry.Exists()) { 522 BAlert* alert = new BAlert("destAlert", 523 B_TRANSLATE("The folder was either moved, renamed or not\nsupported."), 524 B_TRANSLATE("Cancel"), NULL, NULL, 525 B_WIDTH_AS_USUAL, B_EVEN_SPACING, B_WARNING_ALERT); 526 alert->Go(); 527 return; 528 } 529 530 BMessage message; 531 message.AddString("cmd", rule->ExpandCmd()); 532 message.AddRef("srcRef", &fSourceRef); 533 message.AddRef("destRef", &fDestRef); 534 535 fExpandButton->SetLabel(B_TRANSLATE("Stop")); 536 fSourceButton->SetEnabled(false); 537 fDestButton->SetEnabled(false); 538 fShowContents->SetEnabled(false); 539 fSourceItem->SetEnabled(false); 540 fDestItem->SetEnabled(false); 541 fExpandItem->SetEnabled(false); 542 fShowItem->SetEnabled(false); 543 fStopItem->SetEnabled(true); 544 fPreferencesItem->SetEnabled(false); 545 546 BEntry entry(&fSourceRef); 547 BPath path(&entry); 548 BString text(B_TRANSLATE("Expanding file ")); 549 text.Append(path.Leaf()); 550 fStatusView->SetText(text.String()); 551 552 fExpandingThread = new ExpanderThread(&message, new BMessenger(this)); 553 fExpandingThread->Start(); 554 555 fExpandingStarted = true; 556 } 557 558 559 void 560 ExpanderWindow::StopExpanding(void) 561 { 562 if (fExpandingThread) { 563 fExpandingThread->InterruptExternalExpander(); 564 fExpandingThread = NULL; 565 } 566 567 fExpandingStarted = false; 568 569 fExpandButton->SetLabel(B_TRANSLATE("Expand")); 570 fSourceButton->SetEnabled(true); 571 fDestButton->SetEnabled(true); 572 fShowContents->SetEnabled(true); 573 fSourceItem->SetEnabled(true); 574 fDestItem->SetEnabled(true); 575 fExpandItem->SetEnabled(true); 576 fShowItem->SetEnabled(true); 577 fStopItem->SetEnabled(false); 578 fPreferencesItem->SetEnabled(true); 579 } 580 581 582 void 583 ExpanderWindow::_ExpandListingText() 584 { 585 float delta = fLongestLine - fListingText->Frame().Width(); 586 587 if (delta > 0) { 588 BScreen screen; 589 BRect screenFrame = screen.Frame(); 590 591 if (Frame().right + delta > screenFrame.right) 592 delta = screenFrame.right - Frame().right - 4.0f; 593 594 ResizeBy(delta, 0.0f); 595 } 596 597 float minWidth, maxWidth, minHeight, maxHeight; 598 GetSizeLimits(&minWidth, &maxWidth, &minHeight, &maxHeight); 599 600 if (minWidth < Frame().Width() + delta) { 601 // set the Zoom limit as the minimal required size 602 SetZoomLimits(Frame().Width() + delta, 603 min_c(fSizeLimit + fListingText->TextRect().Height() 604 + fLineHeight + B_H_SCROLL_BAR_HEIGHT + 1.0f, 605 maxHeight)); 606 } else { 607 // set the zoom limit based on minimal window size allowed 608 SetZoomLimits(minWidth, 609 min_c(fSizeLimit + fListingText->TextRect().Height() 610 + fLineHeight + B_H_SCROLL_BAR_HEIGHT + 1.0f, 611 maxHeight)); 612 } 613 } 614 615 616 void 617 ExpanderWindow::_UpdateWindowSize(bool showContents) 618 { 619 float minWidth, maxWidth, minHeight, maxHeight; 620 GetSizeLimits(&minWidth, &maxWidth, &minHeight, &maxHeight); 621 622 float bottom = fSizeLimit; 623 624 if (showContents) { 625 if (fPreviousHeight < 0.0) { 626 BFont font; 627 font_height fontHeight; 628 fListingText->GetFont(&font); 629 font.GetHeight(&fontHeight); 630 fLineHeight = ceilf(fontHeight.ascent + fontHeight.descent 631 + fontHeight.leading); 632 fPreviousHeight = bottom + 10.0 * fLineHeight; 633 } 634 minHeight = bottom + 5.0 * fLineHeight; 635 maxHeight = 32767.0; 636 637 bottom = max_c(fPreviousHeight, minHeight); 638 } else { 639 minHeight = fSizeLimit; 640 maxHeight = fSizeLimit; 641 fPreviousHeight = Frame().Height(); 642 } 643 644 SetSizeLimits(minWidth, maxWidth, minHeight, maxHeight); 645 ResizeTo(Frame().Width(), bottom); 646 } 647 648 649 void 650 ExpanderWindow::StartListing() 651 { 652 _UpdateWindowSize(true); 653 654 if (!fSourceChanged) 655 return; 656 657 fPreviousHeight = -1.0; 658 659 fLongestLine = 0.0f; 660 661 ExpanderRule* rule = fRules.MatchingRule(&fSourceRef); 662 if (!rule) 663 return; 664 665 BMessage message; 666 message.AddString("cmd", rule->ListingCmd()); 667 message.AddRef("srcRef", &fSourceRef); 668 669 fShowContents->SetEnabled(true); 670 fSourceItem->SetEnabled(false); 671 fDestItem->SetEnabled(false); 672 fExpandItem->SetEnabled(false); 673 fShowItem->SetEnabled(true); 674 fShowItem->SetLabel(B_TRANSLATE("Hide contents")); 675 fStopItem->SetEnabled(false); 676 fPreferencesItem->SetEnabled(false); 677 678 fSourceButton->SetEnabled(false); 679 fDestButton->SetEnabled(false); 680 fExpandButton->SetEnabled(false); 681 682 BEntry entry(&fSourceRef); 683 BPath path(&entry); 684 BString text(B_TRANSLATE("Creating listing for ")); 685 text.Append(path.Leaf()); 686 fStatusView->SetText(text.String()); 687 fListingText->SetText(""); 688 689 fListingThread = new ExpanderThread(&message, new BMessenger(this)); 690 fListingThread->Start(); 691 692 fListingStarted = true; 693 } 694 695 696 void 697 ExpanderWindow::StopListing(void) 698 { 699 if (fListingThread) { 700 fListingThread->InterruptExternalExpander(); 701 fListingThread = NULL; 702 } 703 704 fListingStarted = false; 705 706 fShowContents->SetEnabled(true); 707 fSourceItem->SetEnabled(true); 708 fDestItem->SetEnabled(true); 709 fExpandItem->SetEnabled(true); 710 fShowItem->SetEnabled(true); 711 fStopItem->SetEnabled(false); 712 fPreferencesItem->SetEnabled(true); 713 714 fSourceButton->SetEnabled(true); 715 fDestButton->SetEnabled(true); 716 fExpandButton->SetEnabled(true); 717 fStatusView->SetText(""); 718 } 719 720 721 void 722 ExpanderWindow::CloseWindowOrKeepOpen() 723 { 724 bool expandFiles = false; 725 fSettings.FindBool("automatically_expand_files", &expandFiles); 726 727 bool closeWhenDone = false; 728 fSettings.FindBool("close_when_done", &closeWhenDone); 729 730 if (expandFiles || closeWhenDone) 731 PostMessage(B_QUIT_REQUESTED); 732 } 733 734 735 void 736 ExpanderWindow::OpenDestFolder() 737 { 738 bool openFolder = true; 739 fSettings.FindBool("open_destination_folder", &openFolder); 740 741 if (!openFolder) 742 return; 743 744 BMessage* message = new BMessage(B_REFS_RECEIVED); 745 message->AddRef("refs", &fDestRef); 746 BPath path(&fDestRef); 747 BMessenger tracker("application/x-vnd.Be-TRAK"); 748 tracker.SendMessage(message); 749 } 750 751 752 void 753 ExpanderWindow::AutoListing() 754 { 755 bool showContents = false; 756 fSettings.FindBool("show_contents_listing", &showContents); 757 758 if (!showContents) 759 return; 760 761 fShowContents->SetValue(B_CONTROL_ON); 762 fShowContents->Invoke(); 763 } 764 765 766 void 767 ExpanderWindow::AutoExpand() 768 { 769 bool expandFiles = false; 770 fSettings.FindBool("automatically_expand_files", &expandFiles); 771 772 if (!expandFiles) { 773 AutoListing(); 774 return; 775 } 776 777 fExpandButton->Invoke(); 778 } 779