<commit_before>// windows start menu add/delete /w squirrel install/uninstall
if(require('electron-squirrel-startup')) return;

const os = require('os');
const path = require('path');
const fs = require('fs');
const execFile = require('child_process').execFile;

const request = require('request');
const async = require('async');
const trash = require('trash');

const electron = require('electron');
const app = electron.app;
const BrowserWindow = electron.BrowserWindow;
const Tray = electron.Tray;
const Menu = electron.Menu;
const MenuItem = electron.MenuItem;
const NativeImage = electron.nativeImage;
const globalShortcut = electron.globalShortcut;
const clipboard = electron.clipboard;
const shell = electron.shell;
const ipc = electron.ipcMain;
const dialog = electron.dialog;

const electronDebug = require('electron-debug')();

const Settings = require('./settings');
const Services = require('./services');

const getTrayImage = (state=null, template=false) => {
    if (!state && os.platform() === 'win32') state = 'alt';
    if (template) {
        const trayImg = NativeImage.createFromPath(getTrayImage());
        trayImg.setTemplateImage(true);
        return trayImg;
    }
    return path.join(app.getAppPath(), 'img', `menu-${state ? `${state}-` : ''}icon@2x.png`);
}

class Pussh {
    constructor() {
        this.platform = os.platform();
        this.name = app.getName();
        this.version = app.getVersion();
        this.lastURLs = [];

        this.settingsWindow = null;
        this.editorWindow = null;
        this.workerWindow = null;
        this.cropWindow = null;

        // open hidden window to provide access to dom only apis
        this.workerWindow = new BrowserWindow({show: false});
        this.workerWindow.loadURL(`file://${path.join(app.getAppPath(), 'worker-window.html')}`);

        // worker window needs to be loaded first
        this.workerWindow.webContents.on('did-finish-load', () => {
            this.settings = new Settings();
            this.services = new Services(this.settings);

            this.watch();
            this.buildTrayMenu();
            this.firstLaunch();
            this.checkUpdates();
        });

        // hide the dock icon on os x
        if (this.platform == 'darwin') app.dock.hide();

        // open settings on app activate
        app.on('activate', () => this.showSettingsWindow());

        // keep the app open when closing the last window
        app.on('window-all-closed', () => {
            this.settingsWindow = null;
            this.editorWindow = null;
            this.workerWindow = null;
            this.cropWindow = null;
        });

        // unregister global hotkeys before quit
        app.on('will-quit', () => globalShortcut.unregisterAll());

        // create status item
        this.tray = new Tray(getTrayImage(null, true));
        this.tray.setPressedImage(getTrayImage('alt'));
    }

    firstLaunch() {
        if (this.settings.get('lastVersionLaunched') === this.version) return;
        this.showSettingsWindow();
        this.settings.set('lastVersionLaunched', this.version);
        this.settings.save();
    }

    checkUpdates() {
        if (!this.settings.get('checkForUpdates')) return;

        request.get({
            url: 'https://pussh.me/dl/pussh.json',
            timeout: 10000,
            json: true
        }, (error, response, body) => {
            if (error || !response || response.statusCode !== 200 || !data.version) return;

            if (this.version !== data.version) {
                const msg = 'Pussh has an update available. Click "OK" to open the Pussh download page.';
                if (!confirm(msg)) return;
                this.openInBrowser('https://pussh.me/');
            }
        });
    }

    showSettingsWindow() {
        if (this.settingsWindow) {
            this.settingsWindow.focus();
            return;
        }

        this.settingsWindow = new BrowserWindow({
            show: false,
            width: 900,
            height: 600,
            minWidth: 900,
            minHeight: 580,
            skipTaskbar: true,
            autoHideMenuBar: true
        });
        this.settingsWindow.setMenu(null);
        this.settingsWindow.loadURL(`file://${path.join(app.getAppPath(), 'settings-window.html')}`);
        this.settingsWindow.on('closed', () => this.settingsWindow = null);
        this.settingsWindow.webContents.on('did-finish-load', () => this.settingsWindow.show());
    }

    showEditorWindow() {
        if (!this.editorWindow) {
            this.editorWindow = new BrowserWindow({
                //show: false,
                width: 900,
                height: 600,
                minWidth: 900,
                minHeight: 580,
                skipTaskbar: true,
                autoHideMenuBar: true
            });
            this.editorWindow.on('closed', () => this.editorWindow = null);
            this.editorWindow.show
            //this.editorWindow.webContents.on('did-finish-load', () => this.editorWindow.show());
        }

        this.editorWindow.loadURL(`file://${path.join(app.getAppPath(), `editor-window.html?lastURL=${encodeURIComponent(this.lastURLs[0])}`)}`);
        this.editorWindow.focus();
    }

    setTrayState(state) {
        switch(state) {
            case 'off':
                this.tray.setImage(getTrayImage(null, true));
                break;
            case 'active':
                this.tray.setImage(getTrayImage('active'));
                break;
            case 'complete':
                this.tray.setImage(getTrayImage('done'));
                break;
        }
    }

    buildTrayMenu() {
        const menu = new Menu();

        if (this.lastURLs.length) {
            this.lastURLs.forEach(url => {
                menu.append(new MenuItem({
                    label: url,
                    click: () => this.copyToClipboard(url) && this.openInBrowser(url)
                }));
            });

            menu.append(new MenuItem({
                type: 'separator'
            }));

            // menu.append(new MenuItem({
            //     label: 'Open Editor',
            //     click: () => this.showEditorWindow()
            // }));

            // menu.append(new MenuItem({
            //     type: 'separator'
            // }));
        }

        menu.append(new MenuItem({
            label: 'Cropped Capture',
            click: () => {
                switch(this.platform) {
                    case 'darwin':
                        execFile('/usr/bin/osascript', ['-e', 'tell application "System Events" to keystroke "$" using {command down, shift down}']);
                        break;
                    case 'win32':
                        this.windowsCapture(true);
                        break;
                }
            }
        }));

        menu.append(new MenuItem({
            label: 'Screen Capture',
            click: () => {
                switch(this.platform) {
                    case 'darwin':
                        execFile('/usr/bin/osascript', ['-e', 'tell application "System Events" to keystroke "#" using {command down, shift down}']);
                        break;
                    case 'win32':
                        this.windowsCapture();
                        break;
                }
            }
        }));

        menu.append(new MenuItem({
            type: 'separator'
        }));

        menu.append(new MenuItem({
            label: 'Settings',
            click: () => this.showSettingsWindow()
        }));

        menu.append(new MenuItem({
            label: 'Quit '+this.name,
            click: () => app.quit()
        }));

        this.tray.setContextMenu(menu);
    }

    watch() {
        switch(this.platform) {
            case 'darwin':
                const desktopFolder = path.join(process.env['HOME'], 'Desktop');
                const checkedFiles = [];

                const checker = () => {
                    fs.readdir(desktopFolder, (err, files) => {
                        if (err || !files.length) return setTimeout(() => checker(), 1000);

                        // remove checked files that no longer exist on the desktop
                        checkedFiles
                        .filter(file => files.indexOf(file) === -1)
                        .forEach(file => checkedFiles.splice(checkedFiles.indexOf(file), 1));

                        // check for new screenshots
                        async.each(
                            files.filter(file => checkedFiles.indexOf(file) === -1 && /.png$/.test(file)),
                            (file, callback) => {
                                const filePath = path.join(desktopFolder, file);

                                // if file is too old, never check it again
                                if (Date.now() - fs.statSync(filePath).ctime.getTime() > 3000) {
                                    checkedFiles.push(file);
                                    return callback();
                                }

                                execFile('/usr/bin/mdls', ['--raw', '--name', 'kMDItemIsScreenCapture', filePath], (error, stdout) => {
                                    // 1 = screenshot, 0 = not a screenshot
                                    if (error || !parseInt(stdout)) return callback();

                                    console.log('Uploading %s', filePath);

                                    this.upload(this.moveToTemp(filePath), filePath);

                                    checkedFiles.push(file);
                                    callback();
                                });
                            },
                            () => {
                                setTimeout(() => checker(), 1000);
                            }
                        );
                    });
                };
                checker();
                break;
            case 'win32':
                globalShortcut.register("Alt+Shift+3", () => this.windowsCapture());
                globalShortcut.register("Alt+Shift+4", () => this.windowsCapture(true));
                break;
        }
    }

    windowsCapture(crop=false) {
        if (this.platform !== 'win32') return;

        // temp files
        const fullImg = path.join(app.getPath('temp'), 'pussh_screen.png');
        const cropImg = path.join(app.getPath('temp'), 'pussh_screen_crop.png');

        // take the screenshot and start crop if needed
        execFile(path.join(app.getAppPath(), 'bin', 'win', 'PusshCap.exe'), [fullImg], (error, stdout) => {
            if (error) return;

            if (!crop || !stdout) {
                this.upload(this.moveToTemp(fullImg), fullImg);
                return;
            }

            const allScreens = electron.screen.getAllDisplays();
            allScreens.forEach(s => {s.bounds.maxX = s.bounds.x + s.bounds.width; s.bounds.maxY = s.bounds.y + s.bounds.height; });
            const minX = allScreens.reduce((pv, cv) => pv < cv.bounds.x ? pv : cv.bounds.x, 0);
            const minY = allScreens.reduce((pv, cv) => pv < cv.bounds.y ? pv : cv.bounds.y, 0);
            const maxWidth = allScreens.reduce((pv, cv) => pv <= cv.bounds.maxX ? cv.bounds.maxX : pv, 0) + Math.abs(minX);
            const maxHeight = allScreens.reduce((pv, cv) => pv <= cv.bounds.maxY ? cv.bounds.maxY : pv, 0) + Math.abs(minY);

            this.cropWindow = new BrowserWindow({
                width: maxWidth,
                height: maxHeight,
                x: minX,
                y: minY,
                show: false,
                frame: false,
                alwaysOnTop: true,
                skipTaskbar: true,
                autoHideMenuBar: true,
                enableLargerThanScreen: true
            });
            this.cropWindow.setSize(maxWidth, maxHeight);

            this.cropWindow.on('closed', () => {
                this.cropWindow = null;
                if (!fs.existsSync(cropImg)) return;
                this.deleteFile(fullImg);
                this.upload(this.moveToTemp(cropImg), cropImg);
            });

            this.cropWindow.loadURL(`file://${path.join(app.getAppPath(), 'crop-window.html')}`);
        });
    }

