* New types are now no longer directly added, but delayed a bit (via a BMessageRunner);
this is done so that the type can be fully installed before investigating it. * When the preferred app of a type changes, the "is application" property will be reexamined - this should help in letting new application types appear in the FileTypesWindow list, but not in the ApplicationTypesWindow list. * Added a progress window for removing uninstalled apps. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@16726 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
8fee027ee3
commit
dcf60976b6
@ -24,7 +24,9 @@
|
||||
#include <PopUpMenu.h>
|
||||
#include <Query.h>
|
||||
#include <Roster.h>
|
||||
#include <Screen.h>
|
||||
#include <ScrollView.h>
|
||||
#include <StatusBar.h>
|
||||
#include <StringView.h>
|
||||
#include <TextView.h>
|
||||
#include <Volume.h>
|
||||
@ -33,7 +35,21 @@
|
||||
#include <stdio.h>
|
||||
|
||||
|
||||
class ProgressWindow : public BWindow {
|
||||
public:
|
||||
ProgressWindow(const char* message, int32 max, volatile bool* signalQuit);
|
||||
virtual ~ProgressWindow();
|
||||
|
||||
virtual void MessageReceived(BMessage* message);
|
||||
|
||||
private:
|
||||
BStatusBar* fStatusBar;
|
||||
BButton* fAbortButton;
|
||||
volatile bool* fQuitListener;
|
||||
};
|
||||
|
||||
const uint32 kMsgTypeSelected = 'typs';
|
||||
const uint32 kMsgTypeInvoked = 'typi';
|
||||
const uint32 kMsgRemoveUninstalled = 'runs';
|
||||
|
||||
|
||||
@ -71,6 +87,77 @@ variety_to_text(uint32 variety)
|
||||
// #pragma mark -
|
||||
|
||||
|
||||
ProgressWindow::ProgressWindow(const char* message, int32 max, volatile bool* signalQuit)
|
||||
: BWindow(BRect(0, 0, 300, 200), "Progress", B_MODAL_WINDOW_LOOK,
|
||||
B_MODAL_SUBSET_WINDOW_FEEL, B_ASYNCHRONOUS_CONTROLS | B_NOT_V_RESIZABLE),
|
||||
fQuitListener(signalQuit)
|
||||
{
|
||||
BView* topView = new BView(Bounds(), NULL, B_FOLLOW_ALL, B_WILL_DRAW);
|
||||
topView->SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR));
|
||||
AddChild(topView);
|
||||
|
||||
char count[100];
|
||||
snprintf(count, sizeof(count), "/%ld", max);
|
||||
|
||||
BRect rect = Bounds().InsetByCopy(8, 8);
|
||||
fStatusBar = new BStatusBar(rect, "status", message, count);
|
||||
fStatusBar->SetMaxValue(max);
|
||||
fStatusBar->SetResizingMode(B_FOLLOW_LEFT_RIGHT);
|
||||
float width, height;
|
||||
fStatusBar->GetPreferredSize(&width, &height);
|
||||
fStatusBar->ResizeTo(rect.Width(), height);
|
||||
topView->AddChild(fStatusBar);
|
||||
|
||||
fAbortButton = new BButton(rect, "abort", "Abort", new BMessage(B_CANCEL),
|
||||
B_FOLLOW_H_CENTER | B_FOLLOW_TOP);
|
||||
fAbortButton->ResizeToPreferred();
|
||||
fAbortButton->MoveTo((Bounds().Width() - fAbortButton->Bounds().Width()) / 2,
|
||||
fStatusBar->Frame().bottom + 10.0f);
|
||||
topView->AddChild(fAbortButton);
|
||||
|
||||
ResizeTo(width * 1.4f, fAbortButton->Frame().bottom + 8.0f);
|
||||
SetSizeLimits(width + 42.0f, 32767.0f,
|
||||
Bounds().Height(), Bounds().Height());
|
||||
|
||||
// center on screen
|
||||
BScreen screen(this);
|
||||
MoveTo(screen.Frame().left + (screen.Frame().Width() - Bounds().Width()) / 2.0f,
|
||||
screen.Frame().top + (screen.Frame().Height() - Bounds().Height()) / 2.0f);
|
||||
}
|
||||
|
||||
|
||||
ProgressWindow::~ProgressWindow()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ProgressWindow::MessageReceived(BMessage* message)
|
||||
{
|
||||
switch (message->what) {
|
||||
case B_UPDATE_STATUS_BAR:
|
||||
char count[100];
|
||||
snprintf(count, sizeof(count), "%ld", (int32)fStatusBar->CurrentValue() + 1);
|
||||
|
||||
fStatusBar->Update(1, NULL, count);
|
||||
break;
|
||||
|
||||
case B_CANCEL:
|
||||
fAbortButton->SetEnabled(false);
|
||||
if (fQuitListener != NULL)
|
||||
*fQuitListener = true;
|
||||
break;
|
||||
|
||||
default:
|
||||
BWindow::MessageReceived(message);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// #pragma mark -
|
||||
|
||||
|
||||
ApplicationTypesWindow::ApplicationTypesWindow(BRect frame)
|
||||
: BWindow(frame, "Application Types", B_TITLED_WINDOW,
|
||||
B_NOT_ZOOMABLE | B_ASYNCHRONOUS_CONTROLS)
|
||||
@ -96,6 +183,7 @@ ApplicationTypesWindow::ApplicationTypesWindow(BRect frame)
|
||||
fTypeListView = new MimeTypeListView(rect, "listview", "application", true, true,
|
||||
B_FOLLOW_LEFT | B_FOLLOW_TOP_BOTTOM);
|
||||
fTypeListView->SetSelectionMessage(new BMessage(kMsgTypeSelected));
|
||||
fTypeListView->SetInvocationMessage(new BMessage(kMsgTypeInvoked));
|
||||
|
||||
BScrollView* scrollView = new BScrollView("scrollview", fTypeListView,
|
||||
B_FOLLOW_LEFT | B_FOLLOW_TOP_BOTTOM, B_FRAME_EVENTS | B_WILL_DRAW, false, true);
|
||||
@ -213,9 +301,17 @@ ApplicationTypesWindow::_RemoveUninstalled()
|
||||
// Note: this runs in the looper's thread, which isn't that nice
|
||||
|
||||
int32 removed = 0;
|
||||
volatile bool quit = false;
|
||||
|
||||
for (int32 i = fTypeListView->FullListCountItems(); i-- > 0;) {
|
||||
BWindow* progressWindow = new ProgressWindow("Removing uninstalled application types",
|
||||
fTypeListView->FullListCountItems(), &quit);
|
||||
progressWindow->AddToSubset(this);
|
||||
progressWindow->Show();
|
||||
|
||||
for (int32 i = fTypeListView->FullListCountItems(); i-- > 0 && !quit;) {
|
||||
MimeTypeItem* item = dynamic_cast<MimeTypeItem*>(fTypeListView->FullListItemAt(i));
|
||||
progressWindow->PostMessage(B_UPDATE_STATUS_BAR);
|
||||
|
||||
if (item == NULL)
|
||||
continue;
|
||||
|
||||
@ -257,6 +353,8 @@ ApplicationTypesWindow::_RemoveUninstalled()
|
||||
}
|
||||
}
|
||||
|
||||
progressWindow->PostMessage(B_QUIT_REQUESTED);
|
||||
|
||||
char message[512];
|
||||
snprintf(message, sizeof(message), "%ld Application Type%s could be removed.",
|
||||
removed, removed == 1 ? "" : "s");
|
||||
@ -366,7 +464,6 @@ ApplicationTypesWindow::_SetType(BMimeType* type, int32 forceUpdate)
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
ApplicationTypesWindow::FrameResized(float width, float height)
|
||||
{
|
||||
@ -393,6 +490,25 @@ ApplicationTypesWindow::MessageReceived(BMessage* message)
|
||||
break;
|
||||
}
|
||||
|
||||
case kMsgTypeInvoked:
|
||||
{
|
||||
int32 index;
|
||||
if (message->FindInt32("index", &index) == B_OK) {
|
||||
MimeTypeItem* item = (MimeTypeItem*)fTypeListView->ItemAt(index);
|
||||
if (item != NULL) {
|
||||
BMimeType type(item->Type());
|
||||
entry_ref ref;
|
||||
if (type.GetAppHint(&ref) == B_OK) {
|
||||
BMessage refs(B_REFS_RECEIVED);
|
||||
refs.AddRef("refs", &ref);
|
||||
|
||||
be_app->PostMessage(&refs);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case kMsgRemoveUninstalled:
|
||||
_RemoveUninstalled();
|
||||
break;
|
||||
|
@ -7,11 +7,15 @@
|
||||
#include "MimeTypeListView.h"
|
||||
|
||||
#include <Bitmap.h>
|
||||
#include <MessageRunner.h>
|
||||
|
||||
|
||||
// TODO: lazy type collecting (super types only at startup)
|
||||
|
||||
|
||||
const uint32 kMsgAddType = 'adtp';
|
||||
|
||||
|
||||
status_t
|
||||
icon_for_type(BMimeType& type, BBitmap& bitmap, icon_size size,
|
||||
icon_source* _source)
|
||||
@ -430,6 +434,51 @@ MimeTypeListView::_MakeTypesUnique(MimeTypeItem* underItem)
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
MimeTypeListView::_AddNewType(const char* type)
|
||||
{
|
||||
MimeTypeItem* item = FindItem(type);
|
||||
|
||||
BMimeType mimeType(type);
|
||||
bool isApp = mimetype_is_application_signature(mimeType);
|
||||
if (fApplicationMode ^ isApp || !mimeType.IsInstalled()) {
|
||||
if (item != NULL) {
|
||||
// type doesn't belong here
|
||||
RemoveItem(item);
|
||||
delete item;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (item != NULL) {
|
||||
// for some reason, the type already exists
|
||||
return;
|
||||
}
|
||||
|
||||
BMimeType superType;
|
||||
MimeTypeItem* superItem = NULL;
|
||||
if (mimeType.GetSupertype(&superType) == B_OK)
|
||||
superItem = FindItem(superType.Type());
|
||||
|
||||
item = new MimeTypeItem(mimeType, fShowIcons, fSupertype.Type() != NULL);
|
||||
item->SetApplicationMode(isApp);
|
||||
|
||||
if (superItem != NULL) {
|
||||
AddUnder(item, superItem);
|
||||
InvalidateItem(IndexOf(superItem));
|
||||
// the super item is not picked up from the class (ie. bug)
|
||||
} else
|
||||
AddItem(item);
|
||||
|
||||
UpdateItem(item);
|
||||
|
||||
if (!fSelectNewType.ICompare(mimeType.Type())) {
|
||||
SelectItem(item);
|
||||
fSelectNewType = "";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
MimeTypeListView::AttachedToWindow()
|
||||
{
|
||||
@ -470,7 +519,7 @@ MimeTypeListView::MessageReceived(BMessage* message)
|
||||
case B_SHORT_DESCRIPTION_CHANGED:
|
||||
{
|
||||
// update label
|
||||
|
||||
|
||||
MimeTypeItem* item = FindItem(type);
|
||||
if (item != NULL)
|
||||
UpdateItem(item);
|
||||
@ -478,33 +527,17 @@ MimeTypeListView::MessageReceived(BMessage* message)
|
||||
}
|
||||
case B_MIME_TYPE_CREATED:
|
||||
{
|
||||
// create new item
|
||||
BMimeType created(type);
|
||||
bool isApp = mimetype_is_application_signature(created);
|
||||
if (fApplicationMode ^ isApp)
|
||||
break;
|
||||
// delay creation of new item a bit, until the type is fully installed
|
||||
|
||||
BMimeType superType;
|
||||
MimeTypeItem* superItem = NULL;
|
||||
if (created.GetSupertype(&superType) == B_OK)
|
||||
superItem = FindItem(superType.Type());
|
||||
BMessage addType(kMsgAddType);
|
||||
addType.AddString("type", type);
|
||||
|
||||
MimeTypeItem* item = new MimeTypeItem(created, fShowIcons,
|
||||
fSupertype.Type() != NULL);
|
||||
item->SetApplicationMode(isApp);
|
||||
|
||||
if (superItem != NULL) {
|
||||
AddUnder(item, superItem);
|
||||
InvalidateItem(IndexOf(superItem));
|
||||
// the super item is not picked up from the class (ie. bug)
|
||||
} else
|
||||
AddItem(item);
|
||||
|
||||
UpdateItem(item);
|
||||
|
||||
if (!fSelectNewType.ICompare(type)) {
|
||||
SelectItem(item);
|
||||
fSelectNewType = "";
|
||||
// TODO: free runner again!
|
||||
BMessageRunner* runner = new BMessageRunner(this, &addType,
|
||||
200000ULL, 1);
|
||||
if (runner->InitCheck() != B_OK) {
|
||||
delete runner;
|
||||
_AddNewType(type);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -519,15 +552,23 @@ MimeTypeListView::MessageReceived(BMessage* message)
|
||||
break;
|
||||
}
|
||||
case B_PREFERRED_APP_CHANGED:
|
||||
{
|
||||
// try to add or remove this type (changing the preferred app
|
||||
// might change visibility in our list)
|
||||
_AddNewType(type);
|
||||
|
||||
// supposed to fall through
|
||||
}
|
||||
case B_ICON_CHANGED:
|
||||
// TODO: take B_ICON_FOR_TYPE_CHANGED into account, too
|
||||
if (fShowIcons) {
|
||||
{
|
||||
MimeTypeItem* item = FindItem(type);
|
||||
if (item != NULL && fShowIcons) {
|
||||
// refresh item
|
||||
MimeTypeItem* item = FindItem(type);
|
||||
if (item != NULL)
|
||||
InvalidateItem(IndexOf(item));
|
||||
InvalidateItem(IndexOf(item));
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
@ -535,6 +576,14 @@ MimeTypeListView::MessageReceived(BMessage* message)
|
||||
break;
|
||||
}
|
||||
|
||||
case kMsgAddType:
|
||||
{
|
||||
const char* type;
|
||||
if (message->FindString("type", &type) == B_OK)
|
||||
_AddNewType(type);
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
BOutlineListView::MessageReceived(message);
|
||||
}
|
||||
|
@ -79,6 +79,7 @@ class MimeTypeListView : public BOutlineListView {
|
||||
void _CollectSubtypes(const char* supertype, MimeTypeItem* supertypeItem);
|
||||
void _CollectTypes();
|
||||
void _MakeTypesUnique(MimeTypeItem* underItem = NULL);
|
||||
void _AddNewType(const char* type);
|
||||
|
||||
BMimeType fSupertype;
|
||||
BString fSelectNewType;
|
||||
|
Loading…
x
Reference in New Issue
Block a user