<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: SalAquaPicker.cxx,v $
 *
 *  $Revision: 1.2 $
 *
 *  last change: $Author: ihi $ $Date: 2007-07-11 10:59:44 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library 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
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

//------------------------------------------------------------------------
// includes
//------------------------------------------------------------------------

#ifndef _COM_SUN_STAR_LANG_DISPOSEDEXCEPTION_HPP_
#include <com/sun/star/lang/DisposedException.hpp>
#endif
#ifndef _COM_SUN_STAR_LANG_XMULTISERVICEFACTORY_HPP_
#include <com/sun/star/lang/XMultiServiceFactory.hpp>
#endif
#ifndef _CPPUHELPER_INTERFACECONTAINER_H_
#include <cppuhelper/interfacecontainer.h>
#endif
#ifndef _OSL_DIAGNOSE_H_
#include <osl/diagnose.h>
#endif
#ifndef  _COM_SUN_STAR_UNO_ANY_HXX_
#include <com/sun/star/uno/Any.hxx>
#endif
#ifndef _FPSERVICEINFO_HXX_
#include <FPServiceInfo.hxx>
#endif
#ifndef _VOS_MUTEX_HXX_
#include <vos/mutex.hxx>
#endif
#ifndef _SV_SVAPP_HXX
#include <vcl/svapp.hxx>
#endif
#ifndef _SALAQUAPICKER_HXX_
#include "SalAquaPicker.hxx"
#endif
#ifndef _URLOBJ_HXX
#include <tools/urlobj.hxx>
#endif
#ifndef _OSL_FILE_HXX_
#include <osl/file.hxx>
#endif
#ifndef _CFSTRINGUTILITIES_HXX_
#include "CFStringUtilities.hxx"
#endif

#include <stdio.h>

#pragma mark DEFINES
#define CLASS_NAME "SalAquaPicker"

//------------------------------------------------------------------------
// namespace directives
//------------------------------------------------------------------------

using namespace ::rtl;
using namespace ::com::sun::star;
using namespace ::com::sun::star::lang;
using namespace ::com::sun::star::uno;

void navigationEventHandler(NavEventCallbackMessage callBackSelector, NavCBRecPtr callBackParms, void *callBackUserData)
{
    NavReplyRecord reply;
    NavUserAction userAction = 0;
    SalAquaPicker *pSalAquaPicker = (SalAquaPicker *) callBackUserData;

    switch (callBackSelector) {

    // We are ignoring several callbackSelectors here...
    case kNavCBEvent:
        pSalAquaPicker->implHandleNavDialogEvent(callBackParms);
        break;
    case kNavCBCustomize:
        OSL_TRACE("NavigationServices callBackSelector = kNavCBCustomize");
        pSalAquaPicker->implHandleNavDialogCustomize(callBackParms);
        break;
    case kNavCBStart:
        OSL_TRACE("NavigationServices callBackSelector = kNavCBStart");

//leave the following in in case we should consider X11 support in the future
#ifndef QUARTZ
        /*
         * We need to bring the dialog to the front. However, to make
         * the dialog usable, soffice.bin must be the application bundle's executable.
         */
        if (callBackParms) {
            WindowRef dialogWindow = callBackParms->window;
            if (dialogWindow) {
                ProcessSerialNumber psn;
                OSStatus error = GetCurrentProcess(&psn);
                if (error == noErr) {
                    (void)SetFrontProcess(&psn);
                }
                BringToFront(dialogWindow);
            }
        }
#endif
        pSalAquaPicker->implHandleNavDialogStart(callBackParms);
        break;
    case kNavCBAdjustRect:
        OSL_TRACE("NavigationServices callBackSelector = kNavCBAdjustRect");
        pSalAquaPicker->getControlHelper()->handleAdjustRect(callBackParms);
        break;
    case kNavCBNewLocation:
        OSL_TRACE("NavigationServices callBackSelector = kNavCBNewLocation");
        break;
    case kNavCBAccept:
        OSL_TRACE("NavigationServices callBackSelector = kNavCBAccept");
        break;
    case kNavCBCancel:
        OSL_TRACE("NavigationServices callBackSelector = kNavCBCancel");
        break;
    case kNavCBAdjustPreview:
        OSL_TRACE("NavigationServices callBackSelector = kNavCBAdjustPreview");
        break;
    case kNavCBPopupMenuSelect:
        NavMenuItemSpec* menuItem = (NavMenuItemSpec*)callBackParms->eventData.eventDataParms.param;
        pSalAquaPicker->implHandlePopupMenuSelect(menuItem);
        break;
    case kNavCBUserAction:
        OSL_TRACE("NavigationServices callBackSelector = kNavCBUserAction");

         if (NavDialogGetReply (callBackParms->context, &reply) == noErr )
         {
             userAction = NavDialogGetUserAction (callBackParms->context);

             switch (userAction) {
             case kNavUserActionSaveAs:
                 OSL_TRACE("NavigationServices userAction = knavUserActionSaveAs");
                 break;
             case kNavUserActionOpen:
                 OSL_TRACE("NavigationServices userAction = knavUserActionOpen");
                 break;
             case kNavUserActionCancel:
                 OSL_TRACE("NavigationServices userAction = knavUserActionCancel");
                 break;
             case kNavUserActionNewFolder:
                 OSL_TRACE("NavigationServices userAction = knavUserActionNewFolder");
                 break;
             default:
                 OSL_TRACE("NavigationServices userAction is UNKNOWN %d", userAction);
                 break;
             }

             NavDisposeReply (&reply);
         }
        break;
    case kNavCBTerminate:
        OSL_TRACE("NavigationServices callBackSelector = kNavCBTerminate");
//leave the following in in case we should consider X11 support in the future
#ifndef QUARTZ
        {
            /*
             * This passage searches the process list to find the X11 application.
             * When it is found, it is being made the front process. Otherwise
             * OpenOffice.org app would stay on top and the X11 window might be hidden.
             */
            OSStatus status;
            ProcessSerialNumber psn = {0, kNoProcess};//to initialize the process list
            while((status = GetNextProcess(&psn)) == noErr && (psn.lowLongOfPSN != kNoProcess)) {
                CFStringRef processName;
                CopyProcessName(&psn, &processName);
                CFStringRef sX11 = CFSTR("X11");
                if (CFStringCompare(processName, sX11, NULL) == kCFCompareEqualTo) {
                    (void)SetFrontProcess(&psn);
                    CFRelease(processName);
                    CFRelease(sX11);
                    break;
                }
                CFRelease(processName);
                CFRelease(sX11);
            }
        }
#endif
        break;
    case kNavCBSelectEntry:
        OSL_TRACE("NavigationServices callBackSelector = kNavCBSelectEntry");
        pSalAquaPicker->implHandleNavDialogSelectEntry(callBackParms);
        break;
    case kNavCBOpenSelection:
        OSL_TRACE("NavigationServices callBackSelector = kNavCBOpenSelection");
        //no need to do anythong here, sfx2 will call us
        break;
    default:
        OSL_TRACE("NavigationServices callBackSelector = %d", (int)callBackSelector);
        break;
    }

    pSalAquaPicker->setLatestEvent(callBackSelector);
}

MacOSBoolean filterEventHandler (AEDesc *theItem, void *info,
                      void *callBackUD,
                      NavFilterModes filterMode )
{
    SalAquaPicker *pPicker = (SalAquaPicker *) callBackUD;
    return pPicker->implFilterHandler(theItem, info, callBackUD, filterMode);
}

MacOSBoolean previewHandler (NavCBRecPtr callBackParms,
                       NavCallBackUserData callBackUD )
{
    SalAquaPicker *pSalAquaPicker = (SalAquaPicker *) callBackUD;

    if (NULL != pSalAquaPicker) {
        return pSalAquaPicker->implPreviewHandler(callBackParms);
    }

    return FALSE;
}

OSStatus SalAquaPicker::run()
{
    DBG_PRINT_ENTRY(CLASS_NAME, __func__);

    if (m_pDialog == NULL) {
        //this is the case e.g. for the folder picker at this stage
        implInitialize();
    }

    OSStatus status = NavDialogRun (m_pDialog);
    if (status != noErr) {
        OSL_TRACE("NavigationServices returned an error while running the dialog");
    }

    DBG_PRINT_EXIT(CLASS_NAME, __func__, status);

    return status;
}

OSStatus SalAquaPicker::runandwaitforresult()
{
    DBG_PRINT_ENTRY(CLASS_NAME, __func__);

    OSStatus status = this->run();
    if (status != noErr) {
        DBG_PRINT_EXIT(CLASS_NAME, __func__, status);
        return status;
    }
    status = NavDialogGetReply (m_pDialog, &m_pReplyRecord);
    if (status != noErr) {
        OSL_TRACE("NavigationServices returned an error while getting the dialog reply");
    }

    DBG_PRINT_EXIT(CLASS_NAME, __func__, status);
    return status;
}

// constructor
SalAquaPicker::SalAquaPicker()
: m_pDialog(NULL)
, m_pControlHelper(new ControlHelper())
, m_aLatestEvent(kNavCBEvent)
{
    DBG_PRINT_ENTRY(CLASS_NAME, __func__);

    // set the standard set of dialog options
    OSStatus status = NavGetDefaultDialogCreationOptions(&m_pDialogOptions);
    if (status != noErr) {
        OSL_TRACE("NavigationServices returned an error while creating dialog options");
    }

    DBG_PRINT_EXIT(CLASS_NAME, __func__);
}

SalAquaPicker::~SalAquaPicker()
{
    DBG_PRINT_ENTRY(CLASS_NAME, __func__);

    if (NULL != m_pControlHelper)
        delete m_pControlHelper;
    if (NULL != m_pEventHandler)
        DisposeNavEventUPP(m_pEventHandler);
    if (NULL != m_pDialog)
        NavDialogDispose (m_pDialog);
    if (NULL != m_pFilterHandler)
        DisposeNavObjectFilterUPP(m_pFilterHandler);
    if (NULL != m_pPreviewHandler)
        DisposeNavPreviewUPP(m_pPreviewHandler);

    DBG_PRINT_EXIT(CLASS_NAME, __func__);
}

void SAL_CALL SalAquaPicker::implsetDisplayDirectory( const rtl::OUString& aDirectory )
    throw( lang::IllegalArgumentException, uno::RuntimeException )
{
    DBG_PRINT_ENTRY(CLASS_NAME, __func__, "directory", aDirectory);

    m_sDisplayDirectory = aDirectory;

    DBG_PRINT_EXIT(CLASS_NAME, __func__);
}

rtl::OUString SAL_CALL SalAquaPicker::implgetDisplayDirectory() throw( uno::RuntimeException )
{
    DBG_PRINT_ENTRY(CLASS_NAME, __func__);
    DBG_PRINT_EXIT(CLASS_NAME, __func__, m_sDisplayDirectory);

    return m_sDisplayDirectory;
}

void SAL_CALL SalAquaPicker::implsetTitle( const rtl::OUString& aTitle ) throw( uno::RuntimeException )
{
    DBG_PRINT_ENTRY(CLASS_NAME, __func__, "title", aTitle);

    ::vos::OGuard aGuard( Application::GetSolarMutex() );

    m_pDialogOptions.windowTitle = CFStringCreateWithOUString ( aTitle );

    DBG_PRINT_EXIT(CLASS_NAME, __func__);
}

void SAL_CALL SalAquaPicker::implInitialize()
{
    DBG_PRINT_ENTRY(CLASS_NAME, __func__);

    m_pEventHandler = NewNavEventUPP( navigationEventHandler );

    //does not work currently - unfortunately
    //WindowRef parent = FrontWindow();
    WindowRef parent = NULL;
    if (NULL == parent) {
        m_pDialogOptions.modality = kWindowModalityAppModal;
    } else if (m_nDialogType == NAVIGATIONSERVICES_SAVE) {
        m_pDialogOptions.modality = kWindowModalityWindowModal;
        m_pDialogOptions.parentWindow = parent;
    }

    OSStatus status = noErr;
    // Create the corresponding dialog
    // pass the pointer to SalAquaPicker as an userData
    switch (m_nDialogType)
    {
        case NAVIGATIONSERVICES_OPEN:
            OSL_TRACE("NAVIGATIONSERVICES_OPEN");
            m_pFilterHandler = NewNavObjectFilterUPP(filterEventHandler);
            m_pPreviewHandler = NewNavPreviewUPP(previewHandler);
            status = NavCreateGetFileDialog (&m_pDialogOptions, NULL, m_pEventHandler, m_pPreviewHandler, m_pFilterHandler, (void *) this, &m_pDialog);
            break;

        case NAVIGATIONSERVICES_SAVE:
            OSL_TRACE("NAVIGATIONSERVICES_SAVE");
            status = NavCreatePutFileDialog (&m_pDialogOptions, kUnknownType, kUnknownType, m_pEventHandler, (void *) this, &m_pDialog);
            break;

        case NAVIGATIONSERVICES_DIRECTORY:
            OSL_TRACE("NAVIGATIONSERVICES_DIRECTORY");
            status = NavCreateChooseFolderDialog (&m_pDialogOptions, m_pEventHandler, NULL, (void *) this, &m_pDialog);
            break;

        default:
            OSL_TRACE("m_nDialogType is UNKNOWN: %d", m_nDialogType);
            break;
    }

    if (status != noErr) {
        OSL_TRACE("An error occurred while creating the dialog!");
    }

    DBG_PRINT_EXIT(CLASS_NAME, __func__);
}