    upload(file, oldFile) {
        const selectedService = this.settings.get('selectedService');

        file = this.randomizeFilename(file);
        file = this.prefixFilename(file);

        // set status icon to active
        this.setTrayState('active');

        this.resize(file, () => {
            this.services.get(selectedService).upload(file, (err, url) => {
                if (err || !url) {
                    this.setTrayState('off');
                    dialog.showMessageBox({type: 'error', buttons: ['Ok'], message: 'An error has occured :(', detail: err.message});
                    return;
                }

                this.lastURLs.unshift(url);
                this.lastURLs = this.lastURLs.slice(0, 10);

                // rebuild the tray menu with the new url
                this.buildTrayMenu();

                // save link to clipboard
                this.copyToClipboard(url);

                // remove files
                if (oldFile) this.trash(oldFile);
                this.deleteFile(file);

                // audio notification
                if (this.settings.get('audioNotifications')) {
                    this.workerWindow.webContents.send('audio-notify', 'fire');
                }

                // open in browser
                if (this.settings.get('openBrowser')) {
                    this.openInBrowser(url);
                }

                // set status icon to 'complete' for 3 seconds
                this.setTrayState('complete');
                setTimeout(() => this.setTrayState('off'), 3000);
            });
        });
    }

    moveToTemp(file) {
        const tmpFile = path.join(app.getPath('temp'), Date.now() + path.basename(file));
        fs.writeFileSync(tmpFile, fs.readFileSync(file));
        return tmpFile;
    }

    trash(file) {
        if (this.settings.get('sendToTrash') === false) return;

        trash([file]);
    }

    deleteFile(file) {
        fs.unlinkSync(file);
    }

    randomizeFilename(file) {
        if (this.settings.get('randomizeFilenames') === false) return file;

        const characters = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
        let newName = "";
        for(let i = 0; i < this.settings.get('randomizeFilenamesLength'); i++) {
            newName += characters.charAt(Math.floor(Math.random() * characters.length));
        }
        newName += path.extname(file); // Append file extension

        var newFile = path.join(path.dirname(file), newName);
        fs.renameSync(file, newFile);
        return newFile;
    }

    prefixFilename(file) {
        if (!this.settings.get('prefixFilenames')) return file;

        var newName = this.settings.get('prefixFilenames') + path.basename(file);

        var newFile = path.join(path.dirname(file), newName);
        fs.renameSync(file, newFile);
        return newFile;
    }

    // Retina screens cause huge screenshots, so we give the option to resize
    resize(file, callback) {
        if (this.platform !== 'darwin' || this.settings.get('retinaResize') === false) return callback();

        execFile('/usr/bin/sips', ['-g', 'dpiWidth', '-g', 'pixelWidth', file], (error, stdout) => {
            if (error) return callback();

            const lines = stdout.split('\n');

            const dpiWidth = parseFloat(lines[1].split(':')[1].trim());
            const pixelWidth = parseInt(lines[2].split(':')[1].trim());

            if (parseInt(dpiWidth) === 72) return callback();

            const newWidth = Math.round((72 / dpiWidth) * pixelWidth);

            execFile('/usr/bin/sips', ['--resampleWidth', newWidth, file], (error, stdout) => {
                callback();
            });
        });
    }

    notify(body, url) {
        if (!this.settings.get('enableNotifications')) return;

        this.workerWindow.webContents.send('system-notify', body, url);
    }

    openInBrowser(url) {
        shell.openExternal(url);
    }

    copyToClipboard(url) {
        clipboard.writeText(url);
        this.notify('The screenshot URL has been copied to your clipboard.', url);
    }
}

app.on('ready', () => global.Pussh = new Pussh());
<commit_msg>formatting<commit_after>// windows start menu add/delete /w squirrel install/uninstall
if(require('electron-squirrel-startup')) return;

const os = require('os');
const path = require('path');
const fs = require('fs');
const execFile = require('child_process').execFile;

const request = require('request');
const async = require('async');
const trash = require('trash');

const electron = require('electron');
const app = electron.app;
const BrowserWindow = electron.BrowserWindow;
const Tray = electron.Tray;
const Menu = electron.Menu;
const MenuItem = electron.MenuItem;
const NativeImage = electron.nativeImage;
const globalShortcut = electron.globalShortcut;
const clipboard = electron.clipboard;
const shell = electron.shell;
const ipc = electron.ipcMain;
const dialog = electron.dialog;

const electronDebug = require('electron-debug')();

const Settings = require('./settings');
const Services = require('./services');

const getTrayImage = (state=null, template=false) => {
    if (!state && os.platform() === 'win32') state = 'alt';
    if (template) {
        const trayImg = NativeImage.createFromPath(getTrayImage());
        trayImg.setTemplateImage(true);
        return trayImg;
    }
    return path.join(app.getAppPath(), 'img', `menu-${state ? `${state}-` : ''}icon@2x.png`);
}

class Pussh {
    constructor() {
        this.platform = os.platform();
        this.name = app.getName();
        this.version = app.getVersion();
        this.lastURLs = [];

        this.settingsWindow = null;
        this.editorWindow = null;
        this.workerWindow = null;
        this.cropWindow = null;

        // open hidden window to provide access to dom only apis
        this.workerWindow = new BrowserWindow({show: false});
        this.workerWindow.loadURL(`file://${path.join(app.getAppPath(), 'worker-window.html')}`);

        // worker window needs to be loaded first
        this.workerWindow.webContents.on('did-finish-load', () => {
            this.settings = new Settings();
            this.services = new Services(this.settings);

            this.watch();
            this.buildTrayMenu();
            this.firstLaunch();
            this.checkUpdates();
        });

        // hide the dock icon on os x
        if (this.platform == 'darwin') app.dock.hide();

        // open settings on app activate
        app.on('activate', () => this.showSettingsWindow());

        // keep the app open when closing the last window
        app.on('window-all-closed', () => {
            this.settingsWindow = null;
            this.editorWindow = null;
            this.workerWindow = null;
            this.cropWindow = null;
        });

        // unregister global hotkeys before quit
        app.on('will-quit', () => globalShortcut.unregisterAll());

        // create status item
        this.tray = new Tray(getTrayImage(null, true));
        this.tray.setPressedImage(getTrayImage('alt'));
    }

    firstLaunch() {
        if (this.settings.get('lastVersionLaunched') === this.version) return;
        this.showSettingsWindow();
        this.settings.set('lastVersionLaunched', this.version);
        this.settings.save();
    }

    checkUpdates() {
        if (!this.settings.get('checkForUpdates')) return;

        request.get({
            url: 'https://pussh.me/dl/pussh.json',
            timeout: 10000,
            json: true
        }, (error, response, body) => {
            if (error || !response || response.statusCode !== 200 || !data.version) return;

            if (this.version !== data.version) {
                const msg = 'Pussh has an update available. Click "OK" to open the Pussh download page.';
                if (!confirm(msg)) return;
                this.openInBrowser('https://pussh.me/');
            }
        });
    }

    showSettingsWindow() {
        if (this.settingsWindow) {
            this.settingsWindow.focus();
            return;
        }

        this.settingsWindow = new BrowserWindow({
            show: false,
            width: 900,
            height: 600,
            minWidth: 900,
            minHeight: 580,
            skipTaskbar: true,
            autoHideMenuBar: true
        });
        this.settingsWindow.setMenu(null);
        this.settingsWindow.loadURL(`file://${path.join(app.getAppPath(), 'settings-window.html')}`);
        this.settingsWindow.on('closed', () => this.settingsWindow = null);
        this.settingsWindow.webContents.on('did-finish-load', () => this.settingsWindow.show());
    }

    showEditorWindow() {
        if (!this.editorWindow) {
            this.editorWindow = new BrowserWindow({
                //show: false,
                width: 900,
                height: 600,
                minWidth: 900,
                minHeight: 580,
                skipTaskbar: true,
                autoHideMenuBar: true
            });
            this.editorWindow.on('closed', () => this.editorWindow = null);
            this.editorWindow.show
            //this.editorWindow.webContents.on('did-finish-load', () => this.editorWindow.show());
        }

        this.editorWindow.loadURL(`file://${path.join(app.getAppPath(), `editor-window.html?lastURL=${encodeURIComponent(this.lastURLs[0])}`)}`);
        this.editorWindow.focus();
    }

    setTrayState(state) {
        switch(state) {
            case 'off':
                this.tray.setImage(getTrayImage(null, true));
                break;
            case 'active':
                this.tray.setImage(getTrayImage('active'));
                break;
            case 'complete':
                this.tray.setImage(getTrayImage('done'));
                break;
        }
    }

    buildTrayMenu() {
        const menu = new Menu();

        if (this.lastURLs.length) {
            this.lastURLs.forEach(url => {
                menu.append(new MenuItem({
                    label: url,
                    click: () => this.copyToClipboard(url) && this.openInBrowser(url)
                }));
            });

            menu.append(new MenuItem({
                type: 'separator'
            }));

            // menu.append(new MenuItem({
            //     label: 'Open Editor',
            //     click: () => this.showEditorWindow()
            // }));

            // menu.append(new MenuItem({
            //     type: 'separator'
            // }));
        }

        menu.append(new MenuItem({
            label: 'Cropped Capture',
            click: () => {
                switch(this.platform) {
                    case 'darwin':
                        execFile('/usr/bin/osascript', ['-e', 'tell application "System Events" to keystroke "$" using {command down, shift down}']);
                        break;
                    case 'win32':
                        this.windowsCapture(true);
                        break;
                }
            }
        }));

        menu.append(new MenuItem({
            label: 'Screen Capture',
            click: () => {
                switch(this.platform) {
                    case 'darwin':
                        execFile('/usr/bin/osascript', ['-e', 'tell application "System Events" to keystroke "#" using {command down, shift down}']);
                        break;
                    case 'win32':
                        this.windowsCapture();
                        break;
                }
            }
        }));

        menu.append(new MenuItem({
            type: 'separator'
        }));

        menu.append(new MenuItem({
            label: 'Settings',
            click: () => this.showSettingsWindow()
        }));

        menu.append(new MenuItem({
            label: 'Quit '+this.name,
            click: () => app.quit()
        }));

        this.tray.setContextMenu(menu);
    }

