<commit_before>/*
 * TNExternalVNCWindow.j
 *
 * Copyright (C) 2010 <NAME> <<EMAIL>>
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as
 * published by the Free Software Foundation, either version 3 of the
 * License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

@import <Foundation/Foundation.j>

@import <AppKit/CPImageView.j>
@import <AppKit/CPWindow.j>

@import <TNKit/TNToolbar.j>
@import <TNKit/TNToolbar.j>
@import <VNCCappuccino/TNVNCView.j>

var TNVNCWindowToolBarCtrlAltDel        = @"TNVNCWindowToolBarCtrlAltDel",
    TNVNCWindowToolBarSendPasteboard    = @"TNVNCWindowToolBarSendPasteboard",
    TNVNCWindowToolBarGetPasteboard     = @"TNVNCWindowToolBarGetPasteboard",
    TNVNCWindowToolBarFullScreen        = @"TNVNCWindowToolBarFullScreen",
    TNVNCWindowToolBarZoom              = @"TNVNCWindowToolBarZoom";


/*! @ingroup virtualmachinenovnc
    CPWindow that contains the external VNCView
*/
@implementation TNExternalVNCWindow : CPWindow
{
    CPImageView         _imageViewVirtualMachineAvatar;
    double              _currentZoom;
    TNStropheContact    _entity;
    TNToolbar           _mainToolbar;
    TNVNCView           _vncView;
}


#pragma mark -
#pragma mark Initialization

/*! intialize the window
    @param aRect the content rect of the window
    @param aStyleMask the style mask of the window
*/
- (id)initWithContentRect:(CGRect)aRect styleMask:(int)aStyleMask
{
    if (self = [super initWithContentRect:aRect styleMask:aStyleMask])
    {
        _currentZoom = 1.0;

        _mainToolbar = [[TNToolbar alloc] init];
        [self setToolbar:_mainToolbar];

        var zoomSlider = [[CPSlider alloc] initWithFrame:CPRectMake(0.0, 0.0, 96.0, 21.0)];
        [zoomSlider setMinValue:1.0];
        [zoomSlider setDoubleValue:100.0];
        [zoomSlider setMaxValue:200.0];

        [_mainToolbar addItemWithIdentifier:@"CUSTOMSPACE" label:@"              " view:nil target:nil action:nil];
        [_mainToolbar addItemWithIdentifier:TNVNCWindowToolBarGetPasteboard label:CPBundleLocalizedString(@"Get Clipboard", @"Get Clipboard") icon:[[CPBundle bundleForClass:[self class]] pathForResource:@"toolbarGetPasteboard.png"] target:self action:@selector(getPasteboard:)];
        [_mainToolbar addItemWithIdentifier:TNVNCWindowToolBarSendPasteboard label:CPBundleLocalizedString(@"Send Clipboard", @"Send Clipboard") icon:[[CPBundle bundleForClass:[self class]] pathForResource:@"toolbarSendPasteboard.png"] target:self action:@selector(sendPasteboard:)];
        [_mainToolbar addItemWithIdentifier:TNVNCWindowToolBarFullScreen label:CPBundleLocalizedString(@"Full Screen", @"Full Screen") icon:[[CPBundle mainBundle] pathForResource:@"IconsButtons/fullscreen.png"] target:self action:@selector(setFullScreen:)];
        [_mainToolbar addItemWithIdentifier:TNVNCWindowToolBarCtrlAltDel label:CPBundleLocalizedString(@"Ctrl Alt Del", @"Ctrl Alt Del") icon:[[CPBundle bundleForClass:[self class]] pathForResource:@"toolbarCtrlAtlDel.png"] target:self action:@selector(sendCtrlAltDel:)];
        zoomItem = [_mainToolbar addItemWithIdentifier:TNVNCWindowToolBarZoom label:CPBundleLocalizedString(@"Zoom", @"Zoom") view:zoomSlider target:self action:@selector(changeScale:)];

        [zoomItem setMinSize:CGSizeMake(120.0, 24.0)];
        [zoomItem setMaxSize:CGSizeMake(120.0, 24.0)];

        [_mainToolbar setPosition:0 forToolbarItemIdentifier:@"CUSTOMSPACE"];
        [_mainToolbar setPosition:1 forToolbarItemIdentifier:CPToolbarSeparatorItemIdentifier];
        [_mainToolbar setPosition:2 forToolbarItemIdentifier:TNVNCWindowToolBarGetPasteboard];
        [_mainToolbar setPosition:3 forToolbarItemIdentifier:TNVNCWindowToolBarSendPasteboard];
        [_mainToolbar setPosition:4 forToolbarItemIdentifier:TNVNCWindowToolBarCtrlAltDel];
        [_mainToolbar setPosition:5 forToolbarItemIdentifier:TNVNCWindowToolBarZoom];
        [_mainToolbar setPosition:10 forToolbarItemIdentifier:CPToolbarFlexibleSpaceItemIdentifier];
        [_mainToolbar setPosition:11 forToolbarItemIdentifier:TNVNCWindowToolBarFullScreen];
    }

    return self;
}