/////
void SAL_CALL SalAquaPicker::implHandleNavDialogCustomize(NavCBRecPtr callBackParms) { }

void SAL_CALL SalAquaPicker::implHandleNavDialogStart(NavCBRecPtr callBackParms) { }

void SAL_CALL SalAquaPicker::implHandleNavDialogEvent(NavCBRecPtr callBackParms) { }

sal_Bool SAL_CALL SalAquaPicker::implFilterHandler(AEDesc *theItem, void *info,
                                                   void *callBackUD,
                                                   NavFilterModes filterMode)
{
    return sal_True;
}

sal_Bool SAL_CALL SalAquaPicker::implPreviewHandler(NavCBRecPtr callBackParms)
{
    return sal_False;
}

void SAL_CALL SalAquaPicker::implHandlePopupMenuSelect(NavMenuItemSpec* menuItem) { }

void SAL_CALL SalAquaPicker::implHandleNavDialogSelectEntry(NavCBRecPtr callBackParms) { }
<commit_msg>INTEGRATION: CWS aquafilepicker02_DEV300 (1.2.40); FILE MERGED 2008/02/15 14:22:07 pl 1.2.40.9: saved some merge problems 2008/02/14 17:28:45 fheckl 1.2.40.8: Further changes concerning Autoextension 2008/02/14 08:30:02 fheckl 1.2.40.7: small implementation changes 2008/02/12 07:55:17 fheckl 1.2.40.6: a little cleanup 2008/01/14 08:23:24 fheckl 1.2.40.5: Code cleanup and some implementation details 2008/01/02 18:51:11 fheckl 1.2.40.4: removing NSInteger 2008/01/02 18:25:59 fheckl 1.2.40.3: issue #80399 more Cocoa 2007/11/18 20:55:02 fheckl 1.2.40.2: making save panel work temporarily 2007/11/18 19:36:37 fheckl 1.2.40.1: initial support for Cocoa version<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: SalAquaPicker.cxx,v $
 *
 *  $Revision: 1.3 $
 *
 *  last change: $Author: kz $ $Date: 2008-03-05 16:38:36 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library 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
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

//------------------------------------------------------------------------
// includes
//------------------------------------------------------------------------

#ifndef _COM_SUN_STAR_LANG_DISPOSEDEXCEPTION_HPP_
#include <com/sun/star/lang/DisposedException.hpp>
#endif
#ifndef _COM_SUN_STAR_LANG_XMULTISERVICEFACTORY_HPP_
#include <com/sun/star/lang/XMultiServiceFactory.hpp>
#endif
#ifndef _CPPUHELPER_INTERFACECONTAINER_H_
#include <cppuhelper/interfacecontainer.h>
#endif
#ifndef _OSL_DIAGNOSE_H_
#include <osl/diagnose.h>
#endif
#ifndef  _COM_SUN_STAR_UNO_ANY_HXX_
#include <com/sun/star/uno/Any.hxx>
#endif
#ifndef _FPSERVICEINFO_HXX_
#include <FPServiceInfo.hxx>
#endif
#ifndef _VOS_MUTEX_HXX_
#include <vos/mutex.hxx>
#endif
#ifndef _SV_SVAPP_HXX
#include <vcl/svapp.hxx>
#endif
#ifndef _SALAQUAPICKER_HXX_
#include "SalAquaPicker.hxx"
#endif
#ifndef _URLOBJ_HXX
#include <tools/urlobj.hxx>
#endif
#ifndef _OSL_FILE_HXX_
#include <osl/file.hxx>
#endif
#ifndef _CFSTRINGUTILITIES_HXX_
#include "CFStringUtilities.hxx"
#endif
#include "NSString_OOoAdditions.hxx"

#include "SalAquaFilePicker.hxx"

#include <stdio.h>

#pragma mark DEFINES
#define CLASS_NAME "SalAquaPicker"

//------------------------------------------------------------------------
// namespace directives
//------------------------------------------------------------------------

using namespace ::rtl;
using namespace ::com::sun::star;
using namespace ::com::sun::star::lang;
using namespace ::com::sun::star::uno;

// constructor
SalAquaPicker::SalAquaPicker()
: m_pDialog(NULL)
, m_pControlHelper(new ControlHelper())
{
    DBG_PRINT_ENTRY(CLASS_NAME, __func__);
    DBG_PRINT_EXIT(CLASS_NAME, __func__);
}

SalAquaPicker::~SalAquaPicker()
{
    DBG_PRINT_ENTRY(CLASS_NAME, __func__);

    ::vos::OGuard aGuard( Application::GetSolarMutex() );

    NSAutoreleasePool *pool = [NSAutoreleasePool new];

    if (NULL != m_pControlHelper)
        delete m_pControlHelper;

    if (NULL != m_pDialog)
        [m_pDialog release];

    [pool release];

    DBG_PRINT_EXIT(CLASS_NAME, __func__);
}

void SAL_CALL SalAquaPicker::implInitialize()
{
    DBG_PRINT_ENTRY(CLASS_NAME, __func__);

    ::vos::OGuard aGuard( Application::GetSolarMutex() );

    if (m_pDialog != nil) {
        return;
    }

    switch (m_nDialogType)
    {
        case NAVIGATIONSERVICES_OPEN:
            OSL_TRACE("NAVIGATIONSERVICES_OPEN");
            m_pDialog = [NSOpenPanel openPanel];
            [(NSOpenPanel*)m_pDialog setCanChooseDirectories:NO];
            [(NSOpenPanel*)m_pDialog setCanChooseFiles:YES];
            break;

        case NAVIGATIONSERVICES_SAVE:
            OSL_TRACE("NAVIGATIONSERVICES_SAVE");
            m_pDialog = [NSSavePanel savePanel];
            [(NSSavePanel*)m_pDialog setCanSelectHiddenExtension:YES];
            [(NSSavePanel*)m_pDialog setExtensionHidden:NO];
            break;

        case NAVIGATIONSERVICES_DIRECTORY:
            OSL_TRACE("NAVIGATIONSERVICES_DIRECTORY");
            m_pDialog = [NSOpenPanel openPanel];
            [(NSOpenPanel*)m_pDialog setCanChooseDirectories:YES];
            [(NSOpenPanel*)m_pDialog setCanChooseFiles:NO];
            break;

        default:
            OSL_TRACE("m_nDialogType is UNKNOWN: %d", m_nDialogType);
            break;
    }

    if (m_pDialog == nil) {
        OSL_TRACE("An error occurred while creating the dialog!");
    }
    else {
        [(NSOpenPanel*)m_pDialog setCanCreateDirectories:YES];
        //Retain the dialog instance or it will go away immediately
        [m_pDialog retain];
    }

    DBG_PRINT_EXIT(CLASS_NAME, __func__);
}

int SalAquaPicker::run()
{
    DBG_PRINT_ENTRY(CLASS_NAME, __func__);

    ::vos::OGuard aGuard( Application::GetSolarMutex() );

    NSAutoreleasePool *pool = [NSAutoreleasePool new];

    if (m_pDialog == NULL) {
        //this is the case e.g. for the folder picker at this stage
        implInitialize();
    }

    NSView *userPane = m_pControlHelper->getUserPane();
    if (userPane != NULL) {
        [m_pDialog setAccessoryView:userPane];
    }

    int retVal = 0;

    NSString *startDirectory;
    if (m_sDisplayDirectory.getLength() > 0) {
        NSString *temp = [NSString stringWithOUString:m_sDisplayDirectory];
        NSURL *url = [NSURL URLWithString:temp];
        startDirectory = [url path];

        OSL_TRACE("start dir: %s", [startDirectory UTF8String]);
        // NSLog(@"%@", startDirectory);
    }
    else {
        startDirectory = NSHomeDirectory();
    }

    switch(m_nDialogType) {
        case NAVIGATIONSERVICES_DIRECTORY:
        case NAVIGATIONSERVICES_OPEN:
            retVal = [(NSOpenPanel*)m_pDialog runModalForDirectory:startDirectory file:nil types:nil];
            break;
        case NAVIGATIONSERVICES_SAVE:
            retVal = [m_pDialog runModalForDirectory:startDirectory file:[NSString stringWithOUString:((SalAquaFilePicker*)this)->getSaveFileName()]/*[m_pDialog saveFilename]*/];
            break;
        // [m_pDialog beginSheetForDirectory:startDirectory file:[m_pDialog saveFilename] modalForWindow:[NSApp keyWindow] modalDelegate:((SalAquaFilePicker*)this)->getDelegate() didEndSelector:@selector(savePanelDidEnd:returnCode:contextInfo:) contextInfo:nil];
        default:
            break;
    }

    DBG_PRINT_EXIT(CLASS_NAME, __func__, retVal);

    [pool release];

    return retVal;
}

int SalAquaPicker::runandwaitforresult()
{
    DBG_PRINT_ENTRY(CLASS_NAME, __func__);

    ::vos::OGuard aGuard( Application::GetSolarMutex() );

    int status = this->run();

    DBG_PRINT_EXIT(CLASS_NAME, __func__, status);
    return status;
}

void SAL_CALL SalAquaPicker::implsetDisplayDirectory( const rtl::OUString& aDirectory )
    throw( lang::IllegalArgumentException, uno::RuntimeException )
{
    DBG_PRINT_ENTRY(CLASS_NAME, __func__, "directory", aDirectory);

    ::vos::OGuard aGuard( Application::GetSolarMutex() );

    if (aDirectory != m_sDisplayDirectory) {
        m_sDisplayDirectory = aDirectory;

        if (m_pDialog != nil) {
            //NSLog(@"would change now to:%@", [NSString stringWithOUString:aDirectory]);
            // [m_pDialog setDirectory:[NSString stringWithOUString:aDirectory]];
        }
    }

    DBG_PRINT_EXIT(CLASS_NAME, __func__);
}

rtl::OUString SAL_CALL SalAquaPicker::implgetDisplayDirectory() throw( uno::RuntimeException )
{
    DBG_PRINT_ENTRY(CLASS_NAME, __func__);
    DBG_PRINT_EXIT(CLASS_NAME, __func__, m_sDisplayDirectory);

    return m_sDisplayDirectory;
}

void SAL_CALL SalAquaPicker::implsetTitle( const rtl::OUString& aTitle ) throw( uno::RuntimeException )
{
    DBG_PRINT_ENTRY(CLASS_NAME, __func__, "title", aTitle);

    ::vos::OGuard aGuard( Application::GetSolarMutex() );

    if (m_pDialog != nil) {
        [m_pDialog setTitle:[NSString stringWithOUString:aTitle]];
    }

    DBG_PRINT_EXIT(CLASS_NAME, __func__);
}

<|endoftext|>


<commit_before>/**
  *  @copyright Copyright (c) 2014, J-PET collaboration
  *  @file JPetManager.cp
  *  @author Wojciech Krzemien, wojciech.krzemien@if.uj.edu.pl
  */

#include "./JPetManager.h"

#include <cassert>
#include <ctime>
#include <string>

#include "../../JPetLoggerInclude.h"
#include "../JPetScopeReader/JPetScopeReader.h"

//ClassImp(JPetManager);

JPetManager& JPetManager::GetManager()
{
  static JPetManager instance;
  return instance;
}

JPetManager::JPetManager(): TNamed("JPetMainManager", "JPetMainManager"), fIsProgressBarEnabled(false)
{

}

// adds the given analysis module to a list of registered task
// @todo check if the module is not already registered
void JPetManager::AddTask(JPetAnalysisModule* mod)
{
  assert(mod);
  fTasks.push_back(mod);
}

void JPetManager::Run()
{
	INFO( "========== Starting processing tasks: " + GetTimeString() + " ==========" );
	ProcessFromCmdLineArgs();
	currentTask = fTasks.begin();
	long long  kNevent = (*currentTask)->getEventNb();
	long long kFirstEvent = 0;
	long long kLastEvent = 0;
	vector<string> fileNames = getInputFileNames();

	for(int i = 0; i < fileNames.size(); i++)
	{
		for (currentTask = fTasks.begin(); currentTask != fTasks.end(); currentTask++) {
			prepareCurrentTaskForFile(fileNames[i]);
			setEventBounds(kFirstEvent, kLastEvent, kNevent);
			processEventsInRange(kFirstEvent, kLastEvent);
			(*currentTask)->terminate();
		}
	}

	INFO( "======== Finished processing all tasks: " + GetTimeString() + " ========\n" );
}