    watch() {
        switch(this.platform) {
            case 'darwin':
                const desktopFolder = path.join(process.env['HOME'], 'Desktop');
                const checkedFiles = [];

                const checker = () => {
                    fs.readdir(desktopFolder, (err, files) => {
                        if (err || !files.length) return setTimeout(() => checker(), 1000);

                        // remove checked files that no longer exist on the desktop
                        checkedFiles
                        .filter(file => files.indexOf(file) === -1)
                        .forEach(file => checkedFiles.splice(checkedFiles.indexOf(file), 1));

                        // check for new screenshots
                        async.each(
                            files.filter(file => checkedFiles.indexOf(file) === -1 && /.png$/.test(file)),
                            (file, callback) => {
                                const filePath = path.join(desktopFolder, file);

                                // if file is too old, never check it again
                                if (Date.now() - fs.statSync(filePath).ctime.getTime() > 3000) {
                                    checkedFiles.push(file);
                                    return callback();
                                }

                                execFile('/usr/bin/mdls', ['--raw', '--name', 'kMDItemIsScreenCapture', filePath], (error, stdout) => {
                                    // 1 = screenshot, 0 = not a screenshot
                                    if (error || !parseInt(stdout)) return callback();

                                    console.log('Uploading %s', filePath);

                                    this.upload(this.moveToTemp(filePath), filePath);

                                    checkedFiles.push(file);
                                    callback();
                                });
                            },
                            () => {
                                setTimeout(() => checker(), 1000);
                            }
                        );
                    });
                };
                checker();
                break;
            case 'win32':
                globalShortcut.register("Alt+Shift+3", () => this.windowsCapture());
                globalShortcut.register("Alt+Shift+4", () => this.windowsCapture(true));
                break;
        }
    }

    windowsCapture(crop=false) {
        if (this.platform !== 'win32') return;

        // temp files
        const fullImg = path.join(app.getPath('temp'), 'pussh_screen.png');
        const cropImg = path.join(app.getPath('temp'), 'pussh_screen_crop.png');

        // take the screenshot and start crop if needed
        execFile(path.join(app.getAppPath(), 'bin', 'win', 'PusshCap.exe'), [fullImg], (error, stdout) => {
            if (error) return;

            if (!crop || !stdout) {
                this.upload(this.moveToTemp(fullImg), fullImg);
                return;
            }

            const allScreens = electron.screen.getAllDisplays();
            allScreens.forEach(s => {
                s.bounds.maxX = s.bounds.x + s.bounds.width;
                s.bounds.maxY = s.bounds.y + s.bounds.height;
            });
            const minX = allScreens.reduce((pv, cv) => pv < cv.bounds.x ? pv : cv.bounds.x, 0);
            const minY = allScreens.reduce((pv, cv) => pv < cv.bounds.y ? pv : cv.bounds.y, 0);
            const maxWidth = allScreens.reduce((pv, cv) => pv <= cv.bounds.maxX ? cv.bounds.maxX : pv, 0) + Math.abs(minX);
            const maxHeight = allScreens.reduce((pv, cv) => pv <= cv.bounds.maxY ? cv.bounds.maxY : pv, 0) + Math.abs(minY);

            this.cropWindow = new BrowserWindow({
                width: maxWidth,
                height: maxHeight,
                x: minX,
                y: minY,
                show: false,
                frame: false,
                alwaysOnTop: true,
                skipTaskbar: true,
                autoHideMenuBar: true,
                enableLargerThanScreen: true
            });
            this.cropWindow.setSize(maxWidth, maxHeight);

            this.cropWindow.on('closed', () => {
                this.cropWindow = null;
                if (!fs.existsSync(cropImg)) return;
                this.deleteFile(fullImg);
                this.upload(this.moveToTemp(cropImg), cropImg);
            });

            this.cropWindow.loadURL(`file://${path.join(app.getAppPath(), 'crop-window.html')}`);
        });
    }

    upload(file, oldFile) {
        const selectedService = this.settings.get('selectedService');

        file = this.randomizeFilename(file);
        file = this.prefixFilename(file);

        // set status icon to active
        this.setTrayState('active');

        this.resize(file, () => {
            this.services.get(selectedService).upload(file, (err, url) => {
                if (err || !url) {
                    this.setTrayState('off');
                    dialog.showMessageBox({type: 'error', buttons: ['Ok'], message: 'An error has occured :(', detail: err.message});
                    return;
                }

                this.lastURLs.unshift(url);
                this.lastURLs = this.lastURLs.slice(0, 10);

                // rebuild the tray menu with the new url
                this.buildTrayMenu();

                // save link to clipboard
                this.copyToClipboard(url);

                // remove files
                if (oldFile) this.trash(oldFile);
                this.deleteFile(file);

                // audio notification
                if (this.settings.get('audioNotifications')) {
                    this.workerWindow.webContents.send('audio-notify', 'fire');
                }

                // open in browser
                if (this.settings.get('openBrowser')) {
                    this.openInBrowser(url);
                }

                // set status icon to 'complete' for 3 seconds
                this.setTrayState('complete');
                setTimeout(() => this.setTrayState('off'), 3000);
            });
        });
    }

    moveToTemp(file) {
        const tmpFile = path.join(app.getPath('temp'), Date.now() + path.basename(file));
        fs.writeFileSync(tmpFile, fs.readFileSync(file));
        return tmpFile;
    }

    trash(file) {
        if (this.settings.get('sendToTrash') === false) return;

        trash([file]);
    }

    deleteFile(file) {
        fs.unlinkSync(file);
    }

    randomizeFilename(file) {
        if (this.settings.get('randomizeFilenames') === false) return file;

        const characters = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
        let newName = "";
        for(let i = 0; i < this.settings.get('randomizeFilenamesLength'); i++) {
            newName += characters.charAt(Math.floor(Math.random() * characters.length));
        }
        newName += path.extname(file); // Append file extension

        var newFile = path.join(path.dirname(file), newName);
        fs.renameSync(file, newFile);
        return newFile;
    }

    prefixFilename(file) {
        if (!this.settings.get('prefixFilenames')) return file;

        var newName = this.settings.get('prefixFilenames') + path.basename(file);

        var newFile = path.join(path.dirname(file), newName);
        fs.renameSync(file, newFile);
        return newFile;
    }

    // Retina screens cause huge screenshots, so we give the option to resize
    resize(file, callback) {
        if (this.platform !== 'darwin' || this.settings.get('retinaResize') === false) return callback();

        execFile('/usr/bin/sips', ['-g', 'dpiWidth', '-g', 'pixelWidth', file], (error, stdout) => {
            if (error) return callback();

            const lines = stdout.split('\n');

            const dpiWidth = parseFloat(lines[1].split(':')[1].trim());
            const pixelWidth = parseInt(lines[2].split(':')[1].trim());

            if (parseInt(dpiWidth) === 72) return callback();

            const newWidth = Math.round((72 / dpiWidth) * pixelWidth);

            execFile('/usr/bin/sips', ['--resampleWidth', newWidth, file], (error, stdout) => {
                callback();
            });
        });
    }

    notify(body, url) {
        if (!this.settings.get('enableNotifications')) return;

        this.workerWindow.webContents.send('system-notify', body, url);
    }

    openInBrowser(url) {
        shell.openExternal(url);
    }

    copyToClipboard(url) {
        clipboard.writeText(url);
        this.notify('The screenshot URL has been copied to your clipboard.', url);
    }
}

app.on('ready', () => global.Pussh = new Pussh());
<|endoftext|>


<commit_before>var gulp = require('gulp');
var browserSync = require('browser-sync');

var config = require('../config.js');

// Static server
gulp.task('browser-sync', function() {
    browserSync({
        server: {
            baseDir: config.build
        },
        open: config.defaults.browserSync.open
    });
});
<commit_msg>Browsersync ghostMode set to false by default<commit_after>var gulp = require('gulp');
var browserSync = require('browser-sync');

var config = require('../config.js');

// Static server
gulp.task('browser-sync', function() {
    browserSync({
        server: {
            baseDir: config.build
        },
        ghostMode: false,
        open: config.defaults.browserSync.open
    });
});
<|endoftext|>