#pragma mark -
#pragma mark Notification handlers

/*! called when entity updates its vCard (and so the avatar)
    @param aNotification the notification
*/
- (void)_entityVCardUpdated:(CPNotification)aNotification
{
    [_imageViewVirtualMachineAvatar setImage:[_entity avatar]];
}

/*! called when entity updates its nickname
    @param aNotification the notification
*/
- (void)_entityNicknameUpdated:(CPNotification)aNotification
{
    [self setTitle:CPBundleLocalizedString(@"Screen for ", @"Screen for ") + [_entity nickname] + " (" + [_entity JID] + ")"];
    [[self platformWindow] setTitle:[self title]];
}


#pragma mark -
#pragma mark Utilities

/*! Initialize the window with given parameters
    @param aHost VNC host
    @param aPort VNC port
    @param aPassword VNC password
    @param isEncrypted set encrypted or not
    @param isTrueColor set true color or not
    @param aCheckRate the check rate
    @param aFBURate the FBU rate
*/
- (void)loadVNCViewWithHost:(CPString)aHost port:(CPString)aPort password:(CPString)aPassword encrypt:(BOOL)isEncrypted trueColor:(BOOL)isTrueColor checkRate:(int)aCheckRate FBURate:(int)aFBURate entity:(TNStropheContact)anEntity
{
    _entity = anEntity;

    [[CPNotificationCenter defaultCenter] addObserver:self selector:@selector(_entityVCardUpdated:) name:TNStropheContactVCardReceivedNotification object:_entity];
    [[CPNotificationCenter defaultCenter] addObserver:self selector:@selector(_entityNicknameUpdated:) name:TNStropheContactNicknameUpdatedNotification object:_entity];

    [self setTitle:CPBundleLocalizedString(@"Screen for ", @"Screen for ") + [_entity nickname] + " (" + [_entity JID] + ")"];
    [[self platformWindow] setTitle:[self title]];
    [[self platformWindow] DOMWindow].onbeforeunload = function(){
        [[CPRunLoop currentRunLoop] limitDateForMode:CPDefaultRunLoopMode];
        [self close];
        // FIXME: should we free self ?
    };

    _imageViewVirtualMachineAvatar = [[CPImageView alloc] initWithFrame:CPRectMake(7.0, 4.0, 50.0, 50.0)];
    [_imageViewVirtualMachineAvatar setImage:[_entity avatar]];
    [[_mainToolbar customSubViews] addObject:_imageViewVirtualMachineAvatar];
    [_mainToolbar reloadToolbarItems];

    _vncView  = [[TNVNCView alloc] initWithFrame:[[self contentView] bounds]];

    [_vncView setAutoresizingMask:CPViewWidthSizable | CPViewHeightSizable];
    [_vncView setFocusContainer:[[self platformWindow] DOMWindow].document];
    [_vncView setHost:aHost];
    [_vncView setPort:aPort];
    [_vncView setPassword:aPassword];
    [_vncView setZoom:1];
    [_vncView setTrueColor:isTrueColor];
    [_vncView setEncrypted:isEncrypted];
    [_vncView setCheckRate:aCheckRate];
    [_vncView setFrameBufferRequestRate:aFBURate];
    [_vncView setDelegate:self];<commit_msg>fix memory leak in external version of VNCWindow in Safari Lion DP4<commit_after>/*
 * TNExternalVNCWindow.j
 *
 * Copyright (C) 2010 <NAME> <<EMAIL>>
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as
 * published by the Free Software Foundation, either version 3 of the
 * License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

@import <Foundation/Foundation.j>

@import <AppKit/CPImageView.j>
@import <AppKit/CPWindow.j>

@import <TNKit/TNToolbar.j>
@import <TNKit/TNToolbar.j>
@import <VNCCappuccino/TNVNCView.j>

var TNVNCWindowToolBarCtrlAltDel        = @"TNVNCWindowToolBarCtrlAltDel",
    TNVNCWindowToolBarSendPasteboard    = @"TNVNCWindowToolBarSendPasteboard",
    TNVNCWindowToolBarGetPasteboard     = @"TNVNCWindowToolBarGetPasteboard",
    TNVNCWindowToolBarFullScreen        = @"TNVNCWindowToolBarFullScreen",
    TNVNCWindowToolBarZoom              = @"TNVNCWindowToolBarZoom";


/*! @ingroup virtualmachinenovnc
    CPWindow that contains the external VNCView
*/
@implementation TNExternalVNCWindow : CPWindow
{
    CPImageView         _imageViewVirtualMachineAvatar;
    double              _currentZoom;
    TNStropheContact    _entity;
    TNToolbar           _mainToolbar;
    TNVNCView           _vncView;
}


#pragma mark -
#pragma mark Initialization

/*! intialize the window
    @param aRect the content rect of the window
    @param aStyleMask the style mask of the window
*/
- (id)initWithContentRect:(CGRect)aRect styleMask:(int)aStyleMask
{
    if (self = [super initWithContentRect:aRect styleMask:aStyleMask])
    {
        _currentZoom = 1.0;

        _mainToolbar = [[TNToolbar alloc] init];
        [self setToolbar:_mainToolbar];

        var zoomSlider = [[CPSlider alloc] initWithFrame:CPRectMake(0.0, 0.0, 96.0, 21.0)];
        [zoomSlider setMinValue:1.0];
        [zoomSlider setDoubleValue:100.0];
        [zoomSlider setMaxValue:200.0];

        [_mainToolbar addItemWithIdentifier:@"CUSTOMSPACE" label:@"              " view:nil target:nil action:nil];
        [_mainToolbar addItemWithIdentifier:TNVNCWindowToolBarGetPasteboard label:CPBundleLocalizedString(@"Get Clipboard", @"Get Clipboard") icon:[[CPBundle bundleForClass:[self class]] pathForResource:@"toolbarGetPasteboard.png"] target:self action:@selector(getPasteboard:)];
        [_mainToolbar addItemWithIdentifier:TNVNCWindowToolBarSendPasteboard label:CPBundleLocalizedString(@"Send Clipboard", @"Send Clipboard") icon:[[CPBundle bundleForClass:[self class]] pathForResource:@"toolbarSendPasteboard.png"] target:self action:@selector(sendPasteboard:)];
        [_mainToolbar addItemWithIdentifier:TNVNCWindowToolBarFullScreen label:CPBundleLocalizedString(@"Full Screen", @"Full Screen") icon:[[CPBundle mainBundle] pathForResource:@"IconsButtons/fullscreen.png"] target:self action:@selector(setFullScreen:)];
        [_mainToolbar addItemWithIdentifier:TNVNCWindowToolBarCtrlAltDel label:CPBundleLocalizedString(@"Ctrl Alt Del", @"Ctrl Alt Del") icon:[[CPBundle bundleForClass:[self class]] pathForResource:@"toolbarCtrlAtlDel.png"] target:self action:@selector(sendCtrlAltDel:)];
        zoomItem = [_mainToolbar addItemWithIdentifier:TNVNCWindowToolBarZoom label:CPBundleLocalizedString(@"Zoom", @"Zoom") view:zoomSlider target:self action:@selector(changeScale:)];

        [zoomItem setMinSize:CGSizeMake(120.0, 24.0)];
        [zoomItem setMaxSize:CGSizeMake(120.0, 24.0)];

        [_mainToolbar setPosition:0 forToolbarItemIdentifier:@"CUSTOMSPACE"];
        [_mainToolbar setPosition:1 forToolbarItemIdentifier:CPToolbarSeparatorItemIdentifier];
        [_mainToolbar setPosition:2 forToolbarItemIdentifier:TNVNCWindowToolBarGetPasteboard];
        [_mainToolbar setPosition:3 forToolbarItemIdentifier:TNVNCWindowToolBarSendPasteboard];
        [_mainToolbar setPosition:4 forToolbarItemIdentifier:TNVNCWindowToolBarCtrlAltDel];
        [_mainToolbar setPosition:5 forToolbarItemIdentifier:TNVNCWindowToolBarZoom];
        [_mainToolbar setPosition:10 forToolbarItemIdentifier:CPToolbarFlexibleSpaceItemIdentifier];
        [_mainToolbar setPosition:11 forToolbarItemIdentifier:TNVNCWindowToolBarFullScreen];
    }

    return self;
}


#pragma mark -
#pragma mark Notification handlers

/*! called when entity updates its vCard (and so the avatar)
    @param aNotification the notification
*/
- (void)_entityVCardUpdated:(CPNotification)aNotification
{
    [_imageViewVirtualMachineAvatar setImage:[_entity avatar]];
}

/*! called when entity updates its nickname
    @param aNotification the notification
*/
- (void)_entityNicknameUpdated:(CPNotification)aNotification
{
    [self setTitle:CPBundleLocalizedString(@"Screen for ", @"Screen for ") + [_entity nickname] + " (" + [_entity JID] + ")"];
    [[self platformWindow] setTitle:[self title]];
}


#pragma mark -
#pragma mark Utilities

/*! Initialize the window with given parameters
    @param aHost VNC host
    @param aPort VNC port
    @param aPassword VNC password
    @param isEncrypted set encrypted or not
    @param isTrueColor set true color or not
    @param aCheckRate the check rate
    @param aFBURate the FBU rate
*/
- (void)loadVNCViewWithHost:(CPString)aHost port:(CPString)aPort password:(CPString)aPassword encrypt:(BOOL)isEncrypted trueColor:(BOOL)isTrueColor checkRate:(int)aCheckRate FBURate:(int)aFBURate entity:(TNStropheContact)anEntity
{
    _entity = anEntity;

    [[CPNotificationCenter defaultCenter] addObserver:self selector:@selector(_entityVCardUpdated:) name:TNStropheContactVCardReceivedNotification object:_entity];
    [[CPNotificationCenter defaultCenter] addObserver:self selector:@selector(_entityNicknameUpdated:) name:TNStropheContactNicknameUpdatedNotification object:_entity];

    [self setTitle:CPBundleLocalizedString(@"Screen for ", @"Screen for ") + [_entity nickname] + " (" + [_entity JID] + ")"];
    [[self platformWindow] setTitle:[self title]];

    var domWindow = [[self platformWindow] DOMWindow],
        unloadFunction = function(){
            [[CPRunLoop currentRunLoop] limitDateForMode:CPDefaultRunLoopMode];
            [self close];
        };

    if (domWindow.onbeforeunload)
        domWindow.onbeforeunload = unloadFunction
    else (domWindow.onunload)
        domWindow.onunload = unloadFunction
    else
        alert("Warning! I'm not happy to use javascript alert, but I have no other way to do it. Listen. I have no much time." +
            " Your browser don't support any known unload event. This will result as big memory leak each time you close this window!"+
            " Please report a bug at https://gitbub.com/primalmotion/Archipel/issues. I have to go! Good luck!");

    _imageViewVirtualMachineAvatar = [[CPImageView alloc] initWithFrame:CPRectMake(7.0, 4.0, 50.0, 50.0)];
    [_imageViewVirtualMachineAvatar setImage:[_entity avatar]];
    [[_mainToolbar customSubViews] addObject:_imageViewVirtualMachineAvatar];
    [_mainToolbar reloadToolbarItems];

    _vncView  = [[TNVNCView alloc] initWithFrame:[[self contentView] bounds]];

    [_vncView setAutoresizingMask:CPViewWidthSizable | CPViewHeightSizable];
    [_vncView setFocusContainer:[[self platformWindow] DOMWindow].document];
    [_vncView setHost:aHost];
    [_vncView setPort:aPort];
    [_vncView setPassword:aPassword];
    [_vncView setZoom:1];
    [_vncView setTrueColor:isTrueColor];
    [_vncView setEncrypted:isEncrypted];
    [_vncView setCheckRate:aCheckRate];
    [_vncView setFrameBufferRequestRate:aFBURate];
    [_vncView setDelegate:self];
{'fraction_non_alphanumeric': 0.0964255485383163, 'fraction_numerical': 0.008138550686893679, 'mean_word_length': 5.0401101061738105, 'pattern_counts': {'":': 0, '<': 23, '<?xml version=': 0, '>': 23, 'https://': 1, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1794163', 'n_tokens_mistral': 4699, 'n_tokens_neox': 4418, 'n_words': 1053}