///> Initialize and process things based on the command line arguments.
void JPetManager::ProcessFromCmdLineArgs()
{
	if (fCmdParser.isRunNumberSet()) { /// we should connect to the database
		fParamManager.getParametersFromDatabase(fCmdParser.getRunNumber()); /// @todo some error handling
	}

	if (fCmdParser.isProgressBarSet()) {
		fIsProgressBarEnabled = true;
	}
	if (fCmdParser.IsFileTypeSet()) {
		if (fCmdParser.getFileType() == "scope") {
			JPetScopeReader* module = new JPetScopeReader("JPetScopeReader", "Process Oscilloscope ASCII data into JPetRecoSignal structures.");
			module->setFileName(getInputFileNames()[0].c_str());
			fTasks.push_front(module);
		} else if (fCmdParser.getFileType() == "hld") {
			fUnpacker.setParams(fCmdParser.getFileNames()[0].c_str());
			UnpackFile();
		}
	}
}

void JPetManager::ParseCmdLine(int argc, char** argv)
{
  fCmdParser.parse(argc, (const char**)argv);

}

int JPetManager::getRunNumber() const
{
  if (fCmdParser.isRunNumberSet()) {
    return fCmdParser.getRunNumber();
  }
  return -1;
}

JPetManager::~JPetManager()
{
  std::list<JPetAnalysisModule*>::iterator taskIter;
  for (taskIter = fTasks.begin(); taskIter != fTasks.end(); taskIter++) {
    delete (*taskIter);
    *taskIter = 0;
  }
}

/**
 * @brief Get Input File name stripped off the extension and the suffixes like .tslot.* or .phys.*
 *
 * Example: if the file given on command line was ../file.phys.hit.root, this method will return ../file
 */
std::vector<std::string> JPetManager::getInputFileNames() const
{
	std::vector<std::string> fileNames = fCmdParser.getFileNames();
	std::cout << "### " << fileNames.size() << std::endl;
	std::vector<std::string> parsedNames;
	for(int i = 0; i < fileNames.size(); i++){
		std::string name = fileNames[i].c_str();
		// strip suffixes of type .tslot.* and .phys.*
		int pos = name.find(".tslot");
		if ( pos == std::string::npos ) {
			pos = name.find(".phys");
		}
		if ( pos == std::string::npos ) {
			pos = name.find(".hld");
		}
		if ( pos == std::string::npos ) {
			pos = name.find(".root");
		}
		if ( pos != std::string::npos ) {
			name.erase( pos );
		}
		parsedNames.push_back(name);
	}
	return parsedNames;
}

/**
 * @brief returns the time TString in the format dd.mm.yyyy HH:MM
 */
TString JPetManager::GetTimeString() const
{
  time_t _tm = time(NULL );
  struct tm* curtime = localtime ( &_tm );
  char buf[100];
  strftime( buf, 100, "%d.%m.%Y %R", curtime);

  return TString( buf );
}

float JPetManager::setProgressBar(int currentEventNumber, int numberOfEvents)
{
  return ( ((float)currentEventNumber) / numberOfEvents ) * 100;
}

bool JPetManager::userBoundsAreCorrect(long long numberOfEvents)
{
	return fCmdParser.getLowerEventBound() != -1 &&
			fCmdParser.getHigherEventBound() != -1 &&
			fCmdParser.getHigherEventBound() < numberOfEvents;
}

void JPetManager::manageProgressBar(long long done, long long end)
{
	if (fIsProgressBarEnabled) {
		printf("\r[%6.4f% %]", setProgressBar(done, end));
	}
}

void JPetManager::processEventsInRange(long long begin, long long end)
{
	for (long long i = begin; i <= end; i++)
	{
		manageProgressBar(i, end);
		(*currentTask)->exec();
	}
}

void JPetManager::prepareCurrentTaskForFile(const string& file)
{
	(*currentTask)->createInputObjects( file.c_str() ); /// readers
	(*currentTask)->createOutputObjects( file.c_str() ); /// writers + histograms
}

void JPetManager::setEventBounds(long long& begin, long long& end, long long& eventCount)
{
	if (userBoundsAreCorrect(eventCount) && currentTask == fTasks.begin())
	{
		begin = fCmdParser.getLowerEventBound();
		end = fCmdParser.getHigherEventBound();
		eventCount = end - begin + 1;
	}
	else
	{
		eventCount = (*currentTask)->getEventNb();
		begin = 0;
		end = eventCount - 1;
	}
}
<commit_msg>removed cout<commit_after>/**
  *  @copyright Copyright (c) 2014, J-PET collaboration
  *  @file JPetManager.cp
  *  @author Wojciech Krzemien, wojciech.krzemien@if.uj.edu.pl
  */

#include "./JPetManager.h"

#include <cassert>
#include <ctime>
#include <string>

#include "../../JPetLoggerInclude.h"
#include "../JPetScopeReader/JPetScopeReader.h"

//ClassImp(JPetManager);

JPetManager& JPetManager::GetManager()
{
  static JPetManager instance;
  return instance;
}

JPetManager::JPetManager(): TNamed("JPetMainManager", "JPetMainManager"), fIsProgressBarEnabled(false)
{

}

// adds the given analysis module to a list of registered task
// @todo check if the module is not already registered
void JPetManager::AddTask(JPetAnalysisModule* mod)
{
  assert(mod);
  fTasks.push_back(mod);
}

void JPetManager::Run()
{
	INFO( "========== Starting processing tasks: " + GetTimeString() + " ==========" );
	ProcessFromCmdLineArgs();
	currentTask = fTasks.begin();
	long long  kNevent = (*currentTask)->getEventNb();
	long long kFirstEvent = 0;
	long long kLastEvent = 0;
	vector<string> fileNames = getInputFileNames();

	for(int i = 0; i < fileNames.size(); i++)
	{
		for (currentTask = fTasks.begin(); currentTask != fTasks.end(); currentTask++) {
			prepareCurrentTaskForFile(fileNames[i]);
			setEventBounds(kFirstEvent, kLastEvent, kNevent);
			processEventsInRange(kFirstEvent, kLastEvent);
			(*currentTask)->terminate();
		}
	}

	INFO( "======== Finished processing all tasks: " + GetTimeString() + " ========\n" );
}

///> Initialize and process things based on the command line arguments.
void JPetManager::ProcessFromCmdLineArgs()
{
	if (fCmdParser.isRunNumberSet()) { /// we should connect to the database
		fParamManager.getParametersFromDatabase(fCmdParser.getRunNumber()); /// @todo some error handling
	}

	if (fCmdParser.isProgressBarSet()) {
		fIsProgressBarEnabled = true;
	}
	if (fCmdParser.IsFileTypeSet()) {
		if (fCmdParser.getFileType() == "scope") {
			JPetScopeReader* module = new JPetScopeReader("JPetScopeReader", "Process Oscilloscope ASCII data into JPetRecoSignal structures.");
			module->setFileName(getInputFileNames()[0].c_str());
			fTasks.push_front(module);
		} else if (fCmdParser.getFileType() == "hld") {
			fUnpacker.setParams(fCmdParser.getFileNames()[0].c_str());
			UnpackFile();
		}
	}
}

void JPetManager::ParseCmdLine(int argc, char** argv)
{
  fCmdParser.parse(argc, (const char**)argv);

}

int JPetManager::getRunNumber() const
{
  if (fCmdParser.isRunNumberSet()) {
    return fCmdParser.getRunNumber();
  }
  return -1;
}

JPetManager::~JPetManager()
{
  std::list<JPetAnalysisModule*>::iterator taskIter;
  for (taskIter = fTasks.begin(); taskIter != fTasks.end(); taskIter++) {
    delete (*taskIter);
    *taskIter = 0;
  }
}

/**
 * @brief Get Input File name stripped off the extension and the suffixes like .tslot.* or .phys.*
 *
 * Example: if the file given on command line was ../file.phys.hit.root, this method will return ../file
 */
std::vector<std::string> JPetManager::getInputFileNames() const
{
	std::vector<std::string> fileNames = fCmdParser.getFileNames();
	std::vector<std::string> parsedNames;
	for(int i = 0; i < fileNames.size(); i++){
		std::string name = fileNames[i].c_str();
		// strip suffixes of type .tslot.* and .phys.*
		int pos = name.find(".tslot");
		if ( pos == std::string::npos ) {
			pos = name.find(".phys");
		}
		if ( pos == std::string::npos ) {
			pos = name.find(".hld");
		}
		if ( pos == std::string::npos ) {
			pos = name.find(".root");
		}
		if ( pos != std::string::npos ) {
			name.erase( pos );
		}
		parsedNames.push_back(name);
	}
	return parsedNames;
}

/**
 * @brief returns the time TString in the format dd.mm.yyyy HH:MM
 */
TString JPetManager::GetTimeString() const
{
  time_t _tm = time(NULL );
  struct tm* curtime = localtime ( &_tm );
  char buf[100];
  strftime( buf, 100, "%d.%m.%Y %R", curtime);

  return TString( buf );
}

float JPetManager::setProgressBar(int currentEventNumber, int numberOfEvents)
{
  return ( ((float)currentEventNumber) / numberOfEvents ) * 100;
}

bool JPetManager::userBoundsAreCorrect(long long numberOfEvents)
{
	return fCmdParser.getLowerEventBound() != -1 &&
			fCmdParser.getHigherEventBound() != -1 &&
			fCmdParser.getHigherEventBound() < numberOfEvents;
}

void JPetManager::manageProgressBar(long long done, long long end)
{
	if (fIsProgressBarEnabled) {
		printf("\r[%6.4f% %]", setProgressBar(done, end));
	}
}

void JPetManager::processEventsInRange(long long begin, long long end)
{
	for (long long i = begin; i <= end; i++)
	{
		manageProgressBar(i, end);
		(*currentTask)->exec();
	}
}

void JPetManager::prepareCurrentTaskForFile(const string& file)
{
	(*currentTask)->createInputObjects( file.c_str() ); /// readers
	(*currentTask)->createOutputObjects( file.c_str() ); /// writers + histograms
}

void JPetManager::setEventBounds(long long& begin, long long& end, long long& eventCount)
{
	if (userBoundsAreCorrect(eventCount) && currentTask == fTasks.begin())
	{
		begin = fCmdParser.getLowerEventBound();
		end = fCmdParser.getHigherEventBound();
		eventCount = end - begin + 1;
	}
	else
	{
		eventCount = (*currentTask)->getEventNb();
		begin = 0;
		end = eventCount - 1;
	}
}
<|endoftext|>


<commit_before>/***********************************************************************
 cmdline.cpp - Command line parsing stuff used by the example and
    utility programs.  Not intended for end-user use!

 Copyright (c) 2007-2009 by Educational Technology Resources,
 Inc.  getopt() and its associated globals are the public domain
 implementation made available at the 1985 UNIFORUM conference in
 Dallas, Texas; the code is untouched except for style tweaks.
 Others may also hold copyrights on code in this file.  See the
 CREDITS.txt file in the top directory of the distribution for details.

 This file is part of MySQL++.

 MySQL++ is free software; you can redistribute it and/or modify it
 under the terms of the GNU Lesser General Public License as published
 by the Free Software Foundation; either version 2.1 of the License, or
 (at your option) any later version.

 MySQL++ 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 Lesser General Public
 License for more details.

 You should have received a copy of the GNU Lesser General Public
 License along with MySQL++; if not, write to the Free Software
 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
 USA
***********************************************************************/

#define MYSQLPP_NOT_HEADER
#include "cmdline.h"

#include <iostream>

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

//// getopt ////////////////////////////////////////////////////////////
// Bring in system getopt(), or define our own.

#if defined(HAVE_POSIX_GETOPT)
#	include <unistd.h>
#elif defined(HAVE_LIBIBERTY_GETOPT)
#	include <libiberty.h>
#else
	// Need to define our own getopt() on this system
	extern "C" {
		// Using C linkage to avoid potential conflicts with system
		// getopt(), if autoconf test fails to find it.
		static const char* optarg;
		static int optind = 1;
		static int getopt(int argc, char* const argv[], const char* opts)
		{
			static int optopt;
			static int sp = 1;
			register int c;
			register const char *cp;

			if (sp == 1) {
				/* If all args are processed, finish */
				if (optind >= argc) {
					return EOF;
				}
				if (argv[optind][0] != '-' || argv[optind][1] == '\0') {
					return EOF;
				}
			}
			else if (!strcmp(argv[optind], "--")) {
				/* No more goptions to be processed after this one */
				optind++;
				return EOF;
			}

			optopt = c = argv[optind][sp];

			/* Check for invalid goption */
			if (c == ':' || (cp = strchr(opts, c)) == 0) {
				fprintf(stderr, "%s: illegal option -- %c\n", argv[0], c);
				if (argv[optind][++sp] == '\0') {
					optind++;
					sp = 1;
				}

				return '?';
			}

			/* Does this goption require an argument? */
			if (*++cp == ':') {
				/* If so, get argument; if none provided output error */
				if (argv[optind][sp + 1] != '\0') {
					optarg = &argv[optind++][sp + 1];
				}
				else if (++optind >= argc) {
					fprintf(stderr,
							"%s: option requires an argument -- %c\n", argv[0], c);
					sp = 1;
					return '?';
				}
				else {
					optarg = argv[optind++];
				}
				sp = 1;
			}
			else {
				if (argv[optind][++sp] == '\0') {
					sp = 1;
					optind++;
				}
				optarg = 0;
			}

			return c;
		}
	} // end extern "C"