<commit_before>(function(window) {

  /** Use a single load function */
  var load = typeof require == 'function' ? require : window.load;

  /** Load Benchmark.js */
  var Benchmark =
    window.Benchmark || (
      Benchmark = load('../vendor/benchmark.js/benchmark.js') || window.Benchmark,
      Benchmark.Benchmark || Benchmark
    );

  /** Load Lo-Dash */
  var lodash =
    window.lodash || (
      lodash = load('../lodash.js') || window._,
      lodash = lodash._ || lodash,
      lodash.noConflict()
    );

  /** Load Underscore */
  var _ =
    window._ || (
      _ = load('../vendor/underscore/underscore.js') || window._,
      _._ || _
    );

  /** Used to score Lo-Dash and Underscore performance */
  var score = { 'lodash': 0, 'underscore': 0 };

  /** Use a queue benchmark suites */
  var suites = [];

  /** Add `console.log()` support for Narwhal and RingoJS */
  window.console || (window.console = { 'log': window.print });

  /** Expose functions to the global object */
  window._ = _;
  window.Benchmark = Benchmark;
  window.lodash = lodash;

  /*--------------------------------------------------------------------------*/

  lodash.extend(Benchmark.options, {
    'async': true,
    'setup': function() {
      var window = Function('return this || global')(),
          _ = window._,
          lodash = window.lodash,
          numbers = [],
          object = {};

      for (var index = 0; index < 20; index++) {
        numbers[index] = index;
        object['key' + index] = index;
      }

      var objects = lodash.map(numbers, function(n) {
        return { 'num': n };
      });
    }
  });

  lodash.extend(Benchmark.Suite.options, {
    'onStart': function() {
      console.log('\n' + this.name + ':');
    },
    'onCycle': function(event) {
      console.log(event.target.toString());
    },
    'onComplete': function() {
      var fastest = this.filter('fastest').pluck('name');
      if (fastest.length > 1) {
        console.log('It\'s too close to call.');
      } else {
        console.log(fastest + ' is the fastest.');
      }
      score.lodash += Math.floor(1 / (this[0].stats.mean + this[0].stats.moe));
      score.underscore += Math.floor(1 / (this[1].stats.mean + this[1].stats.moe));

      // remove from current suite from queue
      suites.shift();

      if (suites.length) {
        // run next suite
        suites[0].run();
      }
      else {
        // report results
        if (score.lodash >= score.underscore) {
          console.log('\nLo-Dash is ' + (score.lodash / score.underscore).toFixed(2) + 'x faster than Underscore.\n');
        } else {
          console.log('\nUnderscore is ' + (score.underscore / score.lodash).toFixed(2) + 'x faster than Lo-Dash.\n');
        }
      }
    }
  });

  /*--------------------------------------------------------------------------*/

  suites.push(
    Benchmark.Suite('each array')
      .add('Lo-Dash', function() {
        var timesTwo = [];
        lodash.each(numbers, function(num) {
          timesTwo.push(num * 2);
        });
      })
      .add('Underscore', function() {
        var timesTwo = [];
        _.each(numbers, function(num) {
          timesTwo.push(num * 2);
        });
      })
  );

  /*--------------------------------------------------------------------------*/

  suites.push(
    Benchmark.Suite('each object')
      .add('Lo-Dash', function() {
        var timesTwo = [];
        lodash.each(object, function(num) {
          timesTwo.push(num * 2);
        });
      })
      .add('Underscore', function() {
        var timesTwo = [];
        _.each(object, function(num) {
          timesTwo.push(num * 2);
        });
      })
  );

  /*--------------------------------------------------------------------------*/

  suites.push(
    Benchmark.Suite('keys')
      .add('Lo-Dash', function() {
        lodash.keys( object );
      })
      .add('Underscore', function() {
        _.keys( object );
      })
  );

  /*--------------------------------------------------------------------------*/

  suites.push(
    Benchmark.Suite('map')
      .add('Lo-Dash', function() {
        lodash.map( objects, function( obj ) {
          return obj.num;
        });
      })
      .add('Underscore', function() {
        _.map( objects, function( obj ) {
          return obj.num;
        });
      })
  );

  /*--------------------------------------------------------------------------*/

  suites.push(
    Benchmark.Suite('pluck')
      .add('Lo-Dash', function() {
        lodash.pluck(objects, 'num');
      })
      .add('Underscore', function() {
        _.pluck(objects, 'num');
      })
  );

  /*--------------------------------------------------------------------------*/

  suites.push(
    Benchmark.Suite('values')
      .add('Lo-Dash', function() {
        lodash.values(objects);
      })
      .add('Underscore', function() {
        _.values(objects);
      })
  );

  /*--------------------------------------------------------------------------*/

  // start suites
  suites[0].run();

}(typeof global == 'object' && global || this));
<commit_msg>Cleanup pref.'s style and add comment.<commit_after>(function(window) {

  /** Use a single load function */
  var load = typeof require == 'function' ? require : window.load;

  /** Load Benchmark.js */
  var Benchmark =
    window.Benchmark || (
      Benchmark = load('../vendor/benchmark.js/benchmark.js') || window.Benchmark,
      Benchmark.Benchmark || Benchmark
    );

  /** Load Lo-Dash */
  var lodash =
    window.lodash || (
      lodash = load('../lodash.js') || window._,
      lodash = lodash._ || lodash,
      lodash.noConflict()
    );

  /** Load Underscore */
  var _ =
    window._ || (
      _ = load('../vendor/underscore/underscore.js') || window._,
      _._ || _
    );

  /** Used to score Lo-Dash and Underscore performance */
  var score = { 'lodash': 0, 'underscore': 0 };

  /** Use a queue benchmark suites */
  var suites = [];

  /** Add `console.log()` support for Narwhal and RingoJS */
  window.console || (window.console = { 'log': window.print });

  /** Expose functions to the global object */
  window._ = _;
  window.Benchmark = Benchmark;
  window.lodash = lodash;

  /*--------------------------------------------------------------------------*/

  lodash.extend(Benchmark.options, {
    'async': true,
    'setup': function() {
      var window = Function('return this || global')(),
          _ = window._,
          lodash = window.lodash,
          numbers = [],
          object = {};

      for (var index = 0; index < 20; index++) {
        numbers[index] = index;
        object['key' + index] = index;
      }

      var objects = lodash.map(numbers, function(n) {
        return { 'num': n };
      });
    }
  });

  lodash.extend(Benchmark.Suite.options, {
    'onStart': function() {
      console.log('\n' + this.name + ':');
    },
    'onCycle': function(event) {
      console.log(event.target.toString());
    },
    'onComplete': function() {
      var fastest = this.filter('fastest').pluck('name');
      if (fastest.length > 1) {
        console.log('It\'s too close to call.');
      } else {
        console.log(fastest + ' is the fastest.');
      }
      // add score adjusting for maring of error
      score.lodash += Math.floor(1 / (this[0].stats.mean + this[0].stats.moe));
      score.underscore += Math.floor(1 / (this[1].stats.mean + this[1].stats.moe));

      // remove from current suite from queue
      suites.shift();

      if (suites.length) {
        // run next suite
        suites[0].run();
      }
      else {
        // report results
        if (score.lodash >= score.underscore) {
          console.log('\nLo-Dash is ' + (score.lodash / score.underscore).toFixed(2) + 'x faster than Underscore.\n');
        } else {
          console.log('\nUnderscore is ' + (score.underscore / score.lodash).toFixed(2) + 'x faster than Lo-Dash.\n');
        }
      }
    }
  });

  /*--------------------------------------------------------------------------*/

  suites.push(
    Benchmark.Suite('each array')
      .add('Lo-Dash', function() {
        var timesTwo = [];
        lodash.each(numbers, function(num) {
          timesTwo.push(num * 2);
        });
      })
      .add('Underscore', function() {
        var timesTwo = [];
        _.each(numbers, function(num) {
          timesTwo.push(num * 2);
        });
      })
  );

  /*--------------------------------------------------------------------------*/

  suites.push(
    Benchmark.Suite('each object')
      .add('Lo-Dash', function() {
        var timesTwo = [];
        lodash.each(object, function(num) {
          timesTwo.push(num * 2);
        });
      })
      .add('Underscore', function() {
        var timesTwo = [];
        _.each(object, function(num) {
          timesTwo.push(num * 2);
        });
      })
  );

  /*--------------------------------------------------------------------------*/

  suites.push(
    Benchmark.Suite('keys')
      .add('Lo-Dash', function() {
        lodash.keys(object);
      })
      .add('Underscore', function() {
        _.keys(object);
      })
  );

  /*--------------------------------------------------------------------------*/

  suites.push(
    Benchmark.Suite('map')
      .add('Lo-Dash', function() {
        lodash.map(objects, function(obj) {
          return obj.num;
        });
      })
      .add('Underscore', function() {
        _.map(objects, function(obj) {
          return obj.num;
        });
      })
  );

  /*--------------------------------------------------------------------------*/

  suites.push(
    Benchmark.Suite('pluck')
      .add('Lo-Dash', function() {
        lodash.pluck(objects, 'num');
      })
      .add('Underscore', function() {
        _.pluck(objects, 'num');
      })
  );

  /*--------------------------------------------------------------------------*/

  suites.push(
    Benchmark.Suite('values')
      .add('Lo-Dash', function() {
        lodash.values(objects);
      })
      .add('Underscore', function() {
        _.values(objects);
      })
  );

  /*--------------------------------------------------------------------------*/

  // start suites
  suites[0].run();

}(typeof global == 'object' && global || this));
<|endoftext|>


<commit_before>$(function() {
  var field = $('#membershipName');
  var header = $('#memberships-search-header');
  var defaultHeader = header.text();
  var container = $('#memberships-search-container');

  // Since we send search requests async this is a possible set of events:
  //   - User types "m"
  //   - (1) We request search?q=m
  //   - User types "a"
  //   - (2) We request search?q=ma
  //   - We get the response from (2)
  //   - We get the response from (1)
  //
  // In this case we want to make sure the last response
  // does not overwrite the reponse from (2).
  var currRequest = 0;
  var currResponse = 0;

  function search(query) {
    var id = ++currRequest;

    var xhr = $.ajax('/memberships/search', {
      data: { q: query }
    });

    xhr.done(function() {
      if (id <= currResponse) {
        // A newer response was already rendered.
        return;
      }

      currResponse = id;
      container.html(xhr.responseText);
      if (query) {
        header.text("Search results for " + query);
      } else {
        header.text(defaultHeader);
      }
    });
  }

  // We start searching 100ms after you've pressed a key
  var delay = 100;
  var delayTimeout;

  field.on('input', function(evt) {
    if (delayTimeout) {
      clearTimeout(delayTimeout);
    }

    delayTimeout = setTimeout(function() {
      search(evt.target.value);
      delayTimeout = null;
    }, delay);
  });

  field.on('keydown', function(evt) {
    if (evt.which == 13) {
      // Prevent enter
      evt.preventDefault();
    }
  });
});

