void TPanelWindowView::RemovePanel( TInnerPanel *panel )
{
	BAutolock( &fPanels.lock );
	fPanels.RemoveItem( panel );
	if ( fPreviousMouseMovedPanel == panel )
		fPreviousMouseMovedPanel = 0;
	delete panel;
	ChangedSize(0); // force reposition of other panels
}
 QString ManualCaptchaSolver::Solve(const QString& base64)
 {
     emit Used();
     emit ChangedSize(++Size);
     SingleCaptchaWidget *w = new SingleCaptchaWidget();
     w->setParent(Widget);
     w->SetCaptcha(base64,QString::number(IdCounter));
     connect(w,SIGNAL(Done(QString,QString,bool)),this,SIGNAL(Done(QString,QString,bool)));
     Layout->addWidget(w);
     return QString::number(IdCounter++);
 }
    ManualCaptchaSolver::ManualCaptchaSolver(QObject *parent) :
        ISolver(parent),
        IdCounter(0),Size(0)
    {
        Scroll = new QScrollArea();

        Widget = new QWidget(Scroll);
        Scroll->setWidget(Widget);
        Scroll->setWidgetResizable(true);
        Layout = new FlowLayout(Widget,-1,10);
        Scroll->widget()->setLayout(Layout);
        emit ChangedSize(0);
        connect(this,SIGNAL(Done(QString,QString,bool)),this,SLOT(DoneSlot(QString,QString,bool)));
    }