#endif // didn't find either POSIX or libiberty getopt()

////////////////////////////////////////////////////////////////////////
// Generic MySQL++-specific command line parsing mechanism

namespace mysqlpp {

//// CommandLineBase::finish_parse /////////////////////////////////////
// Called by subclass when it's finished parsing the command line.  It
// does nothing if we're not still in a "successful" state.

void
CommandLineBase::finish_parse()
{
	if (successful_) {
		const int nextras = argc_ - option_index();
		if (nextras > 0) {
			extra_args_.resize(nextras);
			for (int i = 0; i < nextras; ++i) {
				extra_args_[i] = argv_[option_index() + i];
			}
		}
	}
}

//// CommandLineBase::option_argument //////////////////////////////////
// Accessor for optarg, so caller doesn't have to know about this
// getopt() style interface.  Particualy helpful on non-POSIX systems.

const char*
CommandLineBase::option_argument() const
{
	return optarg;
}

//// CommandLineBase::option_index /////////////////////////////////////
// Accessor for optind, so caller doesn't have to know about this
// getopt() style interface.  Particuarly helpful on non-POSIX systems.

int
CommandLineBase::option_index() const
{
	return optind;
}

//// CommandLineBase::parse_next ///////////////////////////////////////
// Wrapper around getopt(), using the stuff passed to our ctor to
// construct its argument list.

int
CommandLineBase::parse_next() const
{
	return getopt(argc_, argv_, opts_);
}

//// CommandLineBase::parse_error //////////////////////////////////////
// Called by subclasses when they encounter an error in parsing.  We
// wrap up several details of handling that error: display the
// message on stderr, call the subclass's print_usage() method, and
// marks the object as no longer successful.

void
CommandLineBase::parse_error(const char* message)
{
	if (message) {
		std::cerr << message << '\n';
	}
	print_usage();
	successful_ = false;
}

////////////////////////////////////////////////////////////////////////
// Command line parser for MySQL++ examples.

namespace examples {

const char* db_name = "mysql_cpp_data";

//// examples::CommandLine ctor ////////////////////////////////////////

CommandLine::CommandLine(int argc, char* const argv[],
		const char* user, const char* pass, const char* usage_extra) :
CommandLineBase(argc, argv, "hm:p:s:u:D?"),
dtest_mode_(false),
run_mode_(0),
server_(0),
user_(user && *user ? user : 0),
pass_(pass && *pass ? pass : ""),
usage_extra_(usage_extra)
{
	int ch;
	while (successful() && ((ch = parse_next()) != EOF)) {
		switch (ch) {
			case 'm': run_mode_ = atoi(option_argument()); break;
			case 'p': pass_ = option_argument();           break;
			case 's': server_ = option_argument();         break;
			case 'u': user_ = option_argument();           break;
			case 'D': dtest_mode_ = true;                  break;
			default:
				parse_error();
				return;
		}
	}

	finish_parse();
}

//// examples::CommandLine::print_usage ////////////////////////////////
// Show a generic usage message suitable for ../examples/*.cpp  The
// parameters specialize the message to a minor degree.

void
CommandLine::print_usage(const char* extra) const
{
	std::cout << "usage: " << program_name() <<
			" [-s server_addr] [-u user] [-p password] " <<
			extra << std::endl;
	std::cout << std::endl;
	std::cout << "    If no options are given, connects to database "
			"server on localhost" << std::endl;
	std::cout << "    using your user name and no password." << std::endl;
	if (strlen(extra) > 0) {
		std::cout << std::endl;
		std::cout << "    The extra parameter " << extra <<
				" is required, regardless of which" << std::endl;
		std::cout << "    other arguments you pass." << std::endl;
	}
	std::cout << std::endl;
}

} // end namespace mysqlpp::examples

////////////////////////////////////////////////////////////////////////
// Command line parser for MySQL++'s ssqlsxlat tool.

namespace ssqlsxlat {

//// ssqlsxlat::CommandLine ctor ////////////////////////////////////////

CommandLine::CommandLine(int argc, char* const argv[]) :
CommandLineBase(argc, argv, "hi:o:p:s:t:u:1:?"),
input_(0),
output_(0),
pass_(""),
server_(0),
user_(0),
input_source_(ss_unknown),
output_sink_(ss_unknown)
{
	// Parse the command line
	int ch;
	while (successful() && ((ch = parse_next()) != EOF)) {
		switch (ch) {
			case 'i':
			case 't':
			case '1':
				if (input_) {
					std::cerr << "Warning: overriding previous input "
							"source!  Only last -i, -t or -1 is "
							"effective.\n";
				}
				input_ = option_argument();
				input_source_ =
						(ch == '1' ? ss_ssqls1 :
						 ch == 'i' ? ss_ssqls2 :
						             ss_table);
				break;

			case 'o':
				output_ = option_argument();
				output_sink_ = ss_ssqls2;
				break;

			case 'p':
				pass_ = option_argument();
				break;

			case 's':
				server_ = option_argument();
				break;

			case 'u':
				user_ = option_argument();
				break;

			default:
				parse_error();
		}
	}
	finish_parse();

	// Figure out whether command line makes sense, and if not, tell
	// user about it.
	if (successful()) {
		if (input_source_ == ss_unknown) {
			parse_error("No input source given!  Need -i, -t or -1.");
		}
		else if ((input_source_ != ss_ssqls2) && !output_) {
			parse_error("Need -o if you give -t or -1!");
		}
	}
}

//// ssqlsxlat::CommandLine::print_usage ////////////////////////////////
// Show a generic usage message suitable for ../ssqlsxlat/*.cpp  The
// parameters specialize the message to a minor degree.

void
CommandLine::print_usage() const
{
	std::cerr << "usage: " << program_name() <<
        	" [ -i input.ssqls ] [ -1 input-ssqlsv1.cpp ]\n"
			"        [ -u user ] [ -p password ] [ -s server ] [ -t table ]\n"
			"        [ -o parsedump.ssqls ]\n";
	std::cerr << std::endl;
	std::cerr <<
			"        -i: parse SSQLSv2 DSL, generating C++ output at minimum\n"
			"        -o: write out .ssqls file containing info found by\n"
			"            processing -i, -t or -1\n"
			"  -u,p,s,t: log into server with given creds, get schema details\n"
			"            for a table, and generate output as if parsed from\n"
			"            SSQLSv2 DSL; requires -o\n"
			"        -1: find SSQLSv1 declarations in C++ code, and try to\n"
			"            interpret as equivalent SSQLSv2; requires -o\n"
			"      -?,h: write out .ssqls file containing info found by\n"
			"            processing -i, -t or -1\n";
	std::cerr << std::endl;
}

} // end namespace mysqlpp::ssqlsxlat
} // end namespace mysqlpp
<commit_msg>Fixed a crash in CommandLine mechanism when usage message is called up for programs that have no "extra" parameter and corresponding usage appendage.  Initial patch by "Crazy Pete" <crazypete62@yahoo.com>, fixed and extended by me.<commit_after>/***********************************************************************
 cmdline.cpp - Command line parsing stuff used by the example and
    utility programs.  Not intended for end-user use!

 Copyright (c) 2007-2009 by Educational Technology Resources,
 Inc.  getopt() and its associated globals are the public domain
 implementation made available at the 1985 UNIFORUM conference in
 Dallas, Texas; the code is untouched except for style tweaks.
 Others may also hold copyrights on code in this file.  See the
 CREDITS.txt file in the top directory of the distribution for details.

 This file is part of MySQL++.

 MySQL++ is free software; you can redistribute it and/or modify it
 under the terms of the GNU Lesser General Public License as published
 by the Free Software Foundation; either version 2.1 of the License, or
 (at your option) any later version.

 MySQL++ 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 Lesser General Public
 License for more details.

 You should have received a copy of the GNU Lesser General Public
 License along with MySQL++; if not, write to the Free Software
 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
 USA
***********************************************************************/

#define MYSQLPP_NOT_HEADER
#include "cmdline.h"

#include <iostream>

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

//// getopt ////////////////////////////////////////////////////////////
// Bring in system getopt(), or define our own.

#if defined(HAVE_POSIX_GETOPT)
#	include <unistd.h>
#elif defined(HAVE_LIBIBERTY_GETOPT)
#	include <libiberty.h>
#else
	// Need to define our own getopt() on this system
	extern "C" {
		// Using C linkage to avoid potential conflicts with system
		// getopt(), if autoconf test fails to find it.
		static const char* optarg;
		static int optind = 1;
		static int getopt(int argc, char* const argv[], const char* opts)
		{
			static int optopt;
			static int sp = 1;
			register int c;
			register const char *cp;

			if (sp == 1) {
				/* If all args are processed, finish */
				if (optind >= argc) {
					return EOF;
				}
				if (argv[optind][0] != '-' || argv[optind][1] == '\0') {
					return EOF;
				}
			}
			else if (!strcmp(argv[optind], "--")) {
				/* No more goptions to be processed after this one */
				optind++;
				return EOF;
			}

			optopt = c = argv[optind][sp];

			/* Check for invalid goption */
			if (c == ':' || (cp = strchr(opts, c)) == 0) {
				fprintf(stderr, "%s: illegal option -- %c\n", argv[0], c);
				if (argv[optind][++sp] == '\0') {
					optind++;
					sp = 1;
				}

				return '?';
			}

			/* Does this goption require an argument? */
			if (*++cp == ':') {
				/* If so, get argument; if none provided output error */
				if (argv[optind][sp + 1] != '\0') {
					optarg = &argv[optind++][sp + 1];
				}
				else if (++optind >= argc) {
					fprintf(stderr,
							"%s: option requires an argument -- %c\n", argv[0], c);
					sp = 1;
					return '?';
				}
				else {
					optarg = argv[optind++];
				}
				sp = 1;
			}
			else {
				if (argv[optind][++sp] == '\0') {
					sp = 1;
					optind++;
				}
				optarg = 0;
			}

			return c;
		}
	} // end extern "C"
#endif // didn't find either POSIX or libiberty getopt()

////////////////////////////////////////////////////////////////////////
// Generic MySQL++-specific command line parsing mechanism