<commit_msg>Increase timeout slightly<commit_after>$(function() {
  var field = $('#membershipName');
  var header = $('#memberships-search-header');
  var defaultHeader = header.text();
  var container = $('#memberships-search-container');

  // Since we send search requests async this is a possible set of events:
  //   - User types "m"
  //   - (1) We request search?q=m
  //   - User types "a"
  //   - (2) We request search?q=ma
  //   - We get the response from (2)
  //   - We get the response from (1)
  //
  // In this case we want to make sure the last response
  // does not overwrite the reponse from (2).
  var currRequest = 0;
  var currResponse = 0;

  function search(query) {
    var id = ++currRequest;

    var xhr = $.ajax('/memberships/search', {
      data: { q: query }
    });

    xhr.done(function() {
      if (id <= currResponse) {
        // A newer response was already rendered.
        return;
      }

      currResponse = id;
      container.html(xhr.responseText);
      if (query) {
        header.text("Search results for " + query);
      } else {
        header.text(defaultHeader);
      }
    });
  }

  var delay = 200;
  var delayTimeout;

  field.on('input', function(evt) {
    if (delayTimeout) {
      clearTimeout(delayTimeout);
    }

    delayTimeout = setTimeout(function() {
      search(evt.target.value);
      delayTimeout = null;
    }, delay);
  });

  field.on('keydown', function(evt) {
    if (evt.which == 13) {
      // Prevent enter
      evt.preventDefault();
    }
  });
});

<|endoftext|>