bool TPanelWindowView::MoveTabTo( TInnerPanel *panel, int32 index )
{
	BAutolock( &fPanels.lock );
	int32 prev_index = fPanels.IndexOf(panel);
	if ( prev_index < 0 )
	{
		return false;
	}
	fPanels.RemoveItem(panel);
	fPanels.AddItem(panel, index);

	if ( index > prev_index )
		panel = fPanels.ItemAt(prev_index);

	ChangedSize( panel );

	return true;
}
bool TPanelWindowView::SetOptions( const char *option, const BMessage *msg )
{
	if ( !strcasecmp( option, "TransparentMenus" ) )
	{
		if ( msg->FindBool( "data", &fUseTransparentMenus ) != B_OK )
			return false;
	}
	else if ( !strcasecmp( option, "DrawOuterFrame" ) )
	{
		if ( msg->FindBool( "data", &fDrawOuterFrame ) != B_OK )
			return false;
		Invalidate();
	}
	else if ( !strcasecmp( option, "DockLocation" ) )
	{
		BString where;
		if ( msg->FindString( "data", &where ) != B_OK )
			return false;

		int32 fPreviousLocation = fLocation;

		if ( where == "top" )
			fLocation = kLocationTop;
		else if ( where == "bottom" )
			fLocation = kLocationBottom;
		else if ( where == "left" )
			fLocation = kLocationLeft;
		else if ( where == "right" )
			fLocation = kLocationRight;

		if ( fLocation != kLocationBottom )
		{
			fLocation = fPreviousLocation;
			(new BAlert("Warning", "Locations other than bottom aren't implemented in this build.", "Bummer"))->Go(0);
		}
		else
		{
			if ( fPreviousLocation != fLocation )
				((TPanelWindow*)Window())->DockChangedPlaces(fPreviousLocation);
		}
	}
	else if ( !strcasecmp( option, "BackColor" ) )
	{
		rgb_color *temp_c;
		ssize_t _size;
		if ( msg->FindData( "data", B_RGB_COLOR_TYPE, (const void**)&temp_c, &_size ) != B_OK)
			return false;
		fColor2 = *temp_c;
		Invalidate();
	}
	else if ( !strcasecmp( option, "OuterFrameColor" ) )
	{
		rgb_color *temp_c;
		ssize_t _size;
		if ( msg->FindData( "data", B_RGB_COLOR_TYPE, (const void**)&temp_c, &_size ) != B_OK)
			return false;
		fOuterFrameColor = *temp_c;
		Invalidate();
	}
	else if ( !strcasecmp( option, "AutoHide" ) )
	{
		bool autohide;
		if ( msg->FindBool( "data", &autohide ) != B_OK )
			return false;
		((TPanelWindow*)Window())->SetAutoHide(autohide);
	}
	else if ( !strcasecmp( option, "HideEffectDelay" ) )
	{
		int32 delay;
		if ( msg->FindInt32( "data", &delay ) != B_OK )
			return false;
		((TPanelWindow*)Window())->SetHideEffectDelay( delay );
	}
	else if ( !strcasecmp( option, "AlwaysOnTop" ) )
	{
		if ( msg->FindBool( "data", &fAlwaysOnTop ) != B_OK )
			return false;
		if ( fAlwaysOnTop )
			Window()->SetFeel( B_FLOATING_ALL_WINDOW_FEEL );
		else
			Window()->SetFeel( B_NORMAL_WINDOW_FEEL );
	}
	else if ( !strcasecmp( option, "HideStandardDeskbar" ) )
	{
		if ( msg->FindBool( "data", &fHideStandardDeskbar ) != B_OK )
			return false;
		
		BMessage msg(B_SET_PROPERTY);
		msg.AddBool( "data", fHideStandardDeskbar );
		msg.AddSpecifier( "Hidden" );
		msg.AddSpecifier( "Window", "Deskbar" );
		be_app->PostMessage(&msg);
	}
#ifdef USE_WINDOW_SHAPING
	else if ( !strcasecmp( option, "UseWindowShapping" ) )
	{
		if ( msg->FindBool( "data", &fUseWindowShapping ) != B_OK )
			return false;

		((TPanelWindow*)Window())->SetShowHideLimit( fUseWindowShapping ? 0.1f : 0.f );
		ChangedSize(0);
	}
#endif
	else if ( !strcasecmp( option, "DebugLevel" ) )
	{
		if ( msg->FindInt32( "data", &fDebugLevel ) != B_OK )
			return false;
	}
	else
		return false;

	return true;
}
void TPanelWindowView::MessageReceived( BMessage *message )
{
	if ( fDebugLevel >= 20 )
		message->PrintToStream();

	if ( message->what == B_GET_PROPERTY
		 || message->what == B_SET_PROPERTY
		 || message->what == B_COUNT_PROPERTIES
		 || message->what == B_CREATE_PROPERTY
		 || message->what == B_DELETE_PROPERTY
		 || message->what == B_EXECUTE_PROPERTY )
	{
		int32 index, what;
		BMessage specifier;
		const char *property;
		if ( message->GetCurrentSpecifier( &index, &specifier, &what, &property ) == B_OK )
		{
			BMessage reply( B_REPLY );
			if ( message->what == B_GET_PROPERTY
				 || message->what == B_COUNT_PROPERTIES
				 || message->what == B_EXECUTE_PROPERTY )
			{
				if ( GetOptions( property, &reply ) )
					reply.AddInt32( "error", 0 );
				else
					reply.AddInt32( "error", -1 );
			}
			else if ( message->what == B_SET_PROPERTY )
			{
				if ( SetOptions( property, message ) )
					reply.AddInt32( "error", 0 );
				else
					reply.AddInt32( "error", -1 );
			}
			else if ( message->what == B_CREATE_PROPERTY )
			{
				if ( !strcasecmp( property, "tab" ) )
				{
					int32 index;
					if ( message->FindInt32( "index", &index ) != B_OK )
						index = -1;
					TShortcutPanel *panel = new TShortcutPanel( this );

					fPanels.Lock();
					if ( index >= 0 )
					{
						TInnerPanel *rightpanel = fPanels.ItemAt(index);
						AddPanel( panel, rightpanel );
					}
					else
					{
						AddPanel( panel );
					}
					fPanels.Unlock();

					ChangedSize(0);

					reply.AddInt32( "error", 0 );
				}
				else
					reply.AddInt32( "error", -1 );
			}
			else if ( message->what == B_DELETE_PROPERTY )
			{
				int32 index;
				if ( specifier.FindInt32( "index", &index ) != B_OK )
					reply.AddInt32( "error", -1 );
				else
				{
					fPanels.Lock();
					TInnerPanel *panel = fPanels.ItemAt(index);
					if ( !panel )
						reply.AddInt32( "error", -1 );
					else
					{
						if ( panel != fRunningAppPanel )
						{
							RemovePanel( panel );
							reply.AddInt32( "error", 0 );
						}
						else
							reply.AddInt32( "error", -1 );
					}
					fPanels.Unlock();
				}
			}
			message->SendReply( &reply );
		}
		return;
	}

	if ( message->WasDropped() )
	{
		BPoint point = message->DropPoint();
		ConvertFromScreen( &point );
		TInnerPanel *panel = PanelAt( point );
		if ( message->what == 'IDRG' )
		{
			TPanelIcon *item;
			if ( message->FindPointer( "source", (void**)&item ) == B_OK )
			{
				TRaisingIconPanel *previous_parent = item->fParent;
				TRaisingIconPanel *rpanel;
				if ( modifiers() & B_CONTROL_KEY )
				{
					rpanel = new TShortcutPanel(this);
					bool left = false;
					if ( point.x < (panel->Frame().left+(panel->Frame().Width()/2) ) )
					{
						left = true;
					}
						
					rpanel = new TShortcutPanel(this);
					AddPanel( rpanel, left ? panel : 0 );
				}
				else
					rpanel = dynamic_cast<TRaisingIconPanel*>(panel);
				if ( rpanel && rpanel != fRunningAppPanel )
				{
					TPanelIcon *icon = rpanel->IconAt( point, true );
					if ( previous_parent == fRunningAppPanel && dynamic_cast<TShortcutPanel*>(rpanel) )
					{
						int32 index = rpanel->IndexOf(icon);
						AddShortcut( dynamic_cast<TShortcutPanel*>(rpanel), dynamic_cast<TAppPanelIcon*>(item)->Ref(), index );
					}
					else if ( !dynamic_cast<TTrashIcon*>(icon) || (modifiers() & B_SHIFT_KEY) )
					{
						previous_parent->RemoveItem( item, false );
						int32 index = rpanel->IndexOf(icon);
						rpanel->AddItem( item, index );
					}
					else
					{
						if ( item->Removable() )
							RemoveShortcut(item);
					}
					if ( previous_parent->CountItems() == 0 && previous_parent != fRunningAppPanel )
						RemovePanel( previous_parent );
				}
			}
		}
		else
		{
			if ( panel && panel->HitsFrame( point ) )
			{
				panel->HandleDroppedMessage( message, point );
			}
			else
			{
				HandleDroppedMessage( message, point );
			}
		}

		return;
	}

	switch ( message->what )
	{
	case kPanelWindowViewTimer:
		{
			if ( DoIconSmallerWithTime() == 0 )
			{
				fTimer->SetInterval( 999999999 );
			}
			break;
		}
	case T_MENU_CLOSED:
		{
			DebugCall( 8, "Got T_MENU_CLOSED" );

			TAwarePopupMenu *source;
			if ( message->FindPointer( "source", (void**)&source ) == B_OK )
			{
				if ( source == fOpenMenu )
				{
					DebugCall( 9, "fOpenMenu is now 0" );

					fOpenMenu = 0;
					BPoint point;
					uint32 buttons;
					GetMouse( &point, &buttons );
					if ( !Bounds().Contains( point ) )
						Window()->PostMessage(B_EXITED_VIEW);
				}
			}
			break;
		}
	case B_SOME_APP_LAUNCHED:
		{
			team_id tid;
			if ( message->FindInt32( "be:team", &tid ) != B_OK )
				break;
			const char *sig;
			if ( message->FindString( "be:signature", &sig ) != B_OK )
				break;
			entry_ref ref;
			if ( message->FindRef( "be:ref", &ref ) != B_OK )
				break;
			int32 flags;
			if ( message->FindInt32( "be:flags", &flags ) != B_OK )
				break;

			if ( sig && strlen(sig) && ( ( flags & B_BACKGROUND_APP ) == 0 ) )
				AddTeam( tid, sig, ref );

			break;
		}
	case B_SOME_APP_QUIT:
		{
			team_id tid;
			if ( message->FindInt32( "be:team", &tid ) != B_OK )
				break;

			RemoveTeam( tid );

			break;
		}
	case B_SOME_APP_ACTIVATED:
		{
			team_id tid;
			if ( message->FindInt32( "be:team", &tid ) == B_OK )
			{
				TAppPanelIcon *icon = ItemWith( tid );

				if ( icon != fLastActiveAppIcon )
				{
					DebugCall( 10, "B_SOME_APP_ACTIVATED %p[..]->%p[%i]", fLastActiveAppIcon, icon, tid );

					if ( fLastActiveAppIcon )
						fLastActiveAppIcon->SetActive( false );
					if ( icon )
						icon->SetActive( true );
					fLastActiveAppIcon = icon;
				}
			}

			BString temp;
			message->FindString( "be:signature", &temp );

			if ( temp != "application/x-vnd.Be-TSKB" )
				fLastActivatedAppSig = temp;

			break;
		}
	case kDoBubbleHelp:
		{
			BPoint point;
			uint32 buttons;
			GetMouse(&point, &buttons);
			if ( fPreviousMousePosition != point )
			{
				if ( fBubbleCounter > 0 )
				{
					if ( fBubbleCounter >= 6 )
					{
						fBubbleHelp->HideBubble();
					}
					fBubbleCounter = 0;
				}
				fPreviousMousePosition = point;
			}
			else
			{
				BRegion region;
				GetClippingRegion(&region);
				if ( region.Contains( point ) )
				{
					fBubbleCounter ++;
					if ( fBubbleCounter == 6 )
					{
						ConvertToScreen(&point);
						TBubbleTarget *target = fBubbleHelp->TargetAt( point );
						if (dynamic_cast<TTrackerIcon*>(target)) {
							TTrackerIcon *trackerIcon = dynamic_cast<TTrackerIcon*>(target);
							point.x = Window()->Frame().left + trackerIcon->ContentLocation().x + trackerIcon->Frame().Width() + 4;
							point.y = Window()->Frame().top;
							float height = TBubbleHelp::BubbleHeight(target);
							point.y += height;
							point.y += (Window()->Frame().Height() - height)/2 -4;
						}
						fBubbleHelp->ShowBubble( point, target );
					}
//					else if ( fBubbleCounter == 12 )
//					{
//						fBubbleHelp->HideBubble();
//					}
				}
			}
			break;
		}
	case 'flsh':
		{
			BMessenger target;
			if ( message->FindMessenger("source", &target ) == B_OK && target.IsValid() )
			{
				TAppPanelIcon *teamicon = ItemWith( target.Team() );
				if ( teamicon )
				{
//					todo: flashing
					teamicon->Flash();
				}
			}
			break;
		}
	case 'mctx':
		{
//			todo: context menus
			break;
		}
	default:
		BView::MessageReceived(message);
	}
}
void TPanelWindowView::ChangedSize( TInnerPanel *panel )
{
	BAutolock( &fPanels.lock );

	if ( !panel )
	{
		if ( fPanels.FirstItem() )
			ChangedSize( fPanels.FirstItem() );
		return;
	}

	if ( !fPanels.HasItem( panel ) )
	{
		return;
	}

	int index = fPanels.IndexOf(panel);
	TInnerPanel *prev = fPanels.ItemAt(index-1);

	BRect rect = panel->Frame();
	float w = rect.Width();
	rect.left = prev ? prev->Frame().right : 0;
	rect.right = rect.left + w;
	// hm.. :
/*	rect.bottom = rect.Height();
	rect.top = Bounds().Height() - rect.Height();
	rect.bottom += rect.top;*/
	Window()->Lock();
	panel->SetFrame(rect, false);
	panel->Invalidate();
	Window()->Unlock();

	if ( (index+1) < fPanels.CountItems() )
	{
		ChangedSize( fPanels.ItemAt(index+1) );
	}

	float width = 0;
	float height = 0;

	for ( index=0; index<fPanels.CountItems(); index++ )
	{
		panel = fPanels.ItemAt(index);
		width += panel->Frame().Width();
		if ( panel->Frame().Height() > height )
			height = panel->Frame().Height();
	}

	Window()->Lock();

	Window()->ResizeBy( width - Window()->Bounds().Width(), height - Window()->Bounds().Height() );

#ifdef USE_WINDOW_SHAPING
	BuildViewsPicture(fUseWindowShapping);
	Window()->ClipWindowToPicture( fMyPicture, BPoint(0, 0), 0 );
#endif

	dynamic_cast<TPanelWindow*>(Window())->CenterCorrectly();

	Window()->Unlock();
}
 void ManualCaptchaSolver::DoneSlot(const QString& val, const QString& id, bool res)
 {
     emit ChangedSize(--Size);
 }