namespace mysqlpp {

//// CommandLineBase::finish_parse /////////////////////////////////////
// Called by subclass when it's finished parsing the command line.  It
// does nothing if we're not still in a "successful" state.

void
CommandLineBase::finish_parse()
{
	if (successful_) {
		const int nextras = argc_ - option_index();
		if (nextras > 0) {
			extra_args_.resize(nextras);
			for (int i = 0; i < nextras; ++i) {
				extra_args_[i] = argv_[option_index() + i];
			}
		}
	}
}

//// CommandLineBase::option_argument //////////////////////////////////
// Accessor for optarg, so caller doesn't have to know about this
// getopt() style interface.  Particualy helpful on non-POSIX systems.

const char*
CommandLineBase::option_argument() const
{
	return optarg;
}

//// CommandLineBase::option_index /////////////////////////////////////
// Accessor for optind, so caller doesn't have to know about this
// getopt() style interface.  Particuarly helpful on non-POSIX systems.

int
CommandLineBase::option_index() const
{
	return optind;
}

//// CommandLineBase::parse_next ///////////////////////////////////////
// Wrapper around getopt(), using the stuff passed to our ctor to
// construct its argument list.

int
CommandLineBase::parse_next() const
{
	return getopt(argc_, argv_, opts_);
}

//// CommandLineBase::parse_error //////////////////////////////////////
// Called by subclasses when they encounter an error in parsing.  We
// wrap up several details of handling that error: display the
// message on stderr, call the subclass's print_usage() method, and
// marks the object as no longer successful.

void
CommandLineBase::parse_error(const char* message)
{
	if (message) {
		std::cerr << message << '\n';
	}
	print_usage();
	successful_ = false;
}

////////////////////////////////////////////////////////////////////////
// Command line parser for MySQL++ examples.

namespace examples {

const char* db_name = "mysql_cpp_data";

//// examples::CommandLine ctor ////////////////////////////////////////

CommandLine::CommandLine(int argc, char* const argv[],
		const char* user, const char* pass, const char* usage_extra) :
CommandLineBase(argc, argv, "hm:p:s:u:D?"),
dtest_mode_(false),
run_mode_(0),
server_(0),
user_(user && *user ? user : 0),
pass_(pass && *pass ? pass : ""),
usage_extra_(usage_extra)
{
	int ch;
	while (successful() && ((ch = parse_next()) != EOF)) {
		switch (ch) {
			case 'm': run_mode_ = atoi(option_argument()); break;
			case 'p': pass_ = option_argument();           break;
			case 's': server_ = option_argument();         break;
			case 'u': user_ = option_argument();           break;
			case 'D': dtest_mode_ = true;                  break;
			default:
				parse_error();
				return;
		}
	}

	finish_parse();
}

//// examples::CommandLine::print_usage ////////////////////////////////
// Show a generic usage message suitable for ../examples/*.cpp  The
// parameters specialize the message to a minor degree.

void
CommandLine::print_usage(const char* extra) const
{
	std::cout << "usage: " << program_name() <<
			" [-s server_addr] [-u user] [-p password] " <<
			(extra ? extra : "") << std::endl;
	std::cout << std::endl;
	std::cout << "    If no options are given, connects to database "
			"server on localhost" << std::endl;
	std::cout << "    using your user name and no password." << std::endl;
	if (extra && (strlen(extra) > 0)) {
		std::cout << std::endl;
		std::cout << "    The extra parameter " << extra <<
				" is required, regardless of which" << std::endl;
		std::cout << "    other arguments you pass." << std::endl;
	}
	std::cout << std::endl;
}

} // end namespace mysqlpp::examples

////////////////////////////////////////////////////////////////////////
// Command line parser for MySQL++'s ssqlsxlat tool.

namespace ssqlsxlat {

//// ssqlsxlat::CommandLine ctor ////////////////////////////////////////

CommandLine::CommandLine(int argc, char* const argv[]) :
CommandLineBase(argc, argv, "hi:o:p:s:t:u:1:?"),
input_(0),
output_(0),
pass_(""),
server_(0),
user_(0),
input_source_(ss_unknown),
output_sink_(ss_unknown)
{
	// Parse the command line
	int ch;
	while (successful() && ((ch = parse_next()) != EOF)) {
		switch (ch) {
			case 'i':
			case 't':
			case '1':
				if (input_) {
					std::cerr << "Warning: overriding previous input "
							"source!  Only last -i, -t or -1 is "
							"effective.\n";
				}
				input_ = option_argument();
				input_source_ =
						(ch == '1' ? ss_ssqls1 :
						 ch == 'i' ? ss_ssqls2 :
						             ss_table);
				break;

			case 'o':
				output_ = option_argument();
				output_sink_ = ss_ssqls2;
				break;

			case 'p':
				pass_ = option_argument();
				break;

			case 's':
				server_ = option_argument();
				break;

			case 'u':
				user_ = option_argument();
				break;

			default:
				parse_error();
		}
	}
	finish_parse();

	// Figure out whether command line makes sense, and if not, tell
	// user about it.
	if (successful()) {
		if (input_source_ == ss_unknown) {
			parse_error("No input source given!  Need -i, -t or -1.");
		}
		else if ((input_source_ != ss_ssqls2) && !output_) {
			parse_error("Need -o if you give -t or -1!");
		}
	}
}

//// ssqlsxlat::CommandLine::print_usage ////////////////////////////////
// Show a generic usage message suitable for ../ssqlsxlat/*.cpp  The
// parameters specialize the message to a minor degree.

void
CommandLine::print_usage() const
{
	std::cerr << "usage: " << program_name() <<
        	" [ -i input.ssqls ] [ -1 input-ssqlsv1.cpp ]\n"
			"        [ -u user ] [ -p password ] [ -s server ] [ -t table ]\n"
			"        [ -o parsedump.ssqls ]\n";
	std::cerr << std::endl;
	std::cerr <<
			"        -i: parse SSQLSv2 DSL, generating C++ output at minimum\n"
			"        -o: write out .ssqls file containing info found by\n"
			"            processing -i, -t or -1\n"
			"  -u,p,s,t: log into server with given creds, get schema details\n"
			"            for a table, and generate output as if parsed from\n"
			"            SSQLSv2 DSL; requires -o\n"
			"        -1: find SSQLSv1 declarations in C++ code, and try to\n"
			"            interpret as equivalent SSQLSv2; requires -o\n"
			"      -?,h: write out .ssqls file containing info found by\n"
			"            processing -i, -t or -1\n";
	std::cerr << std::endl;
}

} // end namespace mysqlpp::ssqlsxlat
} // end namespace mysqlpp
<|endoftext|>


<commit_before>/****************************************************************/
/*               DO NOT MODIFY THIS HEADER                      */
/* MOOSE - Multiphysics Object Oriented Simulation Environment  */
/*                                                              */
/*           (c) 2010 Battelle Energy Alliance, LLC             */
/*                   ALL RIGHTS RESERVED                        */
/*                                                              */
/*          Prepared by Battelle Energy Alliance, LLC           */
/*            Under Contract No. DE-AC07-05ID14517              */
/*            With the U. S. Department of Energy               */
/*                                                              */
/*            See COPYRIGHT for full restrictions               */
/****************************************************************/

#include "ScalarCoupleable.h"
#include "Problem.h"
#include "SubProblem.h"
#include "FEProblem.h"

ScalarCoupleable::ScalarCoupleable(const InputParameters & parameters) :
    _sc_fe_problem(*parameters.getCheckedPointerParam<FEProblem *>("_fe_problem")),
    _sc_is_implicit(parameters.have_parameter<bool>("implicit") ? parameters.get<bool>("implicit") : true),
    _coupleable_params(parameters)
{
  SubProblem & problem = *parameters.get<SubProblem *>("_subproblem");

  THREAD_ID tid = parameters.have_parameter<THREAD_ID>("_tid") ? parameters.get<THREAD_ID>("_tid") : 0;

  // Coupling
  for (std::set<std::string>::const_iterator iter = parameters.coupledVarsBegin();
       iter != parameters.coupledVarsEnd();
       ++iter)
  {
    std::string name = *iter;
    if (parameters.getVecMooseType(*iter) != std::vector<std::string>())
    {
      std::vector<std::string> vars = parameters.getVecMooseType(*iter);
      for (unsigned int i = 0; i < vars.size(); i++)
      {
        std::string coupled_var_name = vars[i];
        if (problem.hasScalarVariable(coupled_var_name))
        {
          MooseVariableScalar * scalar_var = &problem.getScalarVariable(tid, coupled_var_name);
          _coupled_scalar_vars[name].push_back(scalar_var);
          _coupled_moose_scalar_vars.push_back(scalar_var);
        }
        else if (problem.hasVariable(coupled_var_name))
          ; // ignore normal variables
        else
          mooseError("Coupled variable '" + coupled_var_name + "' was not found\n");
      }
    }
  }
}

ScalarCoupleable::~ScalarCoupleable()
{
  for (std::map<std::string, VariableValue *>::iterator it = _default_value.begin(); it != _default_value.end(); ++it)
  {
    it->second->release();
    delete it->second;
  }
}

const std::vector<MooseVariableScalar *> &
ScalarCoupleable::getCoupledMooseScalarVars()
{
  return _coupled_moose_scalar_vars;
}

bool
ScalarCoupleable::isCoupledScalar(const std::string & var_name, unsigned int i)
{
  std::map<std::string, std::vector<MooseVariableScalar *> >::iterator it = _coupled_scalar_vars.find(var_name);
  if (it != _coupled_scalar_vars.end())
    return (i < it->second.size());
  else
    return false;
}

unsigned int
ScalarCoupleable::coupledScalar(const std::string & var_name, unsigned int comp)
{
  return getScalarVar(var_name, comp)->number();
}

VariableValue *
ScalarCoupleable::getDefaultValue(const std::string & var_name)
{
  std::map<std::string, VariableValue *>::iterator default_value_it = _default_value.find(var_name);
  if (default_value_it == _default_value.end())
  {
    VariableValue * value = new VariableValue(_sc_fe_problem.getMaxScalarOrder(), _coupleable_params.defaultCoupledValue(var_name));
    default_value_it = _default_value.insert(std::make_pair(var_name, value)).first;
  }

  return default_value_it->second;
}

VariableValue &
ScalarCoupleable::coupledScalarValue(const std::string & var_name, unsigned int comp)
{
  if (!isCoupledScalar(var_name, comp))
    return *getDefaultValue(var_name);

  MooseVariableScalar * var = getScalarVar(var_name, comp);
  return (_sc_is_implicit) ? var->sln() : var->slnOld();
}

VariableValue &
ScalarCoupleable::coupledScalarValueOld(const std::string & var_name, unsigned int comp)
{
  if (!isCoupledScalar(var_name, comp))
    return *getDefaultValue(var_name);

  MooseVariableScalar * var = getScalarVar(var_name, comp);
  return (_sc_is_implicit) ? var->slnOld() : var->slnOlder();
}

VariableValue &
ScalarCoupleable::coupledScalarDot(const std::string & var_name, unsigned int comp)
{
  MooseVariableScalar * var = getScalarVar(var_name, comp);
  return var->uDot();
}

VariableValue &
ScalarCoupleable::coupledScalarDotDu(const std::string & var_name, unsigned int comp)
{
  MooseVariableScalar * var = getScalarVar(var_name, comp);
  return var->duDotDu();
}

MooseVariableScalar *
ScalarCoupleable::getScalarVar(const std::string & var_name, unsigned int comp)
{
  if (_coupled_scalar_vars.find(var_name) != _coupled_scalar_vars.end())
  {
    if (comp < _coupled_scalar_vars[var_name].size())
      return _coupled_scalar_vars[var_name][comp];
    else
      mooseError("Trying to get a non-existent component of variable '" + var_name + "'");
  }
  else
    mooseError("Trying to get a non-existent variable '" + var_name + "'");
}

unsigned int
ScalarCoupleable::coupledScalarComponents(const std::string & var_name)
{
  return _coupled_scalar_vars[var_name].size();
}
<commit_msg>add a check in scalar coupleable to make sure optional coupled variable is indeed provided #6376<commit_after>/****************************************************************/
/*               DO NOT MODIFY THIS HEADER                      */
/* MOOSE - Multiphysics Object Oriented Simulation Environment  */
/*                                                              */
/*           (c) 2010 Battelle Energy Alliance, LLC             */
/*                   ALL RIGHTS RESERVED                        */
/*                                                              */
/*          Prepared by Battelle Energy Alliance, LLC           */
/*            Under Contract No. DE-AC07-05ID14517              */
/*            With the U. S. Department of Energy               */
/*                                                              */
/*            See COPYRIGHT for full restrictions               */
/****************************************************************/

#include "ScalarCoupleable.h"
#include "Problem.h"
#include "SubProblem.h"
#include "FEProblem.h"

ScalarCoupleable::ScalarCoupleable(const InputParameters & parameters) :
    _sc_fe_problem(*parameters.getCheckedPointerParam<FEProblem *>("_fe_problem")),
    _sc_is_implicit(parameters.have_parameter<bool>("implicit") ? parameters.get<bool>("implicit") : true),
    _coupleable_params(parameters)
{
  SubProblem & problem = *parameters.get<SubProblem *>("_subproblem");

  THREAD_ID tid = parameters.have_parameter<THREAD_ID>("_tid") ? parameters.get<THREAD_ID>("_tid") : 0;

  // Coupling
  for (std::set<std::string>::const_iterator iter = parameters.coupledVarsBegin();
       iter != parameters.coupledVarsEnd();
       ++iter)
  {
    std::string name = *iter;
    if (parameters.getVecMooseType(*iter) != std::vector<std::string>())
    {
      std::vector<std::string> vars = parameters.getVecMooseType(*iter);
      for (unsigned int i = 0; i < vars.size(); i++)
      {
        std::string coupled_var_name = vars[i];
        if (problem.hasScalarVariable(coupled_var_name))
        {
          MooseVariableScalar * scalar_var = &problem.getScalarVariable(tid, coupled_var_name);
          _coupled_scalar_vars[name].push_back(scalar_var);
          _coupled_moose_scalar_vars.push_back(scalar_var);
        }
        else if (problem.hasVariable(coupled_var_name))
          ; // ignore normal variables
        else
          mooseError("Coupled variable '" + coupled_var_name + "' was not found\n");
      }
    }
  }
}

ScalarCoupleable::~ScalarCoupleable()
{
  for (std::map<std::string, VariableValue *>::iterator it = _default_value.begin(); it != _default_value.end(); ++it)
  {
    it->second->release();
    delete it->second;
  }
}

const std::vector<MooseVariableScalar *> &
ScalarCoupleable::getCoupledMooseScalarVars()
{
  return _coupled_moose_scalar_vars;
}

bool
ScalarCoupleable::isCoupledScalar(const std::string & var_name, unsigned int i)
{
  std::map<std::string, std::vector<MooseVariableScalar *> >::iterator it = _coupled_scalar_vars.find(var_name);
  if (it != _coupled_scalar_vars.end())
    return (i < it->second.size());
  else
  {
    // Make sure the user originally requested this value in the InputParameter syntax
    if (!_coupleable_params.hasCoupledValue(var_name))
      mooseError("The coupled scalar variable \"" << var_name << "\" was never added to this objects's InputParameters, please double-check your spelling");

    return false;
  }
}

unsigned int
ScalarCoupleable::coupledScalar(const std::string & var_name, unsigned int comp)
{
  return getScalarVar(var_name, comp)->number();
}

VariableValue *
ScalarCoupleable::getDefaultValue(const std::string & var_name)
{
  std::map<std::string, VariableValue *>::iterator default_value_it = _default_value.find(var_name);
  if (default_value_it == _default_value.end())
  {
    VariableValue * value = new VariableValue(_sc_fe_problem.getMaxScalarOrder(), _coupleable_params.defaultCoupledValue(var_name));
    default_value_it = _default_value.insert(std::make_pair(var_name, value)).first;
  }

  return default_value_it->second;
}