<commit_before>(function ($) {
  // register namespace
  $.extend(true, window, {
    "Slick": {
      "CellExternalCopyManager": CellExternalCopyManager
    }
  });

  function CellExternalCopyManager(options) {
    /*
      This manager enables users to copy/paste data from/to an external Spreadsheet application
      such as MS-Excel® or OpenOffice-Spreadsheet.

      Since it is not possible to access directly the clipboard in javascript, the plugin uses
      a trick to do it's job. After detecting the keystroke, we dynamically create a textarea
      where the browser copies/pastes the serialized data.

      options:
        copiedCellStyle : sets the css className used for copied cells. default : "copied"
        copiedCellStyleLayerKey : sets the layer key for setting css values of copied cells. default : "copy-manager"
        dataItemColumnValueExtractor : option to specify a custom column value extractor function
        dataItemColumnValueSetter : option to specify a custom column value setter function
        clipboardCommandHandler : option to specify a custom handler for paste actions
        includeHeaderWhenCopying : set to true and the plugin will take the name property from each column (which is usually what appears in your header) and put that as the first row of the text that's copied to the clipboard
        bodyElement: option to specify a custom DOM element which to will be added the hidden textbox. It's useful if the grid is inside a modal dialog.
        onCopyInit: optional handler to run when copy action initializes
        onCopySuccess: optional handler to run when copy action is complete
        ingoreFormatting: optional array to specify fields of columns that ignore all formatters on paste
    */
    var _grid;
    var _self = this;
    var _copiedRanges;
    var _options = options || {};
    var _copiedCellStyleLayerKey = _options.copiedCellStyleLayerKey || "copy-manager";
    var _copiedCellStyle = _options.copiedCellStyle || "copied";
    var _clearCopyTI = 0;
    var _bodyElement = _options.bodyElement || document.body;
    var _onCopyInit = _options.onCopyInit || null;
    var _onCopySuccess = _options.onCopySuccess || null;
    var _ignoreFormatting = _options.ignoreFormatting || [];

    var keyCodes = {
      'C': 67,
      'V': 86,
      'ESC': 27,
      'INSERT': 45
    };

    function init(grid) {
      _grid = grid;
      _grid.onKeyDown.subscribe(handleKeyDown);

      // we need a cell selection model
      var cellSelectionModel = grid.getSelectionModel();
      if (!cellSelectionModel){
        throw new Error("Selection model is mandatory for this plugin. Please set a selection model on the grid before adding this plugin: grid.setSelectionModel(new Slick.CellSelectionModel())");
      }
      // we give focus on the grid when a selection is done on it.
      // without this, if the user selects a range of cell without giving focus on a particular cell, the grid doesn't get the focus and key stroke handles (ctrl+c) don't work
      cellSelectionModel.onSelectedRangesChanged.subscribe(function(e, args){
        _grid.focus();
      });
    }

    function destroy() {
      _grid.onKeyDown.unsubscribe(handleKeyDown);
    }

    function getDataItemValueForColumn(item, columnDef) {
      // If we initialized this with an ignoreFormatting option, don't do fancy formatting
      // on the specified fields (just return the plain JS value)
      for (var i=0; i<_ignoreFormatting.length; i++) {
        if (_ignoreFormatting[i] === columnDef.field) {
          return item[columnDef.field];
        }
      }
      if (_options.dataItemColumnValueExtractor) {
        return _options.dataItemColumnValueExtractor(item, columnDef);
      }

      var retVal = '';

      // use formatter if available; much faster than editor
      if (columnDef.formatter) {
          return columnDef.formatter(0, 0, item[columnDef.field], columnDef, item);
      }

      // if a custom getter is not defined, we call serializeValue of the editor to serialize
      if (columnDef.editor){
        var editorArgs = {
          'container':$("<p>"),  // a dummy container
          'column':columnDef,
          'position':{'top':0, 'left':0}  // a dummy position required by some editors
        };
        var editor = new columnDef.editor(editorArgs);
        editor.loadValue(item);
        retVal = editor.serializeValue();
        editor.destroy();
      }
      else {
        retVal = item[columnDef.field];
      }

      return retVal;
    }

    function setDataItemValueForColumn(item, columnDef, value) {
      if (_options.dataItemColumnValueSetter) {
        return _options.dataItemColumnValueSetter(item, columnDef, value);
      }

      // if a custom setter is not defined, we call applyValue of the editor to unserialize
      if (columnDef.editor){
        var editorArgs = {
          'container':$("body"),  // a dummy container
          'column':columnDef,
          'position':{'top':0, 'left':0}  // a dummy position required by some editors
        };
        var editor = new columnDef.editor(editorArgs);
        editor.loadValue(item);
        editor.applyValue(item, value);
        editor.destroy();
      }
    }

    function _createTextBox(innerText){
      var ta = document.createElement('textarea');
      ta.style.position = 'absolute';
      ta.style.left = '-1000px';
      ta.style.top = document.body.scrollTop + 'px';
      ta.value = innerText;
      _bodyElement.appendChild(ta);
      ta.select();

      return ta;
    }

    function _decodeTabularData(_grid, ta){
      var columns = _grid.getColumns();
      var clipText = ta.value;
      var clipRows = clipText.split(/[\n\f\r]/);
      var clippedRange = [];

      _bodyElement.removeChild(ta);

      for (var i=0; i<clipRows.length; i++) {
        if (clipRows[i]!="")
          clippedRange[i] = clipRows[i].split("\t");
      }

      var selectedCell = _grid.getActiveCell();
      var ranges = _grid.getSelectionModel().getSelectedRanges();
      var selectedRange = ranges && ranges.length ? ranges[0] : null;   // pick only one selection
      var activeRow = null;
      var activeCell = null;

      if (selectedRange){
        activeRow = selectedRange.fromRow;
        activeCell = selectedRange.fromCell;
      } else if (selectedCell){
        activeRow = selectedCell.row;
        activeCell = selectedCell.cell;
      } else {
        // we don't know where to paste
        return;
      }

      var oneCellToMultiple = false;
      var destH = clippedRange.length;
      var destW = clippedRange.length ? clippedRange[0].length : 0;
      if (clippedRange.length == 1 && clippedRange[0].length == 1 && selectedRange){
        oneCellToMultiple = true;
        destH = selectedRange.toRow - selectedRange.fromRow +1;
        destW = selectedRange.toCell - selectedRange.fromCell +1;
      }
	  var availableRows = _grid.getData().length - activeRow;
	  var addRows = 0;
	  if(availableRows < destH)
	  {
		var d = _grid.getData();
		for(addRows = 1; addRows <= destH - availableRows; addRows++)
			d.push({});
		_grid.setData(d);
		_grid.render();
	  }
      var clipCommand = {

        isClipboardCommand: true,
        clippedRange: clippedRange,
        oldValues: [],
        cellExternalCopyManager: _self,
        _options: _options,
        setDataItemValueForColumn: setDataItemValueForColumn,
        markCopySelection: markCopySelection,
        oneCellToMultiple: oneCellToMultiple,
        activeRow: activeRow,
        activeCell: activeCell,
        destH: destH,
        destW: destW,
        desty: activeRow,
        destx: activeCell,
        maxDestY: _grid.getDataLength(),
        maxDestX: _grid.getColumns().length,
        h: 0,
        w: 0,

        execute: function() {
          this.h=0;
          for (var y = 0; y < destH; y++){
            this.oldValues[y] = [];
            this.w=0;
            this.h++;
            for (var x = 0; x < destW; x++){
              this.w++;
              var desty = activeRow + y;
              var destx = activeCell + x;

              if (desty < this.maxDestY && destx < this.maxDestX ) {
                var nd = _grid.getCellNode(desty, destx);
                var dt = _grid.getDataItem(desty);
                this.oldValues[y][x] = dt[columns[destx]['id']];
                if (oneCellToMultiple)
                  this.setDataItemValueForColumn(dt, columns[destx], clippedRange[0][0]);
                else
                  this.setDataItemValueForColumn(dt, columns[destx], clippedRange[y] ? clippedRange[y][x] : '');
                _grid.updateCell(desty, destx);
              }
            }
          }

          var bRange = {
            'fromCell': activeCell,
            'fromRow': activeRow,
            'toCell': activeCell+this.w-1,
            'toRow': activeRow+this.h-1
          }

          this.markCopySelection([bRange]);
          _grid.getSelectionModel().setSelectedRanges([bRange]);
          this.cellExternalCopyManager.onPasteCells.notify({ranges: [bRange]});
        },

        undo: function() {
          for (var y = 0; y < destH; y++){
            for (var x = 0; x < destW; x++){
              var desty = activeRow + y;
              var destx = activeCell + x;

              if (desty < this.maxDestY && destx < this.maxDestX ) {
                var nd = _grid.getCellNode(desty, destx);
                var dt = _grid.getDataItem(desty);
                if (oneCellToMultiple)
                  this.setDataItemValueForColumn(dt, columns[destx], this.oldValues[0][0]);
                else
                  this.setDataItemValueForColumn(dt, columns[destx], this.oldValues[y][x]);
                _grid.updateCell(desty, destx);
              }
            }
          }

          var bRange = {
            'fromCell': activeCell,
            'fromRow': activeRow,
            'toCell': activeCell+this.w-1,
            'toRow': activeRow+this.h-1
          }

          this.markCopySelection([bRange]);
          _grid.getSelectionModel().setSelectedRanges([bRange]);
          this.cellExternalCopyManager.onPasteCells.notify({ranges: [bRange]});

          if(addRows > 1){
            var d = _grid.getData();
            for(; addRows > 1; addRows--)
              d.splice(d.length - 1, 1);
            _grid.setData(d);
            _grid.render();
          }
        }
      };

      if(_options.clipboardCommandHandler) {
        _options.clipboardCommandHandler(clipCommand);
      }
      else {
        clipCommand.execute();
      }
    }

    function handleKeyDown(e, args) {
      var ranges;
      if (!_grid.getEditorLock().isActive() || _grid.getOptions().autoEdit) {
        if (e.which == keyCodes.ESC) {
          if (_copiedRanges) {
            e.preventDefault();
            clearCopySelection();
            _self.onCopyCancelled.notify({ranges: _copiedRanges});
            _copiedRanges = null;
          }
        }

        if ((e.which === keyCodes.C || e.which === keyCodes.INSERT) && (e.ctrlKey || e.metaKey) && !e.shiftKey) {    // CTRL+C or CTRL+INS
          if (_onCopyInit) {
            _onCopyInit.call();
          }
          ranges = _grid.getSelectionModel().getSelectedRanges();
          if (ranges.length != 0) {
            _copiedRanges = ranges;
            markCopySelection(ranges);
            _self.onCopyCells.notify({ranges: ranges});

            var columns = _grid.getColumns();
            var clipText = "";

            for (var rg = 0; rg < ranges.length; rg++){
                var range = ranges[rg];
                var clipTextRows = [];
                for (var i=range.fromRow; i< range.toRow+1 ; i++){
                    var clipTextCells = [];
                    var dt = _grid.getDataItem(i);

                    if (clipTextRows == "" && _options.includeHeaderWhenCopying) {
                        var clipTextHeaders = [];
                        for (var j = range.fromCell; j < range.toCell + 1 ; j++) {
                            if (columns[j].name.length > 0)
                                clipTextHeaders.push(columns[j].name);
                        }
                        clipTextRows.push(clipTextHeaders.join("\t"));
                    }

                    for (var j=range.fromCell; j< range.toCell+1 ; j++){
                        clipTextCells.push(getDataItemValueForColumn(dt, columns[j]));
                    }
                    clipTextRows.push(clipTextCells.join("\t"));
                }
                clipText += clipTextRows.join("\r\n") + "\r\n";
            }

            if(window.clipboardData) {
                window.clipboardData.setData("Text", clipText);
                return true;
            }
            else {
                var $focus = $(_grid.getActiveCellNode());
                var ta = _createTextBox(clipText);

                ta.focus();

                setTimeout(function(){
                     _bodyElement.removeChild(ta);
                    // restore focus
                    if ($focus && $focus.length>0) {
                        $focus.attr('tabIndex', '-1');
                        $focus.focus();
                        $focus.removeAttr('tabIndex');
                    }
                }, 100);

                if (_onCopySuccess) {
                    var rowCount = 0;
                    // If it's cell selection, use the toRow/fromRow fields
                    if (ranges.length === 1) {
                        rowCount = (ranges[0].toRow + 1) - ranges[0].fromRow;
                    }
                    else {
                        rowCount = ranges.length;
                    }
                    _onCopySuccess.call(this, rowCount);
                }

                return false;
            }
          }
        }

        if ((e.which === keyCodes.V && (e.ctrlKey || e.metaKey) && !e.shiftKey || (e.which === keyCodes.INSERT && e.shiftKey && !e.ctrlKey))) {    // CTRL+V or Shift+INS
            var ta = _createTextBox('');

            setTimeout(function(){
                _decodeTabularData(_grid, ta);
            }, 100);

            return false;
        }
      }
    }

    function markCopySelection(ranges) {
      clearCopySelection();

      var columns = _grid.getColumns();
      var hash = {};
      for (var i = 0; i < ranges.length; i++) {
        for (var j = ranges[i].fromRow; j <= ranges[i].toRow; j++) {
          hash[j] = {};
          for (var k = ranges[i].fromCell; k <= ranges[i].toCell && k<columns.length; k++) {
            hash[j][columns[k].id] = _copiedCellStyle;
          }
        }
      }
      _grid.setCellCssStyles(_copiedCellStyleLayerKey, hash);
      clearTimeout(_clearCopyTI);
      _clearCopyTI = setTimeout(function(){
        _self.clearCopySelection();
      }, 2000);
    }

    function clearCopySelection() {
      _grid.removeCellCssStyles(_copiedCellStyleLayerKey);
    }

    $.extend(this, {
      "init": init,
      "destroy": destroy,
      "clearCopySelection": clearCopySelection,
      "handleKeyDown":handleKeyDown,

      "onCopyCells": new Slick.Event(),
      "onCopyCancelled": new Slick.Event(),
      "onPasteCells": new Slick.Event()
    });
  }
})(jQuery);
<commit_msg>always ignore formatters (we want serialized value, not formatted value), and added onCellChange notification<commit_after>(function ($) {
  // register namespace
  $.extend(true, window, {
    "Slick": {
      "CellExternalCopyManager": CellExternalCopyManager
    }
  });

  function CellExternalCopyManager(options) {
    /*
      This manager enables users to copy/paste data from/to an external Spreadsheet application
      such as MS-Excel® or OpenOffice-Spreadsheet.

      Since it is not possible to access directly the clipboard in javascript, the plugin uses
      a trick to do it's job. After detecting the keystroke, we dynamically create a textarea
      where the browser copies/pastes the serialized data.

      options:
        copiedCellStyle : sets the css className used for copied cells. default : "copied"
        copiedCellStyleLayerKey : sets the layer key for setting css values of copied cells. default : "copy-manager"
        dataItemColumnValueExtractor : option to specify a custom column value extractor function
        dataItemColumnValueSetter : option to specify a custom column value setter function
        clipboardCommandHandler : option to specify a custom handler for paste actions
        includeHeaderWhenCopying : set to true and the plugin will take the name property from each column (which is usually what appears in your header) and put that as the first row of the text that's copied to the clipboard
        bodyElement: option to specify a custom DOM element which to will be added the hidden textbox. It's useful if the grid is inside a modal dialog.
        onCopyInit: optional handler to run when copy action initializes
        onCopySuccess: optional handler to run when copy action is complete
    */
    var _grid;
    var _self = this;
    var _copiedRanges;
    var _options = options || {};
    var _copiedCellStyleLayerKey = _options.copiedCellStyleLayerKey || "copy-manager";
    var _copiedCellStyle = _options.copiedCellStyle || "copied";
    var _clearCopyTI = 0;
    var _bodyElement = _options.bodyElement || document.body;
    var _onCopyInit = _options.onCopyInit || null;
    var _onCopySuccess = _options.onCopySuccess || null;

    var keyCodes = {
      'C': 67,
      'V': 86,
      'ESC': 27,
      'INSERT': 45
    };

    function init(grid) {
      _grid = grid;
      _grid.onKeyDown.subscribe(handleKeyDown);

      // we need a cell selection model
      var cellSelectionModel = grid.getSelectionModel();
      if (!cellSelectionModel){
        throw new Error("Selection model is mandatory for this plugin. Please set a selection model on the grid before adding this plugin: grid.setSelectionModel(new Slick.CellSelectionModel())");
      }
      // we give focus on the grid when a selection is done on it.
      // without this, if the user selects a range of cell without giving focus on a particular cell, the grid doesn't get the focus and key stroke handles (ctrl+c) don't work
      cellSelectionModel.onSelectedRangesChanged.subscribe(function(e, args){
        _grid.focus();
      });
    }

    function destroy() {
      _grid.onKeyDown.unsubscribe(handleKeyDown);
    }

    function getDataItemValueForColumn(item, columnDef) {
      if (_options.dataItemColumnValueExtractor) {
        var dataItemColumnValueExtractorValue = _options.dataItemColumnValueExtractor(item, columnDef);

        if (dataItemColumnValueExtractorValue)
          return dataItemColumnValueExtractorValue;
      }

      var retVal = '';

      // if a custom getter is not defined, we call serializeValue of the editor to serialize
      if (columnDef.editor){
        var editorArgs = {
          'container':$("<p>"),  // a dummy container
          'column':columnDef,
          'position':{'top':0, 'left':0}  // a dummy position required by some editors
        };
        var editor = new columnDef.editor(editorArgs);
        editor.loadValue(item);
        retVal = editor.serializeValue();
        editor.destroy();
      }
      else {
        retVal = item[columnDef.field];
      }

      return retVal;
    }

    function setDataItemValueForColumn(item, columnDef, value) {
      if (_options.dataItemColumnValueSetter) {
        return _options.dataItemColumnValueSetter(item, columnDef, value);
      }

      // if a custom setter is not defined, we call applyValue of the editor to unserialize
      if (columnDef.editor){
        var editorArgs = {
          'container':$("body"),  // a dummy container
          'column':columnDef,
          'position':{'top':0, 'left':0}  // a dummy position required by some editors
        };
        var editor = new columnDef.editor(editorArgs);
        editor.loadValue(item);
        editor.applyValue(item, value);
        editor.destroy();
      }
    }

    function _createTextBox(innerText){
      var ta = document.createElement('textarea');
      ta.style.position = 'absolute';
      ta.style.left = '-1000px';
      ta.style.top = document.body.scrollTop + 'px';
      ta.value = innerText;
      _bodyElement.appendChild(ta);
      ta.select();

      return ta;
    }

    function _decodeTabularData(_grid, ta){
      var columns = _grid.getColumns();
      var clipText = ta.value;
      var clipRows = clipText.split(/[\n\f\r]/);
      var clippedRange = [];

      _bodyElement.removeChild(ta);

      for (var i=0; i<clipRows.length; i++) {
        if (clipRows[i]!="")
          clippedRange[i] = clipRows[i].split("\t");
      }

      var selectedCell = _grid.getActiveCell();
      var ranges = _grid.getSelectionModel().getSelectedRanges();
      var selectedRange = ranges && ranges.length ? ranges[0] : null;   // pick only one selection
      var activeRow = null;
      var activeCell = null;

      if (selectedRange){
        activeRow = selectedRange.fromRow;
        activeCell = selectedRange.fromCell;
      } else if (selectedCell){
        activeRow = selectedCell.row;
        activeCell = selectedCell.cell;
      } else {
        // we don't know where to paste
        return;
      }

      var oneCellToMultiple = false;
      var destH = clippedRange.length;
      var destW = clippedRange.length ? clippedRange[0].length : 0;
      if (clippedRange.length == 1 && clippedRange[0].length == 1 && selectedRange){
        oneCellToMultiple = true;
        destH = selectedRange.toRow - selectedRange.fromRow +1;
        destW = selectedRange.toCell - selectedRange.fromCell +1;
      }
      var availableRows = _grid.getData().length - activeRow;
      var addRows = 0;
      if(availableRows < destH)
      {
        var d = _grid.getData();
        for(addRows = 1; addRows <= destH - availableRows; addRows++)
          d.push({});
        _grid.setData(d);
        _grid.render();
      }
      var clipCommand = {

        isClipboardCommand: true,
        clippedRange: clippedRange,
        oldValues: [],
        cellExternalCopyManager: _self,
        _options: _options,
        setDataItemValueForColumn: setDataItemValueForColumn,
        markCopySelection: markCopySelection,
        oneCellToMultiple: oneCellToMultiple,
        activeRow: activeRow,
        activeCell: activeCell,
        destH: destH,
        destW: destW,
        desty: activeRow,
        destx: activeCell,
        maxDestY: _grid.getDataLength(),
        maxDestX: _grid.getColumns().length,
        h: 0,
        w: 0,

        execute: function() {
          this.h=0;
          for (var y = 0; y < destH; y++){
            this.oldValues[y] = [];
            this.w=0;
            this.h++;
            for (var x = 0; x < destW; x++){
              this.w++;
              var desty = activeRow + y;
              var destx = activeCell + x;

              if (desty < this.maxDestY && destx < this.maxDestX ) {
                var nd = _grid.getCellNode(desty, destx);
                var dt = _grid.getDataItem(desty);
                this.oldValues[y][x] = dt[columns[destx]['id']];
                if (oneCellToMultiple)
                  this.setDataItemValueForColumn(dt, columns[destx], clippedRange[0][0]);
                else
                  this.setDataItemValueForColumn(dt, columns[destx], clippedRange[y] ? clippedRange[y][x] : '');
                _grid.updateCell(desty, destx);
                _grid.onCellChange.notify({
                    row: desty,
                    cell: destx,
                    item: dt,
                    grid: _grid
                });

              }
            }
          }

          var bRange = {
            'fromCell': activeCell,
            'fromRow': activeRow,
            'toCell': activeCell+this.w-1,
            'toRow': activeRow+this.h-1
          }

          this.markCopySelection([bRange]);
          _grid.getSelectionModel().setSelectedRanges([bRange]);
          this.cellExternalCopyManager.onPasteCells.notify({ranges: [bRange]});
        },

        undo: function() {
          for (var y = 0; y < destH; y++){
            for (var x = 0; x < destW; x++){
              var desty = activeRow + y;
              var destx = activeCell + x;

              if (desty < this.maxDestY && destx < this.maxDestX ) {
                var nd = _grid.getCellNode(desty, destx);
                var dt = _grid.getDataItem(desty);
                if (oneCellToMultiple)
                  this.setDataItemValueForColumn(dt, columns[destx], this.oldValues[0][0]);
                else
                  this.setDataItemValueForColumn(dt, columns[destx], this.oldValues[y][x]);
                _grid.updateCell(desty, destx);
                _grid.onCellChange.notify({
                    row: desty,
                    cell: destx,
                    item: dt,
                    grid: _grid
                });
              }
            }
          }

          var bRange = {
            'fromCell': activeCell,
            'fromRow': activeRow,
            'toCell': activeCell+this.w-1,
            'toRow': activeRow+this.h-1
          }

          this.markCopySelection([bRange]);
          _grid.getSelectionModel().setSelectedRanges([bRange]);
          this.cellExternalCopyManager.onPasteCells.notify({ranges: [bRange]});

          if(addRows > 1){
            var d = _grid.getData();
            for(; addRows > 1; addRows--)
              d.splice(d.length - 1, 1);
            _grid.setData(d);
            _grid.render();
          }
        }
      };

      if(_options.clipboardCommandHandler) {
        _options.clipboardCommandHandler(clipCommand);
      }
      else {
        clipCommand.execute();
      }
    }

    function handleKeyDown(e, args) {
      var ranges;
      if (!_grid.getEditorLock().isActive() || _grid.getOptions().autoEdit) {
        if (e.which == keyCodes.ESC) {
          if (_copiedRanges) {
            e.preventDefault();
            clearCopySelection();
            _self.onCopyCancelled.notify({ranges: _copiedRanges});
            _copiedRanges = null;
          }
        }

        if ((e.which === keyCodes.C || e.which === keyCodes.INSERT) && (e.ctrlKey || e.metaKey) && !e.shiftKey) {    // CTRL+C or CTRL+INS
          if (_onCopyInit) {
            _onCopyInit.call();
          }
          ranges = _grid.getSelectionModel().getSelectedRanges();
          if (ranges.length != 0) {
            _copiedRanges = ranges;
            markCopySelection(ranges);
            _self.onCopyCells.notify({ranges: ranges});

            var columns = _grid.getColumns();
            var clipText = "";

            for (var rg = 0; rg < ranges.length; rg++){
                var range = ranges[rg];
                var clipTextRows = [];
                for (var i=range.fromRow; i< range.toRow+1 ; i++){
                    var clipTextCells = [];
                    var dt = _grid.getDataItem(i);

                    if (clipTextRows == "" && _options.includeHeaderWhenCopying) {
                        var clipTextHeaders = [];
                        for (var j = range.fromCell; j < range.toCell + 1 ; j++) {
                            if (columns[j].name.length > 0)
                                clipTextHeaders.push(columns[j].name);
                        }
                        clipTextRows.push(clipTextHeaders.join("\t"));
                    }

                    for (var j=range.fromCell; j< range.toCell+1 ; j++){
                        clipTextCells.push(getDataItemValueForColumn(dt, columns[j]));
                    }
                    clipTextRows.push(clipTextCells.join("\t"));
                }
                clipText += clipTextRows.join("\r\n") + "\r\n";
            }

            if(window.clipboardData) {
                window.clipboardData.setData("Text", clipText);
                return true;
            }
            else {
                var $focus = $(_grid.getActiveCellNode());
                var ta = _createTextBox(clipText);

                ta.focus();

                setTimeout(function(){
                     _bodyElement.removeChild(ta);
                    // restore focus
                    if ($focus && $focus.length>0) {
                        $focus.attr('tabIndex', '-1');
                        $focus.focus();
                        $focus.removeAttr('tabIndex');
                    }
                }, 100);

                if (_onCopySuccess) {
                    var rowCount = 0;
                    // If it's cell selection, use the toRow/fromRow fields
                    if (ranges.length === 1) {
                        rowCount = (ranges[0].toRow + 1) - ranges[0].fromRow;
                    }
                    else {
                        rowCount = ranges.length;
                    }
                    _onCopySuccess.call(this, rowCount);
                }

                return false;
            }
          }
        }

        if ((e.which === keyCodes.V && (e.ctrlKey || e.metaKey) && !e.shiftKey || (e.which === keyCodes.INSERT && e.shiftKey && !e.ctrlKey))) {    // CTRL+V or Shift+INS
            var ta = _createTextBox('');

            setTimeout(function(){
                _decodeTabularData(_grid, ta);
            }, 100);

            return false;
        }
      }
    }

    function markCopySelection(ranges) {
      clearCopySelection();

      var columns = _grid.getColumns();
      var hash = {};
      for (var i = 0; i < ranges.length; i++) {
        for (var j = ranges[i].fromRow; j <= ranges[i].toRow; j++) {
          hash[j] = {};
          for (var k = ranges[i].fromCell; k <= ranges[i].toCell && k<columns.length; k++) {
            hash[j][columns[k].id] = _copiedCellStyle;
          }
        }
      }
      _grid.setCellCssStyles(_copiedCellStyleLayerKey, hash);
      clearTimeout(_clearCopyTI);
      _clearCopyTI = setTimeout(function(){
        _self.clearCopySelection();
      }, 2000);
    }

    function clearCopySelection() {
      _grid.removeCellCssStyles(_copiedCellStyleLayerKey);
    }

    $.extend(this, {
      "init": init,
      "destroy": destroy,
      "clearCopySelection": clearCopySelection,
      "handleKeyDown":handleKeyDown,

      "onCopyCells": new Slick.Event(),
      "onCopyCancelled": new Slick.Event(),
      "onPasteCells": new Slick.Event()
    });
  }
})(jQuery);
<|endoftext|>