VariableValue &
ScalarCoupleable::coupledScalarValue(const std::string & var_name, unsigned int comp)
{
  if (!isCoupledScalar(var_name, comp))
    return *getDefaultValue(var_name);

  MooseVariableScalar * var = getScalarVar(var_name, comp);
  return (_sc_is_implicit) ? var->sln() : var->slnOld();
}

VariableValue &
ScalarCoupleable::coupledScalarValueOld(const std::string & var_name, unsigned int comp)
{
  if (!isCoupledScalar(var_name, comp))
    return *getDefaultValue(var_name);

  MooseVariableScalar * var = getScalarVar(var_name, comp);
  return (_sc_is_implicit) ? var->slnOld() : var->slnOlder();
}

VariableValue &
ScalarCoupleable::coupledScalarDot(const std::string & var_name, unsigned int comp)
{
  MooseVariableScalar * var = getScalarVar(var_name, comp);
  return var->uDot();
}

VariableValue &
ScalarCoupleable::coupledScalarDotDu(const std::string & var_name, unsigned int comp)
{
  MooseVariableScalar * var = getScalarVar(var_name, comp);
  return var->duDotDu();
}

MooseVariableScalar *
ScalarCoupleable::getScalarVar(const std::string & var_name, unsigned int comp)
{
  if (_coupled_scalar_vars.find(var_name) != _coupled_scalar_vars.end())
  {
    if (comp < _coupled_scalar_vars[var_name].size())
      return _coupled_scalar_vars[var_name][comp];
    else
      mooseError("Trying to get a non-existent component of variable '" + var_name + "'");
  }
  else
    mooseError("Trying to get a non-existent variable '" + var_name + "'");
}

unsigned int
ScalarCoupleable::coupledScalarComponents(const std::string & var_name)
{
  return _coupled_scalar_vars[var_name].size();
}
<|endoftext|>


<commit_before>/// Copyright (C) 2017 Niklas Rosenstein
/// All rights reserved.

#pragma once
#include <c4d.h>
#include "math.hpp"

namespace c4ddev {

  enum BLIT_MODE {
    BLIT_NN,
    BLIT_BILINEAR,
    BLIT_BICUBIC
  };

  //
  // Render one bitmap onto another using one of three interpolation modes as
  // specified by the #BLIT_MODE enumeration
  // The #FuncRead function must have the following signature:
  //     void (Int32 x, Int32 y, Float col[4])
  // The #FuncWrite function must have the following signature:
  //     void (Int32 x, Int32 y, Float const col[4])
  //
  template <typename FuncWrite, typename FuncRead>
  void BlitBitmap(
    FuncWrite&& write,
    FuncRead&& read,
    Int32 dx,
    Int32 dy,
    Int32 dw,
    Int32 dh,
    Int32 sx,
    Int32 sy,
    Int32 sw,
    Int32 sh,
    BLIT_MODE mode=BLIT_NN
  ){
    // 5 colors with each 4 components.
    Float c[5][4];
    #pragma omp parallel for private(c)
    for (Int32 y1 = 0; y1 < dh; ++y1) {
      for (Int32 x1 = 0; x1 < dw; ++x1) {
        // Map the coordinates onto the source bitmap.
        Float y = (y1 / Float(dh)) * sh + sx;
        Float x = (x1 / Float(dw)) * sw + sy;
        Int32 iy = Floor(y);
        Int32 ix = Floor(x);
        read(ix+0, iy+1, c[0]);
        read(ix+0, iy+0, c[1]);
        read(ix+1, iy+0, c[2]);
        read(ix+1, iy+1, c[3]);

        if (mode == 1) {
          // FIXME: Black tear-line appearing in upscaled image.
          c[4][0] = BilinearInterpolation(c[0][0], c[0][1], c[0][2], c[0][3], ix, iy, ix+1, iy+1, x, y);
          c[4][1] = BilinearInterpolation(c[1][0], c[1][1], c[1][2], c[1][3], ix, iy, ix+1, iy+1, x, y);
          c[4][2] = BilinearInterpolation(c[2][0], c[2][1], c[2][2], c[2][3], ix, iy, ix+1, iy+1, x, y);
          c[4][3] = BilinearInterpolation(c[3][0], c[3][1], c[3][2], c[3][3], ix, iy, ix+1, iy+1, x, y);
        }
        else if (mode == 2) {
          // FIXME: Implement Bicubic interpolation.
          //r[4] = BicubicInterpolation(r[0], r[1], r[2], r[3], ix, iy, ix+1, iy+1, x, y);
          //g[4] = BicubicInterpolation(g[0], g[1], g[2], g[3], ix, iy, ix+1, iy+1, x, y);
          //b[4] = BicubicInterpolation(b[0], b[1], b[2], b[3], ix, iy, ix+1, iy+1, x, y);
          //a[4] = BicubicInterpolation(a[0], a[1], a[2], a[3], ix, iy, ix+1, iy+1, x, y);
        }
        else {
          // FIXME: Proper nearest neighbour interpolation.
          memcpy(c[4], c[0], sizeof(c[0]));
        }
        write(dx+x1, dy+y1, c[4]);
      }
    }

  }

  inline void BlitBitmap(
    BaseBitmap* dst,
    BaseBitmap* src,
    Int32 dx,
    Int32 dy,
    Int32 dw,
    Int32 dh,
    Int32 sx,
    Int32 sy,
    Int32 sw,
    Int32 sh,
    BLIT_MODE mode=BLIT_NN
  ){
    // FIXME: Alpha.
    return BlitBitmap(
      [dst](Int32 x, Int32 y, Float const col[4]) {
        dst->SetPixel(x, y, col[0], col[1], col[2]);
      },
      [src](Int32 x, Int32 y, Float col[4]) {
        UInt16 r, g, b, a = 255;
        src->GetPixel(x, y, &r, &g, &b);
        col[0] = r;
        col[1] = g;
        col[2] = b;
        col[3] = a;
      },
      dx, dy, dw, dh, sx, sy, sw, sh, mode
    );
  }

  inline void BlitBitmap(
    GeClipMap* dst,
    BaseBitmap* src,
    Int32 dx,
    Int32 dy,
    Int32 dw,
    Int32 dh,
    Int32 sx,
    Int32 sy,
    Int32 sw,
    Int32 sh,
    BLIT_MODE mode=BLIT_NN
  ){
    // FIXME: Alpha.
    Int32 dbw = dst->GetBw();
    Int32 dbh = dst->GetBh();
    return BlitBitmap(
      [dst, dbw, dbh](Int32 x, Int32 y, Float const col[4]) {
        if (x < 0 || y < 0 || x >= dbw || y >= dbh) return;
        dst->SetPixelRGBA(x, y, col[0], col[1], col[2], col[3]);
      },
      [src](Int32 x, Int32 y, Float col[4]) {
        UInt16 r, g, b, a = 255;
        src->GetPixel(x, y, &r, &g, &b);
        col[0] = r;
        col[1] = g;
        col[2] = b;
        col[3] = a;
      },
      dx, dy, dw, dh, sx, sy, sw, sh, mode
    );
  }

} // namespace c4ddev
<commit_msg>BlitClipmap() functions now must return a boolean<commit_after>/// Copyright (C) 2017 Niklas Rosenstein
/// All rights reserved.

#pragma once
#include <c4d.h>
#include "math.hpp"

namespace c4ddev {

  enum BLIT_MODE {
    BLIT_NN,
    BLIT_BILINEAR,
    BLIT_BICUBIC
  };

  //
  // Render one bitmap onto another using one of three interpolation modes as
  // specified by the #BLIT_MODE enumeration
  // The #FuncRead function must have the following signature:
  //     bool (Int32 x, Int32 y, Float col[4])
  // The #FuncWrite function must have the following signature:
  //     bool (Int32 x, Int32 y, Float const col[4])
  //
  template <typename FuncWrite, typename FuncRead>
  void BlitBitmap(
    FuncWrite&& write,
    FuncRead&& read,
    Int32 dx,
    Int32 dy,
    Int32 dw,
    Int32 dh,
    Int32 sx,
    Int32 sy,
    Int32 sw,
    Int32 sh,
    BLIT_MODE mode=BLIT_NN
  ){
    // 5 colors with each 4 components.
    Float c[5][4];
    #pragma omp parallel for private(c)
    for (Int32 y1 = 0; y1 < dh; ++y1) {
      for (Int32 x1 = 0; x1 < dw; ++x1) {
        // Map the coordinates onto the source bitmap.
        Float y = (y1 / Float(dh)) * sh + sx;
        Float x = (x1 / Float(dw)) * sw + sy;
        Int32 iy = Floor(y);
        Int32 ix = Floor(x);
        Bool valid = read(ix+0, iy+1, c[0]) && read(ix+0, iy+0, c[1]) && read(ix+1, iy+0, c[2]) && read(ix+1, iy+1, c[3]);
        if (!valid) continue;

        if (mode == 1) {
          // FIXME: Black tear-line appearing in upscaled image.
          c[4][0] = BilinearInterpolation(c[0][0], c[0][1], c[0][2], c[0][3], ix, iy, ix+1, iy+1, x, y);
          c[4][1] = BilinearInterpolation(c[1][0], c[1][1], c[1][2], c[1][3], ix, iy, ix+1, iy+1, x, y);
          c[4][2] = BilinearInterpolation(c[2][0], c[2][1], c[2][2], c[2][3], ix, iy, ix+1, iy+1, x, y);
          c[4][3] = BilinearInterpolation(c[3][0], c[3][1], c[3][2], c[3][3], ix, iy, ix+1, iy+1, x, y);
        }
        else if (mode == 2) {
          // FIXME: Implement Bicubic interpolation.
          //r[4] = BicubicInterpolation(r[0], r[1], r[2], r[3], ix, iy, ix+1, iy+1, x, y);
          //g[4] = BicubicInterpolation(g[0], g[1], g[2], g[3], ix, iy, ix+1, iy+1, x, y);
          //b[4] = BicubicInterpolation(b[0], b[1], b[2], b[3], ix, iy, ix+1, iy+1, x, y);
          //a[4] = BicubicInterpolation(a[0], a[1], a[2], a[3], ix, iy, ix+1, iy+1, x, y);
        }
        else {
          // FIXME: Proper nearest neighbour interpolation.
          memcpy(c[4], c[0], sizeof(c[0]));
        }
        write(dx+x1, dy+y1, c[4]);
      }
    }

  }

  inline void BlitBitmap(
    BaseBitmap* dst,
    BaseBitmap* src,
    Int32 dx,
    Int32 dy,
    Int32 dw,
    Int32 dh,
    Int32 sx,
    Int32 sy,
    Int32 sw,
    Int32 sh,
    BLIT_MODE mode=BLIT_NN
  ){
    // FIXME: Alpha.
    Int32 dbw = dst->GetBw();
    Int32 dbh = dst->GetBh();
    Int32 sbw = src->GetBw();
    Int32 sbh = src->GetBh();
    return BlitBitmap(
      [dst, dbw, dbh](Int32 x, Int32 y, Float const col[4]) {
        if (x < 0 || y < 0 || x >= dbw || y >= dbh) return false;
        dst->SetPixel(x, y, col[0], col[1], col[2]);
        return true;
      },
      [src, sbw, sbh](Int32 x, Int32 y, Float col[4]) {
        if (x < 0 || y < 0 || x >= sbw || y >= sbh) return false;
        UInt16 r, g, b, a = 255;
        src->GetPixel(x, y, &r, &g, &b);
        col[0] = r;
        col[1] = g;
        col[2] = b;
        col[3] = a;
        return true;
      },
      dx, dy, dw, dh, sx, sy, sw, sh, mode
    );
  }

  inline void BlitBitmap(
    GeClipMap* dst,
    BaseBitmap* src,
    Int32 dx,
    Int32 dy,
    Int32 dw,
    Int32 dh,
    Int32 sx,
    Int32 sy,
    Int32 sw,
    Int32 sh,
    BLIT_MODE mode=BLIT_NN
  ){
    // FIXME: Alpha.
    Int32 dbw = dst->GetBw();
    Int32 dbh = dst->GetBh();
    Int32 sbw = src->GetBw();
    Int32 sbh = src->GetBh();
    return BlitBitmap(
      [dst, dbw, dbh](Int32 x, Int32 y, Float const col[4]) {
        if (x < 0 || y < 0 || x >= dbw || y >= dbh) return false;
        dst->SetPixelRGBA(x, y, col[0], col[1], col[2], col[3]);
        return true;
      },
      [src, sbw, sbh](Int32 x, Int32 y, Float col[4]) {
        if (x < 0 || y < 0 || x >= sbw || y >= sbh) return false;
        UInt16 r, g, b, a = 255;
        src->GetPixel(x, y, &r, &g, &b);
        col[0] = r;
        col[1] = g;
        col[2] = b;
        col[3] = a;
        return true;
      },
      dx, dy, dw, dh, sx, sy, sw, sh, mode
    );
  }

} // namespace c4ddev
<|endoftext|>


<commit_before>#include "itemlist.h"
#include <QDebug>

ItemList::ItemList(QWidget *parent, CBHash settingsSet, QJsonObject * attrs) : QTreeView(parent) {
    settings = settingsSet;
    setIndentation(8);

//    setStyleSheet(QString(
//                      "QTreeView {"
//                          "background-color: black;"
//                      "}"
//                      ));

    setEditTriggers(QAbstractItemView::NoEditTriggers);

    setDragEnabled(true);
    setAcceptDrops(true);
    setDropIndicatorShown(true);

    setDragDropMode(QAbstractItemView::DragDrop);
    setDefaultDropAction(Qt::CopyAction);

    setExpandsOnDoubleClick(true);

    setSelectionBehavior(QAbstractItemView::SelectRows);
    setSelectionMode(QAbstractItemView::SingleSelection);

    setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded);

//  setDragDropOverwriteMode(true);
//  setMovement(QTreeView::Snap);

//  setFlow(QListView::TopToBottom);

    model = new Model(attrs);
    setModel(model);
//    setTreePosition(2);
//    setRootIndex();
//    setRowHidden(0, rootIndex(), true);

    expandAll();

    setItemDelegate(new ModelItemDelegate(this));

    setContextMenuPolicy(Qt::CustomContextMenu);
    setIconSize(QSize(0,0));

    connect(this, SIGNAL(doubleClicked(const QModelIndex&)), this, SLOT(on_doubleClick(const QModelIndex&)));
    connect(model, SIGNAL(itemsCountChanged(int)), parent, SLOT(updateHeader(int)));
    connect(this, SIGNAL(customContextMenuRequested(const QPoint&)), this, SLOT(showContextMenu(const QPoint &)));

    header() -> setSectionResizeMode(0, QHeaderView::Interactive);
//    header()->setStretchLastSection(false);
}

ItemList::~ItemList() {
    delete model;
}

Model * ItemList::getModel() const {
    return model;
}

void ItemList::keyPressEvent(QKeyEvent *event) {
    if (event ->key() == Qt::Key_Enter || event ->key() == Qt::Key_Return) {
        QModelIndexList list = selectedIndexes();

        if (list.count() > 0) {
            ModelItem * item = model -> getItem(list.first());
            execItem(item);
        }
    } else if (event ->key() == Qt::Key_Delete) {
        QModelIndexList list = selectedIndexes();
        QModelIndex modelIndex;

        for(int i = list.count() - 1; i >= 0; i--) {
            modelIndex = list.at(i);
            removeItem(model -> getItem(modelIndex));
        }
    } else { QTreeView::keyPressEvent(event); }
}

ModelItem * ItemList::activeItem(bool next) {
    ModelItem * item = 0;

    if (Player::instance() -> currentPlaylist() == this) {
        if (Player::instance() -> playedItem()) {
            item = Player::instance() -> playedItem();
        }
    }

    if (item == 0) {
        QModelIndexList list = selectedIndexes();

        if (list.count() > 0) {
            item = model -> getItem(list.first());

            if (!item -> getState() -> isUnprocessed()) {
                QModelIndex m;
                if (next) {
                    m = this -> indexAbove(list.first());
                } else { m = this -> indexBelow(list.first()); }

                if (m.isValid()) {
                   item = model -> getItem(m);
                } else {
                   item = model -> getItem(list.first().parent());
                }
            }
        } else {
            item = model -> getItem(this -> rootIndex());
        }
    }

    return item;
}

void ItemList::proceedPrev() {
    ModelItem * item = activeItem(false);

    if (item == 0) return;

    item = prevItem(item);
    execItem(item);
}

void ItemList::proceedNext() {
    ModelItem * item = activeItem();
    if (item == 0) return;

    item = nextItem(item);
    execItem(item);
}

void ItemList::deleteCurrentProceedNext() {
    ModelItem * item = activeItem();
    if (item == 0) return;

    item = nextItem(item);

    // check logic !!!
    if (Player::instance() -> currentPlaylist() == this) {
        if (Player::instance() -> playedItem()) {
            removeItem(Player::instance() -> playedItem());
        }
    }

    execItem(item);
}

void ItemList::dragEnterEvent(QDragEnterEvent *event) {
    if (event -> source() != this && event -> mimeData() -> hasFormat("text/uri-list"))
        event -> accept();
    else event -> ignore();
}

void ItemList::dragMoveEvent(QDragMoveEvent * event) {
    if (event -> source() != this && event -> mimeData() -> hasFormat("text/uri-list"))
        event -> accept();
    else event -> ignore();
}

//static QStringList nameFiltersFromString(const QString &nameFilter);

//QStringList entryList(Filters filters = NoFilter, SortFlags sort = NoSort) const;
//QStringList entryList(const QStringList &nameFilters, Filters filters = NoFilter,
//                      SortFlags sort = NoSort) const;

//QFileInfoList entryInfoList(Filters filters = NoFilter, SortFlags sort = NoSort) const;
//QFileInfoList entryInfoList(const QStringList &nameFilters, Filters filters = NoFilter,
//                            SortFlags sort = NoSort) const;

void ItemList::filesRoutine(ModelItem * index, QFileInfoList list){
    foreach(QFileInfo file, list) {
        if (file.isDir()) {
            ModelItem * new_index = model -> addFolder(file.fileName(), index);
            filesRoutine(new_index, QDir(file.filePath()).entryInfoList(QDir::Dirs | QDir::Files | QDir::NoDotAndDotDot | QDir::Hidden));
        } else {
            model -> appendRow(file.filePath(), index);
        }
    }
}

void ItemList::filesRoutine(ModelItem * index, QList<QUrl> list){
    foreach(QUrl url, list) {
        QFileInfo file = QFileInfo(url.toLocalFile());
        if (file.isDir()) {
            ModelItem * new_index = model -> addFolder(file.fileName(), index);
            filesRoutine(new_index, QDir(file.filePath()).entryInfoList(QDir::Dirs | QDir::Files | QDir::NoDotAndDotDot | QDir::Hidden));
        } else {
            model -> appendRow(file.filePath(), index);
        }
    }
}

void ItemList::dropEvent(QDropEvent *event) {
    if (event -> source() != this && event -> mimeData() -> hasUrls()) {
        QList<QUrl> list = event -> mimeData() -> urls();
        ModelItem * index = model -> buildPath(QFileInfo(list.first().toLocalFile()).path()); // -> parent();
        filesRoutine(index, list);
        model -> repaint();

        QModelIndex modelIndex = model -> index(index);
        expand(modelIndex);
        scrollTo(modelIndex);
        event -> accept();
    } else event -> ignore();
}

void ItemList::startDrag(Qt::DropActions /*supportedActions*/) {
//    QByteArray itemData;
//    QDataStream dataStream(&itemData, QIODevice::WriteOnly);

//    ListWidgetItem *item = dynamic_cast<ListWidgetItem *>(childAt(dragPoint));

//    dataStream << dragPoint;

//    QMimeData *mimeData = new QMimeData;
//    mimeData->setData("application/x-QListView-DragAndDrop", itemData);

//    drag = new QDrag(this);
//    drag->setMimeData(mimeData);
//    drag->setHotSpot(mapToParent(QPoint(item->x(),y)));
//    drag->setPixmap(currentPixmap);

//    QModelIndex indx = indexAt(dragPoint);
//    if (drag->exec(Qt::MoveAction | Qt::CopyAction) == Qt::MoveAction)
//     {
//        model()->removeRow(indx.row());
//     }
}

void ItemList::on_doubleClick(const QModelIndex &index) {
    ModelItem * item = model -> getItem(index);

    if (!item -> getState() -> isUnprocessed()) {
        execItem(item);
    }
}

void ItemList::showContextMenu(const QPoint& pnt) {
    QList<QAction *> actions;

    if (indexAt(pnt).isValid()) {
        QAction * openAct = new QAction(QIcon(":/open"), "Open location", this);
        connect(openAct, SIGNAL(triggered(bool)), this, SLOT(openLocation()));
        actions.append(openAct);
    }

    if (actions.count() > 0)
        QMenu::exec(actions, mapToGlobal(pnt));
}

void ItemList::openLocation() {
    ModelItem * item = model -> getItem(this -> currentIndex());
    if (item -> getState() -> isUnprocessed())
        QDesktopServices::openUrl(QUrl::fromLocalFile(item -> fullpath()));
    else
        QDesktopServices::openUrl(QUrl::fromLocalFile(item -> parent() -> fullpath()));
}

QJsonObject ItemList::toJSON() {
    QJsonObject res = model -> getItem(rootIndex()) -> toJSON();
    QJsonObject set = QJsonObject();

    foreach(QString c, settings.keys()) {
        set[c] = settings.value(c);
    }

    res["s"] = set;
    res["l"] = model -> itemsCount();
    return res;
}

bool ItemList::isRemoveFileWithItem() {
    return settings["d"];
}

bool ItemList::isPlaylist() {
    return settings["p"];
}

CBHash ItemList::getSettings() const {
    return settings;
}
void ItemList::setSettings(CBHash newSettings) {
    settings = newSettings;
}

////////////////////////////////////////////////////////////
//// Dnd
////////////////////////////////////////////////////////////

void ItemList::mousePressEvent(QMouseEvent *event) {
    if (event->button() == Qt::LeftButton) {
        dragStartPoint = event -> pos();
    }

    QTreeView::mousePressEvent(event);
}

void ItemList::mouseMoveEvent(QMouseEvent * event) {
    if ((event -> buttons() == Qt::LeftButton) && (dragStartPoint - event -> pos()).manhattanLength() >= 5){
        QDrag * drag = new QDrag(this);
        QMimeData * mimeData = model -> mimeData(selectedIndexes());
        qDebug() << mimeData ->text().length();
//        drag -> setPixmap(toolIcon);
        drag -> setMimeData(mimeData);
        drag -> exec();//(Qt::CopyAction, Qt::CopyAction);
    }

    QTreeView::mouseMoveEvent(event);
}

void ItemList::markSelectedAsLiked() {
    ModelItem * temp;
    foreach (const QModelIndex &index, selectedIndexes()) {
        if (index.isValid()) {
            temp = model -> getItem(index);
            if (!temp -> getState() -> isUnprocessed()) {
                temp -> setState(STATE_LIKED);
                model -> refreshItem(temp);
            }
        }
    }
}

////////////////////////////////////////////////////////////

bool ItemList::execItem(ModelItem * item) {
    if (item) {
        scrollTo(model -> index(item));
        if (item -> isExist()) {
            Player::instance() -> playItem(this, item);
            return true;
        }
        else {
            item -> getState() -> setNotExist();
            model -> refreshItem(item);
        }
    } else return true;

    return false;
}

void ItemList::removeItem(ModelItem * item) {
    QModelIndex modelIndex = model -> index(item);
    QString delPath = item -> fullpath();

    if (Player::instance() -> playedItem() == item) {
        Player::instance() -> removePlaylist();
    }

    if (model -> removeRow(modelIndex.row(), modelIndex.parent())) {
        if (isRemoveFileWithItem()) {
            if (item -> getState() -> isUnprocessed()) {
                QDir(delPath).removeRecursively();
            } else {
                QFile::remove(delPath);
            }
        }
    }
}

////////////////////////////////////////////////////////////

// test needed / update need
ModelItem * ItemList::nextItem(QModelIndex currIndex) {
    QModelIndex newIndex;
    ModelItem * item;

    while(true) {
        newIndex = currIndex.parent().child(currIndex.row()+1, 0); //indexBelow(currIndex);

        if (newIndex.isValid()) {
            item = model -> getItem(newIndex);
            qDebug() << item -> data(0);
            if (!item->getState() -> isUnprocessed()) {
                return item;
            } else {
                currIndex = newIndex.child(0, 0);
            }
        } else {
            currIndex = currIndex.parent();
            item = model -> getItem(newIndex);

            if (!currIndex.isValid())
                return model -> root();
        }
    }
}

ModelItem * ItemList::nextItem(ModelItem * curr) {
    ModelItem * item = curr;
    bool first_elem = curr -> parent() == 0;

    while(true) {
        if (first_elem) {
            first_elem = false;
        } else {
            item = item -> parent() -> child(item -> row() + 1);
        }

        if (item != 0) {
            if (!item -> getState() -> isUnprocessed()) {
                return item;
            } else {
                curr = item;
                item = curr -> child(0);
                first_elem = true;
            }
        } else {
            if (curr -> parent() == 0)
                return 0;

            item = curr;
            curr = curr -> parent();
        }
    }
}
ModelItem * ItemList::prevItem(ModelItem * curr) {
    ModelItem * item = curr;
    bool last_elem = false;

    while(true) {
        if (last_elem) {
            last_elem = false;
        } else {
            item = item -> parent() -> child(item -> row() - 1);
        }

        if (item != 0) {
            if (!item->getState() -> isUnprocessed()) {
                return item;
            } else {
                curr = item;
                item = curr -> child(item -> childCount() - 1);
                last_elem = true;
            }
        } else {
            if (curr -> parent() == 0)
                return 0;

            item = curr;
            curr = curr -> parent();
        }
    }
}
<commit_msg>fix item search<commit_after>#include "itemlist.h"
#include <QDebug>