<commit_before>(function (module) {
    mifosX.controllers = _.extend(module, {
        CreateClientController: function (scope, resourceFactory, location, http, dateFilter, API_VERSION, $upload, $rootScope, routeParams) {
            scope.offices = [];
            scope.staffs = [];
            scope.savingproducts = [];
            scope.first = {};
            scope.first.date = new Date();
            scope.first.submitondate = new Date ();
            scope.formData = {};
            scope.clientNonPersonDetails = {};
            scope.restrictDate = new Date();
            scope.showSavingOptions = false;
            scope.opensavingsproduct = false;
            scope.forceOffice = null;
            scope.showNonPersonOptions = false;
            scope.clientPersonId = 1;

            var requestParams = {staffInSelectedOfficeOnly:true};
            if (routeParams.groupId) {
                requestParams.groupId = routeParams.groupId;
            }
            if (routeParams.officeId) {
                requestParams.officeId = routeParams.officeId;
            }
            resourceFactory.clientTemplateResource.get(requestParams, function (data) {
                scope.offices = data.officeOptions;
                scope.staffs = data.staffOptions;
                scope.formData.officeId = scope.offices[0].id;
                scope.savingproducts = data.savingProductOptions;
                scope.genderOptions = data.genderOptions;
                scope.clienttypeOptions = data.clientTypeOptions;
                scope.clientClassificationOptions = data.clientClassificationOptions;
                scope.clientNonPersonConstitutionOptions = data.clientNonPersonConstitutionOptions;
                scope.clientNonPersonMainBusinessLineOptions = data.clientNonPersonMainBusinessLineOptions;
                scope.clientLegalFormOptions = data.clientLegalFormOptions;
                if (data.savingProductOptions.length > 0) {
                    scope.showSavingOptions = true;
                }
                if(routeParams.officeId) {
                    scope.formData.officeId = routeParams.officeId;
                    for(var i in data.officeOptions) {
                        if(data.officeOptions[i].id == routeParams.officeId) {
                            scope.forceOffice = data.officeOptions[i];
                            break;
                        }
                    }
                }
                if(routeParams.groupId) {
                    if(typeof data.staffId !== "undefined") {
                        scope.formData.staffId = data.staffId;
                    }
                }
            });

            scope.displayPersonOrNonPersonOptions = function (legalFormId) {
                if(legalFormId == scope.clientPersonId || legalFormId == null) {
                    scope.showNonPersonOptions = false;
                }else {
                    scope.showNonPersonOptions = true;
                }
            };

            scope.changeOffice = function (officeId) {
                resourceFactory.clientTemplateResource.get({staffInSelectedOfficeOnly:true, officeId: officeId
                }, function (data) {
                    scope.staffs = data.staffOptions;
                    scope.savingproducts = data.savingProductOptions;
                });
            };

            scope.setChoice = function () {
                if (this.formData.active) {
                    scope.choice = 1;
                }
                else if (!this.formData.active) {
                    scope.choice = 0;
                }
            };
            if(routeParams.groupId) {
            	scope.cancel = '#/viewgroup/' + routeParams.groupId
            	scope.groupid = routeParams.groupId;
            }else {
            	scope.cancel = "#/clients"
            }

            scope.submit = function () {
                var reqDate = dateFilter(scope.first.date, scope.df);

                this.formData.locale = scope.optlang.code;
                this.formData.active = this.formData.active || false;
                this.formData.dateFormat = scope.df;
                this.formData.activationDate = reqDate;

                if (routeParams.groupId) {
                    this.formData.groupId = routeParams.groupId;
                }

                if (routeParams.officeId) {
                    this.formData.officeId = routeParams.officeId;
                }

                if (scope.first.submitondate) {
                    reqDate = dateFilter(scope.first.submitondate, scope.df);
                    this.formData.submittedOnDate = reqDate;
                }

                if (scope.first.dateOfBirth) {
                    this.formData.dateOfBirth = dateFilter(scope.first.dateOfBirth, scope.df);
                }

                if(scope.first.incorpValidityTillDate) {
                    this.formData.clientNonPersonDetails.locale = scope.optlang.code;
                    this.formData.clientNonPersonDetails.dateFormat = scope.df;
                    this.formData.clientNonPersonDetails.incorpValidityTillDate = dateFilter(scope.first.incorpValidityTillDate, scope.df);
                }

                if (!scope.opensavingsproduct) {
                    this.formData.savingsProductId = null;
                }

                resourceFactory.clientResource.save(this.formData, function (data) {
                    location.path('/viewclient/' + data.clientId);
                });
            };
        }
    });
    mifosX.ng.application.controller('CreateClientController', ['$scope', 'ResourceFactory', '$location', '$http', 'dateFilter', 'API_VERSION', '$upload', '$rootScope', '$routeParams', mifosX.controllers.CreateClientController]).run(function ($log) {
        $log.info("CreateClientController initialized");
    });
}(mifosX.controllers || {}));
<commit_msg>Fix MIFOSX-2639<commit_after>(function (module) {
    mifosX.controllers = _.extend(module, {
        CreateClientController: function (scope, resourceFactory, location, http, dateFilter, API_VERSION, $upload, $rootScope, routeParams) {
            scope.offices = [];
            scope.staffs = [];
            scope.savingproducts = [];
            scope.first = {};
            scope.first.date = new Date();
            scope.first.submitondate = new Date ();
            scope.formData = {};
            scope.clientNonPersonDetails = {};
            scope.restrictDate = new Date();
            scope.showSavingOptions = false;
            scope.opensavingsproduct = false;
            scope.forceOffice = null;
            scope.showNonPersonOptions = false;
            scope.clientPersonId = 1;

            var requestParams = {staffInSelectedOfficeOnly:true};
            if (routeParams.groupId) {
                requestParams.groupId = routeParams.groupId;
            }
            if (routeParams.officeId) {
                requestParams.officeId = routeParams.officeId;
            }
            resourceFactory.clientTemplateResource.get(requestParams, function (data) {
                scope.offices = data.officeOptions;
                scope.staffs = data.staffOptions;
                scope.formData.officeId = scope.offices[0].id;
                scope.savingproducts = data.savingProductOptions;
                scope.genderOptions = data.genderOptions;
                scope.clienttypeOptions = data.clientTypeOptions;
                scope.clientClassificationOptions = data.clientClassificationOptions;
                scope.clientNonPersonConstitutionOptions = data.clientNonPersonConstitutionOptions;
                scope.clientNonPersonMainBusinessLineOptions = data.clientNonPersonMainBusinessLineOptions;
                scope.clientLegalFormOptions = data.clientLegalFormOptions;
                if (data.savingProductOptions.length > 0) {
                    scope.showSavingOptions = true;
                }
                if(routeParams.officeId) {
                    scope.formData.officeId = routeParams.officeId;
                    for(var i in data.officeOptions) {
                        if(data.officeOptions[i].id == routeParams.officeId) {
                            scope.forceOffice = data.officeOptions[i];
                            break;
                        }
                    }
                }
                if(routeParams.groupId) {
                    if(typeof data.staffId !== "undefined") {
                        scope.formData.staffId = data.staffId;
                    }
                }
            });

            scope.displayPersonOrNonPersonOptions = function (legalFormId) {
                if(legalFormId == scope.clientPersonId || legalFormId == null) {
                    scope.showNonPersonOptions = false;
                }else {
                    scope.showNonPersonOptions = true;
                }
            };

            scope.changeOffice = function (officeId) {
                resourceFactory.clientTemplateResource.get({staffInSelectedOfficeOnly:true, officeId: officeId
                }, function (data) {
                    scope.staffs = data.staffOptions;
                    scope.savingproducts = data.savingProductOptions;
                });
            };

            scope.setChoice = function () {
                if (this.formData.active) {
                    scope.choice = 1;
                }
                else if (!this.formData.active) {
                    scope.choice = 0;
                }
            };
            if(routeParams.groupId) {
            	scope.cancel = '#/viewgroup/' + routeParams.groupId
            	scope.groupid = routeParams.groupId;
            }else {
            	scope.cancel = "#/clients"
            }

            scope.submit = function () {
                var reqDate = dateFilter(scope.first.date, scope.df);

                this.formData.locale = scope.optlang.code;
                this.formData.active = this.formData.active || false;
                this.formData.dateFormat = scope.df;
                this.formData.activationDate = reqDate;

                if (routeParams.groupId) {
                    this.formData.groupId = routeParams.groupId;
                }

                if (routeParams.officeId) {
                    this.formData.officeId = routeParams.officeId;
                }

                if (scope.first.submitondate) {
                    reqDate = dateFilter(scope.first.submitondate, scope.df);
                    this.formData.submittedOnDate = reqDate;
                }

                if (scope.first.dateOfBirth) {
                    this.formData.dateOfBirth = dateFilter(scope.first.dateOfBirth, scope.df);
                }

                if (this.formData.legalFormId == scope.clientPersonId || this.formData.legalFormId == null) {
                    delete this.formData.fullname;
                } else {
                    delete this.formData.firstname;
                    delete this.formData.middlename;
                    delete this.formData.lastname;
                }

                if(scope.first.incorpValidityTillDate) {
                    this.formData.clientNonPersonDetails.locale = scope.optlang.code;
                    this.formData.clientNonPersonDetails.dateFormat = scope.df;
                    this.formData.clientNonPersonDetails.incorpValidityTillDate = dateFilter(scope.first.incorpValidityTillDate, scope.df);
                }

                if (!scope.opensavingsproduct) {
                    this.formData.savingsProductId = null;
                }

                resourceFactory.clientResource.save(this.formData, function (data) {
                    location.path('/viewclient/' + data.clientId);
                });
            };
        }
    });
    mifosX.ng.application.controller('CreateClientController', ['$scope', 'ResourceFactory', '$location', '$http', 'dateFilter', 'API_VERSION', '$upload', '$rootScope', '$routeParams', mifosX.controllers.CreateClientController]).run(function ($log) {
        $log.info("CreateClientController initialized");
    });
}(mifosX.controllers || {}));
<|endoftext|>