ItemList::ItemList(QWidget *parent, CBHash settingsSet, QJsonObject * attrs) : QTreeView(parent) {
    settings = settingsSet;
    setIndentation(8);

//    setStyleSheet(QString(
//                      "QTreeView {"
//                          "background-color: black;"
//                      "}"
//                      ));

    setEditTriggers(QAbstractItemView::NoEditTriggers);

    setDragEnabled(true);
    setAcceptDrops(true);
    setDropIndicatorShown(true);

    setDragDropMode(QAbstractItemView::DragDrop);
    setDefaultDropAction(Qt::CopyAction);

    setExpandsOnDoubleClick(true);

    setSelectionBehavior(QAbstractItemView::SelectRows);
    setSelectionMode(QAbstractItemView::SingleSelection);

    setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded);

//  setDragDropOverwriteMode(true);
//  setMovement(QTreeView::Snap);

//  setFlow(QListView::TopToBottom);

    model = new Model(attrs);
    setModel(model);
//    setTreePosition(2);
//    setRootIndex();
//    setRowHidden(0, rootIndex(), true);

    expandAll();

    setItemDelegate(new ModelItemDelegate(this));

    setContextMenuPolicy(Qt::CustomContextMenu);
    setIconSize(QSize(0,0));

    connect(this, SIGNAL(doubleClicked(const QModelIndex&)), this, SLOT(on_doubleClick(const QModelIndex&)));
    connect(model, SIGNAL(itemsCountChanged(int)), parent, SLOT(updateHeader(int)));
    connect(this, SIGNAL(customContextMenuRequested(const QPoint&)), this, SLOT(showContextMenu(const QPoint &)));

    header() -> setSectionResizeMode(0, QHeaderView::Interactive);
//    header()->setStretchLastSection(false);
}

ItemList::~ItemList() {
    delete model;
}

Model * ItemList::getModel() const {
    return model;
}

void ItemList::keyPressEvent(QKeyEvent *event) {
    if (event ->key() == Qt::Key_Enter || event ->key() == Qt::Key_Return) {
        QModelIndexList list = selectedIndexes();

        if (list.count() > 0) {
            ModelItem * item = model -> getItem(list.first());
            execItem(item);
        }
    } else if (event ->key() == Qt::Key_Delete) {
        QModelIndexList list = selectedIndexes();
        QModelIndex modelIndex;

        for(int i = list.count() - 1; i >= 0; i--) {
            modelIndex = list.at(i);
            removeItem(model -> getItem(modelIndex));
        }
    } else { QTreeView::keyPressEvent(event); }
}

ModelItem * ItemList::activeItem(bool next) {
    ModelItem * item = 0;

    if (Player::instance() -> currentPlaylist() == this) {
        if (Player::instance() -> playedItem()) {
            item = Player::instance() -> playedItem();
        }
    }

    // has some bug on unprocessed select
    if (item == 0) {
        QModelIndexList list = selectedIndexes();

        if (list.count() > 0) {
            item = model -> getItem(list.first());

            if (!item -> getState() -> isUnprocessed()) {
                QModelIndex m;
                if (next) {
                    m = this -> indexAbove(list.first());
                } else { m = this -> indexBelow(list.first()); }

                if (m.isValid()) {
                   item = model -> getItem(m);
                } else {
                   item = model -> getItem(list.first().parent());
                }
            }
        } else {
            item = model -> getItem(this -> rootIndex());
        }
    }

    return item;
}

void ItemList::proceedPrev() {
    ModelItem * item = activeItem(false);

    if (item == 0) return;

    item = prevItem(item);
    execItem(item);
}

void ItemList::proceedNext() {
    ModelItem * item = activeItem();
    if (item == 0) return;

    item = nextItem(item);
    execItem(item);
}

void ItemList::deleteCurrentProceedNext() {
    ModelItem * item = activeItem();
    if (item == 0) return;

    item = nextItem(item);

    // check logic !!!
    if (Player::instance() -> currentPlaylist() == this) {
        if (Player::instance() -> playedItem()) {
            removeItem(Player::instance() -> playedItem());
        }
    }

    execItem(item);
}

void ItemList::dragEnterEvent(QDragEnterEvent *event) {
    if (event -> source() != this && event -> mimeData() -> hasFormat("text/uri-list"))
        event -> accept();
    else event -> ignore();
}

void ItemList::dragMoveEvent(QDragMoveEvent * event) {
    if (event -> source() != this && event -> mimeData() -> hasFormat("text/uri-list"))
        event -> accept();
    else event -> ignore();
}

//static QStringList nameFiltersFromString(const QString &nameFilter);

//QStringList entryList(Filters filters = NoFilter, SortFlags sort = NoSort) const;
//QStringList entryList(const QStringList &nameFilters, Filters filters = NoFilter,
//                      SortFlags sort = NoSort) const;

//QFileInfoList entryInfoList(Filters filters = NoFilter, SortFlags sort = NoSort) const;
//QFileInfoList entryInfoList(const QStringList &nameFilters, Filters filters = NoFilter,
//                            SortFlags sort = NoSort) const;

void ItemList::filesRoutine(ModelItem * index, QFileInfoList list){
    foreach(QFileInfo file, list) {
        if (file.isDir()) {
            ModelItem * new_index = model -> addFolder(file.fileName(), index);
            filesRoutine(new_index, QDir(file.filePath()).entryInfoList(QDir::Dirs | QDir::Files | QDir::NoDotAndDotDot | QDir::Hidden));
        } else {
            model -> appendRow(file.filePath(), index);
        }
    }
}

void ItemList::filesRoutine(ModelItem * index, QList<QUrl> list){
    foreach(QUrl url, list) {
        QFileInfo file = QFileInfo(url.toLocalFile());
        if (file.isDir()) {
            ModelItem * new_index = model -> addFolder(file.fileName(), index);
            filesRoutine(new_index, QDir(file.filePath()).entryInfoList(QDir::Dirs | QDir::Files | QDir::NoDotAndDotDot | QDir::Hidden));
        } else {
            model -> appendRow(file.filePath(), index);
        }
    }
}

void ItemList::dropEvent(QDropEvent *event) {
    if (event -> source() != this && event -> mimeData() -> hasUrls()) {
        QList<QUrl> list = event -> mimeData() -> urls();
        ModelItem * index = model -> buildPath(QFileInfo(list.first().toLocalFile()).path()); // -> parent();
        filesRoutine(index, list);
        model -> repaint();

        QModelIndex modelIndex = model -> index(index);
        expand(modelIndex);
        scrollTo(modelIndex);
        event -> accept();
    } else event -> ignore();
}

void ItemList::startDrag(Qt::DropActions /*supportedActions*/) {
//    QByteArray itemData;
//    QDataStream dataStream(&itemData, QIODevice::WriteOnly);

//    ListWidgetItem *item = dynamic_cast<ListWidgetItem *>(childAt(dragPoint));

//    dataStream << dragPoint;

//    QMimeData *mimeData = new QMimeData;
//    mimeData->setData("application/x-QListView-DragAndDrop", itemData);

//    drag = new QDrag(this);
//    drag->setMimeData(mimeData);
//    drag->setHotSpot(mapToParent(QPoint(item->x(),y)));
//    drag->setPixmap(currentPixmap);

//    QModelIndex indx = indexAt(dragPoint);
//    if (drag->exec(Qt::MoveAction | Qt::CopyAction) == Qt::MoveAction)
//     {
//        model()->removeRow(indx.row());
//     }
}

void ItemList::on_doubleClick(const QModelIndex &index) {
    ModelItem * item = model -> getItem(index);

    if (!item -> getState() -> isUnprocessed()) {
        execItem(item);
    }
}

void ItemList::showContextMenu(const QPoint& pnt) {
    QList<QAction *> actions;

    if (indexAt(pnt).isValid()) {
        QAction * openAct = new QAction(QIcon(":/open"), "Open location", this);
        connect(openAct, SIGNAL(triggered(bool)), this, SLOT(openLocation()));
        actions.append(openAct);
    }

    if (actions.count() > 0)
        QMenu::exec(actions, mapToGlobal(pnt));
}

void ItemList::openLocation() {
    ModelItem * item = model -> getItem(this -> currentIndex());
    if (item -> getState() -> isUnprocessed())
        QDesktopServices::openUrl(QUrl::fromLocalFile(item -> fullpath()));
    else
        QDesktopServices::openUrl(QUrl::fromLocalFile(item -> parent() -> fullpath()));
}

QJsonObject ItemList::toJSON() {
    QJsonObject res = model -> getItem(rootIndex()) -> toJSON();
    QJsonObject set = QJsonObject();

    foreach(QString c, settings.keys()) {
        set[c] = settings.value(c);
    }

    res["s"] = set;
    res["l"] = model -> itemsCount();
    return res;
}

bool ItemList::isRemoveFileWithItem() {
    return settings["d"];
}

bool ItemList::isPlaylist() {
    return settings["p"];
}

CBHash ItemList::getSettings() const {
    return settings;
}
void ItemList::setSettings(CBHash newSettings) {
    settings = newSettings;
}

////////////////////////////////////////////////////////////
//// Dnd
////////////////////////////////////////////////////////////

void ItemList::mousePressEvent(QMouseEvent *event) {
    if (event->button() == Qt::LeftButton) {
        dragStartPoint = event -> pos();
    }

    QTreeView::mousePressEvent(event);
}

void ItemList::mouseMoveEvent(QMouseEvent * event) {
    if ((event -> buttons() == Qt::LeftButton) && (dragStartPoint - event -> pos()).manhattanLength() >= 5){
        QDrag * drag = new QDrag(this);
        QMimeData * mimeData = model -> mimeData(selectedIndexes());
        qDebug() << mimeData ->text().length();
//        drag -> setPixmap(toolIcon);
        drag -> setMimeData(mimeData);
        drag -> exec();//(Qt::CopyAction, Qt::CopyAction);
    }

    QTreeView::mouseMoveEvent(event);
}

void ItemList::markSelectedAsLiked() {
    ModelItem * temp;
    foreach (const QModelIndex &index, selectedIndexes()) {
        if (index.isValid()) {
            temp = model -> getItem(index);
            if (!temp -> getState() -> isUnprocessed()) {
                temp -> setState(STATE_LIKED);
                model -> refreshItem(temp);
            }
        }
    }
}

////////////////////////////////////////////////////////////

bool ItemList::execItem(ModelItem * item) {
    if (item) {
        scrollTo(model -> index(item));
        if (item -> isExist()) {
            Player::instance() -> playItem(this, item);
            return true;
        }
        else {
            item -> getState() -> setNotExist();
            model -> refreshItem(item);
        }
    } else return true;

    return false;
}

void ItemList::removeItem(ModelItem * item) {
    QModelIndex modelIndex = model -> index(item);
    QString delPath = item -> fullpath();

    if (Player::instance() -> playedItem() == item) {
        Player::instance() -> removePlaylist();
    }

    if (model -> removeRow(modelIndex.row(), modelIndex.parent())) {
        if (isRemoveFileWithItem()) {
            if (item -> getState() -> isUnprocessed()) {
                QDir(delPath).removeRecursively();
            } else {
                QFile::remove(delPath);
            }
        }
    }
}

////////////////////////////////////////////////////////////

// test needed / update need
ModelItem * ItemList::nextItem(QModelIndex currIndex) {
    QModelIndex newIndex;
    ModelItem * item;

    while(true) {
        newIndex = currIndex.parent().child(currIndex.row()+1, 0); //indexBelow(currIndex);

        if (newIndex.isValid()) {
            item = model -> getItem(newIndex);
            qDebug() << item -> data(0);
            if (!item->getState() -> isUnprocessed()) {
                return item;
            } else {
                currIndex = newIndex.child(0, 0);
            }
        } else {
            currIndex = currIndex.parent();
            item = model -> getItem(newIndex);

            if (!currIndex.isValid())
                return model -> root();
        }
    }
}

ModelItem * ItemList::nextItem(ModelItem * curr) {
    ModelItem * item = curr;
    bool first_elem = curr -> parent() == 0 || curr -> getState() -> isUnprocessed();

    while(true) {
        if (first_elem) {
            first_elem = false;
        } else {
            item = item -> parent() -> child(item -> row() + 1);
        }

        if (item != 0) {
            if (!item -> getState() -> isUnprocessed()) {
                return item;
            } else {
                curr = item;
                item = curr -> child(0);
                first_elem = true;
            }
        } else {
            if (curr -> parent() == 0)
                return 0;

            item = curr;
            curr = curr -> parent();
        }
    }
}
ModelItem * ItemList::prevItem(ModelItem * curr) {
    ModelItem * item = curr;
    bool last_elem = false;

    while(true) {
        if (last_elem) {
            last_elem = false;
        } else {
            item = item -> parent() -> child(item -> row() - 1);
        }

        if (item != 0) {
            if (!item->getState() -> isUnprocessed()) {
                return item;
            } else {
                curr = item;
                item = curr -> child(item -> childCount() - 1);
                last_elem = true;
            }
        } else {
            if (curr -> parent() == 0)
                return 0;

            item = curr;
            curr = curr -> parent();
        }
    }
}
<|endoftext|>