<commit_before>/*************************************************************************
 *
 *  $RCSfile: navicont.hxx,v $
 *
 *  $Revision: 1.2 $
 *
 *  last change: $Author: jp $ $Date: 2001-05-07 08:53:53 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 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
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (the "License"); You may not use this file
 *  except in compliance with the License. You may obtain a copy of the
 *  License at http://www.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#ifndef _NAVICONT_HXX
#define _NAVICONT_HXX

#ifndef _STRING_HXX
#include <tools/string.hxx>
#endif

class SwDocShell;
class TransferDataContainer;
class TransferableDataHelper;

/*  [Beschreibung]
    Navigator-Bookmark zur eindeutigen Identifizierung im Sw
*/

class NaviContentBookmark
{
    String          aUrl;       // URL inkl. Sprungmarke
    String          aDescr;     // Description
    long            nDocSh;     // Adresse der DocShell
    USHORT          nDefDrag;   // Description enthaelt defaultDragType

public:
    NaviContentBookmark();
    NaviContentBookmark( const String &rUrl, const String& rDesc,
                            USHORT nDragType, const SwDocShell* );

    const String&   GetURL() const              { return aUrl; }
    const String&   GetDescription() const      { return aDescr; }
    USHORT          GetDefaultDragType() const  { return nDefDrag; }
    long            GetDocShell() const         { return nDocSh; }

    static BOOL     HasFormat( TransferableDataHelper& rData,
                                const SwDocShell* pDocSh = 0 );

    void            Copy( TransferDataContainer& rData ) const;
    BOOL            Paste( TransferableDataHelper& rData );
};

#endif
<commit_msg>INTEGRATION: CWS tune05 (1.2.764); FILE MERGED 2004/07/22 08:13:50 cmc 1.2.764.1: #i30554# NaviContentBookmark::HasFormat unused<commit_after>/*************************************************************************
 *
 *  $RCSfile: navicont.hxx,v $
 *
 *  $Revision: 1.3 $
 *
 *  last change: $Author: obo $ $Date: 2004-08-12 13:05:31 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 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
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (the "License"); You may not use this file
 *  except in compliance with the License. You may obtain a copy of the
 *  License at http://www.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#ifndef _NAVICONT_HXX
#define _NAVICONT_HXX

#ifndef _STRING_HXX
#include <tools/string.hxx>
#endif

class SwDocShell;
class TransferDataContainer;
class TransferableDataHelper;

/*  [Beschreibung]
    Navigator-Bookmark zur eindeutigen Identifizierung im Sw
*/

class NaviContentBookmark
{
    String          aUrl;       // URL inkl. Sprungmarke
    String          aDescr;     // Description
    long            nDocSh;     // Adresse der DocShell
    USHORT          nDefDrag;   // Description enthaelt defaultDragType

public:
    NaviContentBookmark();
    NaviContentBookmark( const String &rUrl, const String& rDesc,
                            USHORT nDragType, const SwDocShell* );

    const String&   GetURL() const              { return aUrl; }
    const String&   GetDescription() const      { return aDescr; }
    USHORT          GetDefaultDragType() const  { return nDefDrag; }
    long            GetDocShell() const         { return nDocSh; }
    void            Copy( TransferDataContainer& rData ) const;
    BOOL            Paste( TransferableDataHelper& rData );
};

#endif
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  $RCSfile: view0.cxx,v $
 *
 *  $Revision: 1.1.1.1 $
 *
 *  last change: $Author: hr $ $Date: 2000-09-18 17:14:49 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 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
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (the "License"); You may not use this file
 *  except in compliance with the License. You may obtain a copy of the
 *  License at http://www.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#ifdef PRECOMPILED
#include "ui_pch.hxx"
#endif

#pragma hdrstop

#include "hintids.hxx"

#ifndef _SVX_SRCHITEM_HXX
#include <svx/srchitem.hxx>
#endif
#ifndef _SFXAPP_HXX //autogen
#include <sfx2/app.hxx>
#endif
#ifndef _SVX_SRCHDLG_HXX //autogen
#include <svx/srchdlg.hxx>
#endif
#ifndef _IDETEMP_HXX
#include <basctl/idetemp.hxx>
#endif
#ifndef _SFX_TEMPLDLG_HXX //autogen
#include <sfx2/templdlg.hxx>
#endif
#ifndef _UIVWIMP_HXX
#include <uivwimp.hxx>
#endif

#ifndef _NAVIPI_HXX //autogen
#include <navipi.hxx>
#endif
#include "view.hxx"
#include "basesh.hxx"
#include "docsh.hxx"
#include "globals.hrc"
#include "cmdid.h"          // FN_       ...
#include "globdoc.hxx"
#include "wview.hxx"
#include "shells.hrc"

#define OLEObjects
#define SwView
#define SearchAttributes
#define ReplaceAttributes
#define SearchSettings
#define _ExecSearch ExecSearch
#define _StateSearch StateSearch
#define Frames
#define Graphics
#define Tables
#define Controls
#define GlobalContents
#define Text
#define Frame
#define Graphic
#define Object
#define Draw
#define TextDrawText
#define TextInTable
#define ListInText
#define ListInTable
#define WebTextInTable
#define WebListInText
#define WebListInTable
#define TextPage
#include "itemdef.hxx"
#include <svx/svxslots.hxx>
#include "swslots.hxx"

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

#define C2S(cChar) UniString::CreateFromAscii(cChar)

SFX_IMPL_VIEWFACTORY(SwView, SW_RES(STR_NONAME))
{
    SFX_VIEW_REGISTRATION(SwDocShell);
    SFX_VIEW_REGISTRATION(SwGlobalDocShell);
}

SFX_IMPL_INTERFACE( SwView, SfxViewShell, SW_RES(RID_TOOLS_TOOLBOX) )
{
    SFX_CHILDWINDOW_CONTEXT_REGISTRATION(SID_NAVIGATOR);
    SFX_CHILDWINDOW_REGISTRATION(SfxTemplateDialogWrapper::GetChildWindowId());
    SFX_CHILDWINDOW_REGISTRATION(SvxSearchDialogWrapper::GetChildWindowId());
    SFX_CHILDWINDOW_REGISTRATION(FN_REDLINE_ACCEPT);
    SFX_CHILDWINDOW_REGISTRATION(SID_HYPERLINK_DIALOG);
    SFX_FEATURED_CHILDWINDOW_REGISTRATION(FN_SYNC_LABELS, 1);
    SFX_OBJECTBAR_REGISTRATION( SFX_OBJECTBAR_TOOLS|
                                SFX_VISIBILITY_STANDARD|SFX_VISIBILITY_SERVER,
                                SW_RES(RID_TOOLS_TOOLBOX) );
}

TYPEINIT1(SwView,SfxViewShell)

/*-----------------13.12.97 11:06-------------------

--------------------------------------------------*/
ShellModes  SwView::GetShellMode()
{
    return pViewImpl->GetShellMode();
}

/*-----------------13.12.97 11:28-------------------

--------------------------------------------------*/
view::XSelectionSupplier* SwView::GetUNOObject()
{
    return pViewImpl->GetUNOObject();
}

/*------------------------------------------------------------------------
    $Log: not supported by cvs2svn $
    Revision 1.72  2000/09/18 16:06:12  willem.vandorp
    OpenOffice header added.

    Revision 1.71  2000/09/04 11:44:56  tbe
    basicide, isetbrw, si, vcdlged moved from svx to basctl

    Revision 1.70  2000/05/10 11:53:20  os
    Basic API removed

    Revision 1.69  2000/05/09 14:43:13  os
    BASIC interface partially removed

    Revision 1.68  2000/04/18 15:02:50  os
    UNICODE

    Revision 1.67  2000/03/23 07:50:25  os
    UNO III

    Revision 1.66  2000/02/09 08:07:01  os
    #72165# hyperlink dialog moved again

    Revision 1.65  1999/09/07 13:56:53  os
    Insert/EditIndexEntry as FloatingWindow

    Revision 1.64  1999/01/27 08:58:32  OS
    #56371# TF_ONE51

      Rev 1.63   27 Jan 1999 09:58:32   OS
   #56371# TF_ONE51

      Rev 1.62   15 Jul 1998 12:52:42   OS
   Navigator an der SwView registrieren #34794#

      Rev 1.61   09 Jun 1998 15:32:20   OM
   VC-Controls entfernt

      Rev 1.60   02 Jun 1998 15:49:54   OS
   TF_STARONE raus; GetUNOSelectionObject gestrichen

      Rev 1.59   03 Apr 1998 14:38:18   OS
   UnoObject fuer die View reaktiviert

      Rev 1.58   16 Mar 1998 16:18:04   OM
   Aktualisieren-Button kontextsensitiv

      Rev 1.57   15 Mar 1998 15:14:08   OM
   Synchron-Button

      Rev 1.56   27 Feb 1998 18:25:14   OM
   Redline-Browser

      Rev 1.55   29 Jan 1998 09:21:06   OS
   TF_STARONE

      Rev 1.54   16 Dec 1997 12:00:24   OS
   Impl-Pointer fuer UNO

      Rev 1.53   29 Nov 1997 16:49:14   MA
   includes

      Rev 1.52   21 Nov 1997 15:00:12   MA
   includes

      Rev 1.51   03 Nov 1997 13:58:28   MA
   precomp entfernt

      Rev 1.50   09 Sep 1997 11:33:08   OS
   TextPage heisst nur Page #43650#

      Rev 1.49   08 Sep 1997 10:52:36   OS
   DBG_ERROR -> DBG_ASSERT

      Rev 1.48   08 Sep 1997 07:43:38   OS
   TextTables nur ClassName

      Rev 1.47   04 Sep 1997 18:10:56   MBA
   GetSelectionObject erzeugt richtiges Objekt auch bei WebView

      Rev 1.46   04 Sep 1997 08:25:24   OS
   Tables heisst jetzt TextTables, kein GPF wg. fehlender TLB-Angaben

      Rev 1.45   03 Sep 1997 10:52:26   MBA
   OLEObjects in SVX

      Rev 1.44   29 Aug 1997 12:21:34   MH
   chg: SfxTypeLib_Impl

      Rev 1.43   05 Aug 1997 16:36:38   TJ
   include svx/srchitem.hxx

      Rev 1.42   07 Jul 1997 09:35:10   OS
   Collection fuer GlobalDoc

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

<commit_msg>gallery child window registered<commit_after>/*************************************************************************
 *
 *  $RCSfile: view0.cxx,v $
 *
 *  $Revision: 1.2 $
 *
 *  last change: $Author: os $ $Date: 2000-09-28 15:34:12 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 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
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (the "License"); You may not use this file
 *  except in compliance with the License. You may obtain a copy of the
 *  License at http://www.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#ifdef PRECOMPILED
#include "ui_pch.hxx"
#endif

#pragma hdrstop

#include "hintids.hxx"

#ifndef _SVX_GALBRWS_HXX_
#include <svx/galbrws.hxx>
#endif
#ifndef _SVX_SRCHITEM_HXX
#include <svx/srchitem.hxx>
#endif
#ifndef _SFXAPP_HXX //autogen
#include <sfx2/app.hxx>
#endif
#ifndef _SVX_SRCHDLG_HXX //autogen
#include <svx/srchdlg.hxx>
#endif
#ifndef _IDETEMP_HXX
#include <basctl/idetemp.hxx>
#endif
#ifndef _SFX_TEMPLDLG_HXX //autogen
#include <sfx2/templdlg.hxx>
#endif
#ifndef _UIVWIMP_HXX
#include <uivwimp.hxx>
#endif

#ifndef _NAVIPI_HXX //autogen
#include <navipi.hxx>
#endif
#include "view.hxx"
#include "basesh.hxx"
#include "docsh.hxx"
#include "globals.hrc"
#include "cmdid.h"          // FN_       ...
#include "globdoc.hxx"
#include "wview.hxx"
#include "shells.hrc"

#define OLEObjects
#define SwView
#define SearchAttributes
#define ReplaceAttributes
#define SearchSettings
#define _ExecSearch ExecSearch
#define _StateSearch StateSearch
#define Frames
#define Graphics
#define Tables
#define Controls
#define GlobalContents
#define Text
#define Frame
#define Graphic
#define Object
#define Draw
#define TextDrawText
#define TextInTable
#define ListInText
#define ListInTable
#define WebTextInTable
#define WebListInText
#define WebListInTable
#define TextPage
#include "itemdef.hxx"
#include <svx/svxslots.hxx>
#include "swslots.hxx"

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

#define C2S(cChar) UniString::CreateFromAscii(cChar)

SFX_IMPL_VIEWFACTORY(SwView, SW_RES(STR_NONAME))
{
    SFX_VIEW_REGISTRATION(SwDocShell);
    SFX_VIEW_REGISTRATION(SwGlobalDocShell);
}

SFX_IMPL_INTERFACE( SwView, SfxViewShell, SW_RES(RID_TOOLS_TOOLBOX) )
{
    SFX_CHILDWINDOW_CONTEXT_REGISTRATION(SID_NAVIGATOR);
    SFX_CHILDWINDOW_REGISTRATION(SfxTemplateDialogWrapper::GetChildWindowId());
    SFX_CHILDWINDOW_REGISTRATION(SvxSearchDialogWrapper::GetChildWindowId());
    SFX_CHILDWINDOW_REGISTRATION(FN_REDLINE_ACCEPT);
    SFX_CHILDWINDOW_REGISTRATION(SID_HYPERLINK_DIALOG);
    SFX_CHILDWINDOW_REGISTRATION(GalleryChildWindow::GetChildWindowId());

        SFX_FEATURED_CHILDWINDOW_REGISTRATION(FN_SYNC_LABELS, 1);
    SFX_OBJECTBAR_REGISTRATION( SFX_OBJECTBAR_TOOLS|
                                SFX_VISIBILITY_STANDARD|SFX_VISIBILITY_SERVER,
                                SW_RES(RID_TOOLS_TOOLBOX) );
}

TYPEINIT1(SwView,SfxViewShell)

/*-----------------13.12.97 11:06-------------------

--------------------------------------------------*/
ShellModes  SwView::GetShellMode()
{
    return pViewImpl->GetShellMode();
}

/*-----------------13.12.97 11:28-------------------

--------------------------------------------------*/
view::XSelectionSupplier* SwView::GetUNOObject()
{
    return pViewImpl->GetUNOObject();
}

/*------------------------------------------------------------------------
    $Log: not supported by cvs2svn $
    Revision 1.1.1.1  2000/09/18 17:14:49  hr
    initial import

    Revision 1.72  2000/09/18 16:06:12  willem.vandorp
    OpenOffice header added.

    Revision 1.71  2000/09/04 11:44:56  tbe
    basicide, isetbrw, si, vcdlged moved from svx to basctl

    Revision 1.70  2000/05/10 11:53:20  os
    Basic API removed

    Revision 1.69  2000/05/09 14:43:13  os
    BASIC interface partially removed

    Revision 1.68  2000/04/18 15:02:50  os
    UNICODE

    Revision 1.67  2000/03/23 07:50:25  os
    UNO III

    Revision 1.66  2000/02/09 08:07:01  os
    #72165# hyperlink dialog moved again

    Revision 1.65  1999/09/07 13:56:53  os
    Insert/EditIndexEntry as FloatingWindow

    Revision 1.64  1999/01/27 08:58:32  OS
    #56371# TF_ONE51

      Rev 1.63   27 Jan 1999 09:58:32   OS
   #56371# TF_ONE51

      Rev 1.62   15 Jul 1998 12:52:42   OS
   Navigator an der SwView registrieren #34794#

      Rev 1.61   09 Jun 1998 15:32:20   OM
   VC-Controls entfernt

      Rev 1.60   02 Jun 1998 15:49:54   OS
   TF_STARONE raus; GetUNOSelectionObject gestrichen

      Rev 1.59   03 Apr 1998 14:38:18   OS
   UnoObject fuer die View reaktiviert

      Rev 1.58   16 Mar 1998 16:18:04   OM
   Aktualisieren-Button kontextsensitiv

      Rev 1.57   15 Mar 1998 15:14:08   OM
   Synchron-Button

      Rev 1.56   27 Feb 1998 18:25:14   OM
   Redline-Browser

      Rev 1.55   29 Jan 1998 09:21:06   OS
   TF_STARONE

      Rev 1.54   16 Dec 1997 12:00:24   OS
   Impl-Pointer fuer UNO

      Rev 1.53   29 Nov 1997 16:49:14   MA
   includes

      Rev 1.52   21 Nov 1997 15:00:12   MA
   includes

      Rev 1.51   03 Nov 1997 13:58:28   MA
   precomp entfernt

      Rev 1.50   09 Sep 1997 11:33:08   OS
   TextPage heisst nur Page #43650#

      Rev 1.49   08 Sep 1997 10:52:36   OS
   DBG_ERROR -> DBG_ASSERT

      Rev 1.48   08 Sep 1997 07:43:38   OS
   TextTables nur ClassName

      Rev 1.47   04 Sep 1997 18:10:56   MBA
   GetSelectionObject erzeugt richtiges Objekt auch bei WebView

      Rev 1.46   04 Sep 1997 08:25:24   OS
   Tables heisst jetzt TextTables, kein GPF wg. fehlender TLB-Angaben

      Rev 1.45   03 Sep 1997 10:52:26   MBA
   OLEObjects in SVX

      Rev 1.44   29 Aug 1997 12:21:34   MH
   chg: SfxTypeLib_Impl

      Rev 1.43   05 Aug 1997 16:36:38   TJ
   include svx/srchitem.hxx

      Rev 1.42   07 Jul 1997 09:35:10   OS
   Collection fuer GlobalDoc

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

<|endoftext|>


<commit_before>
// Copyright 2010-2012 University of Washington. All Rights Reserved.
// LICENSE_PLACEHOLDER
// This software was created with Government support under DE
// AC05-76RL01830 awarded by the United States Department of
// Energy. The Government has certain rights in the software.

#ifndef __INCOHERENT_RELEASER_HPP__
#define __INCOHERENT_RELEASER_HPP__

#include "Grappa.hpp"
#include "Message.hpp"

#ifdef VTRACE
#include <vt_user.h>
#endif

// forward declare for active message templates
template< typename T >
class IncoherentReleaser;

template< typename T >
static void incoherent_release_reply_am( typename IncoherentReleaser< T >::ReplyArgs * args,
                                         size_t size,
                                         void * payload, size_t payload_size );

template< typename T >
static void incoherent_release_request_am( typename IncoherentReleaser< T >::RequestArgs * args,
                                           size_t size,
                                           void * payload, size_t payload_size );

/// Stats for IncoherentReleaser
class IRStatistics {
  private:
    uint64_t release_ams;
    uint64_t release_ams_bytes;
#ifdef VTRACE_SAMPLED
    unsigned ir_grp_vt;
    unsigned release_ams_ev_vt;
    unsigned release_ams_bytes_ev_vt;
#endif

  public:
    IRStatistics();
    void reset();

    inline void count_release_ams( uint64_t bytes ) {
      release_ams++;
      release_ams_bytes+=bytes;
    }

    void dump( std::ostream& o, const char * terminator );
    void sample();
    void profiling_sample();
    void merge(const IRStatistics * other);
};

extern IRStatistics incoherent_releaser_stats;

/// IncoherentReleaser behavior for cache.
template< typename T >
class IncoherentReleaser {
private:
  bool release_started_;
  bool released_;
  GlobalAddress< T > * request_address_;
  size_t * count_;
  T ** pointer_;
  Thread * thread_;
  int num_messages_;
  int response_count_;

public:

  IncoherentReleaser( GlobalAddress< T > * request_address, size_t * count, T ** pointer )
    : request_address_( request_address )
    , count_( count )
    , pointer_( pointer )
    , release_started_( false )
    , released_( false )
    , thread_(NULL)
    , num_messages_(0)
    , response_count_(0)
  {
    reset();
  }

  void reset( ) {
    CHECK( !release_started_ || released_ ) << "inconsistent state for reset";
    release_started_ = false;
    released_ = false;
    thread_ = NULL;
    num_messages_ = 0;
    response_count_ = 0;
    if( *count_ == 0 ) {
      DVLOG(5) << "Zero-length release";
      release_started_ = true;
      released_ = true;
    } else if( request_address_->is_2D() ) {
      num_messages_ = 1;
      if( request_address_->node() == Grappa_mynode() ) {
        release_started_ = true;
        released_ = true;
      }
    } else {
      DVLOG(5) << "Straddle: block_max is " << (*request_address_ + *count_).block_max() ;
      DVLOG(5) << ", request_address is " << *request_address_;
      DVLOG(5) << ", sizeof(T) is " << sizeof(T);
      DVLOG(5) << ", count is " << *count_;
      DVLOG(5) << ", block_min is " << request_address_->block_min();

      DVLOG(5) << "Straddle: address is " << *request_address_ ;
      DVLOG(5) << ", address + count is " << *request_address_ + *count_;

      ptrdiff_t byte_diff = ( (*request_address_ + *count_ - 1).last_byte().block_max() -
                               request_address_->first_byte().block_min() );

      DVLOG(5) << "Straddle: address block max is " << request_address_->block_max();
      DVLOG(5) << " address + count block max is " << (*request_address_ + *count_).block_max();
      DVLOG(5) << " address + count -1 block max is " << (*request_address_ + *count_ - 1).block_max();
      DVLOG(5) << " difference is " << ( (*request_address_ + *count_ - 1).block_max() - request_address_->block_min() );
      DVLOG(5) << " multiplied difference is " << ( (*request_address_ + *count_ - 1).block_max() - request_address_->block_min() ) * sizeof(T);
      DVLOG(5) << " address block min " << request_address_->block_min();
      DVLOG(5) << "Straddle: diff is " << byte_diff << " bs " << block_size;
      num_messages_ = byte_diff / block_size;
    }

    if( num_messages_ > 1 ) DVLOG(5) << "****************************** MULTI BLOCK CACHE REQUEST ******************************";

    DVLOG(5) << "Detecting straddle for sizeof(T):" << sizeof(T)
             << " count:" << *count_
             << " num_messages_:" << num_messages_
             << " request_address:" << *request_address_;
  }

  void start_release() {
    if( !release_started_ ) {
#ifdef VTRACE_FULL
      VT_TRACER("incoherent start_release");
#endif
            DVLOG(5) << "Thread " << CURRENT_THREAD
              << " issuing release for " << *request_address_
              << " * " << *count_ ;
      release_started_ = true;
      RequestArgs args;
      args.request_address = *request_address_;
      DVLOG(5) << "Computing request_bytes from block_max " << request_address_->first_byte().block_max() << " and " << *request_address_;
      args.reply_address = make_global( this );
      size_t offset = 0;
      size_t request_bytes = 0;
      size_t total_bytes = *count_ * sizeof(T);

      // allocate enough requests/messages that we don't run out
      size_t nmsg = total_bytes / block_size + 2;
      RequestArgs arg_array[nmsg];
      Grappa::ExternalPayloadMessage<RequestArgs> msg_array[nmsg];

      for( size_t i = 0;
           offset < total_bytes;
           offset += request_bytes, i++) {

        request_bytes = args.request_address.first_byte().block_max() - args.request_address.first_byte();

        if( request_bytes > total_bytes - offset ) {
          request_bytes = total_bytes - offset;
        }

        DVLOG(5) << "sending release request with " << request_bytes
                 << " of total bytes = " << *count_ * sizeof(T)
                 << " to " << args.request_address;

        arg_array[i] = args;
        new (msg_array+i) Grappa::ExternalPayloadMessage<RequestArgs>(arg_array[i].request_address.node(), &arg_array[i], ((char*)(*pointer_)) + offset, request_bytes);
        msg_array[i].enqueue();
//        Grappa_call_on( args.request_address.node(), &incoherent_release_request_am<T>,
//                         &args, sizeof( args ),
//                         ((char*)(*pointer_)) + offset, request_bytes);

	// TODO: change type so we don't screw with pointer like this
        args.request_address = GlobalAddress<T>::Raw( args.request_address.raw_bits() + request_bytes );
      }
      DVLOG(5) << "release started for " << args.request_address;

      // blocks here waiting for messages to be sent
    }
  }

  void block_until_released() {
    if( !released_ ) {
      start_release();
#ifdef VTRACE_FULL
      VT_TRACER("incoherent block_until_released");
#endif
      DVLOG(5) << "Thread " << CURRENT_THREAD
              << " ready to block on " << *request_address_
              << " * " << *count_ ;
      while( !released_ ) {
        DVLOG(5) << "Thread " << CURRENT_THREAD
                << " blocking on " << *request_address_
                << " * " << *count_ ;
        if( !released_ ) {
          thread_ = CURRENT_THREAD;
          Grappa_suspend();
          thread_ = NULL;
        }
        DVLOG(5) << "Thread " << CURRENT_THREAD
                 << " woke up for " << *request_address_
                 << " * " << *count_ ;
      }
    }
  }

  void release_reply( ) {
    DVLOG(5) << "Thread " << CURRENT_THREAD
             << " received release reply ";
    ++response_count_;
    if ( response_count_ == num_messages_ ) {
      released_ = true;
      if( thread_ != NULL ) {
        DVLOG(5) << "Thread " << CURRENT_THREAD
                 << " waking Thread " << thread_;
        Grappa_wake( thread_ );
      }
    }
  }

  bool released() const { return released_; }

  struct ReplyArgs {
    GlobalAddress< IncoherentReleaser > reply_address;
    void operator()() {
      DVLOG(5) << "Thread " << CURRENT_THREAD << " received release reply to " << reply_address;
      reply_address.pointer()->release_reply( );
    }
  };

  struct RequestArgs {
    GlobalAddress< T > request_address;
    GlobalAddress< IncoherentReleaser > reply_address;

    void operator()(void * payload, size_t payload_size) {
      incoherent_releaser_stats.count_release_ams( payload_size );
      DVLOG(5) << "Thread " << CURRENT_THREAD
      << " received release request to " << request_address
      << " reply to " << reply_address;
      memcpy( request_address.pointer(), payload, payload_size );
      ReplyArgs reply_args;
      reply_args.reply_address = reply_address;

      Grappa::send_heap_message(reply_address.node(), reply_args);

      DVLOG(5) << "Thread " << CURRENT_THREAD
      << " sent release reply to " << reply_address;
    }
  };
};

#endif
<commit_msg>Fix stack overflow in IncoherentReleaser, use new blocking MessagePool.<commit_after>
// Copyright 2010-2012 University of Washington. All Rights Reserved.
// LICENSE_PLACEHOLDER
// This software was created with Government support under DE
// AC05-76RL01830 awarded by the United States Department of
// Energy. The Government has certain rights in the software.

#ifndef __INCOHERENT_RELEASER_HPP__
#define __INCOHERENT_RELEASER_HPP__

#include "Grappa.hpp"
#include "Message.hpp"
#include "MessagePool.hpp"

#ifdef VTRACE
#include <vt_user.h>
#endif

// forward declare for active message templates
template< typename T >
class IncoherentReleaser;

template< typename T >
static void incoherent_release_reply_am( typename IncoherentReleaser< T >::ReplyArgs * args,
                                         size_t size,
                                         void * payload, size_t payload_size );

template< typename T >
static void incoherent_release_request_am( typename IncoherentReleaser< T >::RequestArgs * args,
                                           size_t size,
                                           void * payload, size_t payload_size );

/// Stats for IncoherentReleaser
class IRStatistics {
  private:
    uint64_t release_ams;
    uint64_t release_ams_bytes;
#ifdef VTRACE_SAMPLED
    unsigned ir_grp_vt;
    unsigned release_ams_ev_vt;
    unsigned release_ams_bytes_ev_vt;
#endif

  public:
    IRStatistics();
    void reset();

    inline void count_release_ams( uint64_t bytes ) {
      release_ams++;
      release_ams_bytes+=bytes;
    }

    void dump( std::ostream& o, const char * terminator );
    void sample();
    void profiling_sample();
    void merge(const IRStatistics * other);
};

extern IRStatistics incoherent_releaser_stats;

/// IncoherentReleaser behavior for cache.
template< typename T >
class IncoherentReleaser {
private:
  bool release_started_;
  bool released_;
  GlobalAddress< T > * request_address_;
  size_t * count_;
  T ** pointer_;
  Thread * thread_;
  int num_messages_;
  int response_count_;

public:

  IncoherentReleaser( GlobalAddress< T > * request_address, size_t * count, T ** pointer )
    : request_address_( request_address )
    , count_( count )
    , pointer_( pointer )
    , release_started_( false )
    , released_( false )
    , thread_(NULL)
    , num_messages_(0)
    , response_count_(0)
  {
    reset();
  }

  void reset( ) {
    CHECK( !release_started_ || released_ ) << "inconsistent state for reset";
    release_started_ = false;
    released_ = false;
    thread_ = NULL;
    num_messages_ = 0;
    response_count_ = 0;
    if( *count_ == 0 ) {
      DVLOG(5) << "Zero-length release";
      release_started_ = true;
      released_ = true;
    } else if( request_address_->is_2D() ) {
      num_messages_ = 1;
      if( request_address_->node() == Grappa_mynode() ) {
        release_started_ = true;
        released_ = true;
      }
    } else {
      DVLOG(5) << "Straddle: block_max is " << (*request_address_ + *count_).block_max() ;
      DVLOG(5) << ", request_address is " << *request_address_;
      DVLOG(5) << ", sizeof(T) is " << sizeof(T);
      DVLOG(5) << ", count is " << *count_;
      DVLOG(5) << ", block_min is " << request_address_->block_min();

      DVLOG(5) << "Straddle: address is " << *request_address_ ;
      DVLOG(5) << ", address + count is " << *request_address_ + *count_;

      ptrdiff_t byte_diff = ( (*request_address_ + *count_ - 1).last_byte().block_max() -
                               request_address_->first_byte().block_min() );

      DVLOG(5) << "Straddle: address block max is " << request_address_->block_max();
      DVLOG(5) << " address + count block max is " << (*request_address_ + *count_).block_max();
      DVLOG(5) << " address + count -1 block max is " << (*request_address_ + *count_ - 1).block_max();
      DVLOG(5) << " difference is " << ( (*request_address_ + *count_ - 1).block_max() - request_address_->block_min() );
      DVLOG(5) << " multiplied difference is " << ( (*request_address_ + *count_ - 1).block_max() - request_address_->block_min() ) * sizeof(T);
      DVLOG(5) << " address block min " << request_address_->block_min();
      DVLOG(5) << "Straddle: diff is " << byte_diff << " bs " << block_size;
      num_messages_ = byte_diff / block_size;
    }

    if( num_messages_ > 1 ) DVLOG(5) << "****************************** MULTI BLOCK CACHE REQUEST ******************************";

    DVLOG(5) << "Detecting straddle for sizeof(T):" << sizeof(T)
             << " count:" << *count_
             << " num_messages_:" << num_messages_
             << " request_address:" << *request_address_;
  }

  void start_release() {
    if( !release_started_ ) {
#ifdef VTRACE_FULL
      VT_TRACER("incoherent start_release");
#endif
            DVLOG(5) << "Thread " << CURRENT_THREAD
              << " issuing release for " << *request_address_
              << " * " << *count_ ;
      release_started_ = true;
      RequestArgs args;
      args.request_address = *request_address_;
      DVLOG(5) << "Computing request_bytes from block_max " << request_address_->first_byte().block_max() << " and " << *request_address_;
      args.reply_address = make_global( this );
      size_t offset = 0;
      size_t request_bytes = 0;
      size_t total_bytes = *count_ * sizeof(T);

      // allocate enough requests/messages that we don't run out
      size_t nmsg = total_bytes / block_size + 2;

      Grappa::MessagePoolStatic<STACK_SIZE/2> pool;

      for( size_t i = 0;
           offset < total_bytes;
           offset += request_bytes, i++) {

        request_bytes = args.request_address.first_byte().block_max() - args.request_address.first_byte();

        if( request_bytes > total_bytes - offset ) {
          request_bytes = total_bytes - offset;
        }

        DVLOG(5) << "sending release request with " << request_bytes
                 << " of total bytes = " << *count_ * sizeof(T)
                 << " to " << args.request_address;

        pool.send_message(args.request_address.core(),
          [args](void * payload, size_t payload_size) {
            incoherent_releaser_stats.count_release_ams( payload_size );
            DVLOG(5) << "Thread " << CURRENT_THREAD
            << " received release request to " << args.request_address
            << " reply to " << args.reply_address;
            memcpy( args.request_address.pointer(), payload, payload_size );

            auto reply_address = args.reply_address;
            Grappa::send_heap_message(args.reply_address.core(), [reply_address]{
              DVLOG(5) << "Thread " << CURRENT_THREAD << " received release reply to " << reply_address;
              reply_address.pointer()->release_reply();
            });

            DVLOG(5) << "Thread " << CURRENT_THREAD
            << " sent release reply to " << reply_address;
          },
          (char*)(*pointer_) + offset, request_bytes
        );

      	// TODO: change type so we don't screw with pointer like this
        args.request_address = GlobalAddress<T>::Raw( args.request_address.raw_bits() + request_bytes );
      }
      DVLOG(5) << "release started for " << args.request_address;

      // blocks here waiting for messages to be sent
    }
  }

  void block_until_released() {
    if( !released_ ) {
      start_release();
#ifdef VTRACE_FULL
      VT_TRACER("incoherent block_until_released");
#endif
      DVLOG(5) << "Thread " << CURRENT_THREAD
              << " ready to block on " << *request_address_
              << " * " << *count_ ;
      while( !released_ ) {
        DVLOG(5) << "Thread " << CURRENT_THREAD
                << " blocking on " << *request_address_
                << " * " << *count_ ;
        if( !released_ ) {
          thread_ = CURRENT_THREAD;
          Grappa_suspend();
          thread_ = NULL;
        }
        DVLOG(5) << "Thread " << CURRENT_THREAD
                 << " woke up for " << *request_address_
                 << " * " << *count_ ;
      }
    }
  }

  void release_reply( ) {
    DVLOG(5) << "Thread " << CURRENT_THREAD
             << " received release reply ";
    ++response_count_;
    if ( response_count_ == num_messages_ ) {
      released_ = true;
      if( thread_ != NULL ) {
        DVLOG(5) << "Thread " << CURRENT_THREAD
                 << " waking Thread " << thread_;
        Grappa_wake( thread_ );
      }
    }
  }

  bool released() const { return released_; }

  struct ReplyArgs {
    GlobalAddress< IncoherentReleaser > reply_address;
    void operator()() {
      DVLOG(5) << "Thread " << CURRENT_THREAD << " received release reply to " << reply_address;
      reply_address.pointer()->release_reply( );
    }
  };

  struct RequestArgs {
    GlobalAddress< T > request_address;
    GlobalAddress< IncoherentReleaser > reply_address;

    void operator()(void * payload, size_t payload_size) {
      incoherent_releaser_stats.count_release_ams( payload_size );
      DVLOG(5) << "Thread " << CURRENT_THREAD
      << " received release request to " << request_address
      << " reply to " << reply_address;
      memcpy( request_address.pointer(), payload, payload_size );
      ReplyArgs reply_args;
      reply_args.reply_address = reply_address;

      Grappa::send_heap_message(reply_address.node(), reply_args);

      DVLOG(5) << "Thread " << CURRENT_THREAD
      << " sent release reply to " << reply_address;
    }
  };
};

#endif
<|endoftext|>


<commit_before>//////////////////////////////////////////////////////////////////////////
//
// SneezyMUD - All rights reserved, SneezyMUD Coding Team
//
//////////////////////////////////////////////////////////////////////////

#include <stdio.h>

#include "extern.h"
#include "configuration.h"
#include "statistics.h"
#include "database.h"

extern FILE *obj_f;
extern FILE *mob_f;

std::vector<mobIndexData>mob_index(0);
std::vector<objIndexData>obj_index(0);

indexData::indexData() :
  virt(0),
  pos(0),
  number(0),
  name(NULL),
  short_desc(NULL),
  long_desc(NULL),
  description(NULL),
  max_exist(-99),
  spec(0),
  weight(0)
{
}

indexData & indexData::operator= (const indexData &a)
{
  if (this == &a)
    return *this;

  virt = a.virt;
  pos = a.pos;
  number = a.number;
  delete [] name;
  delete [] short_desc;
  delete [] long_desc;
  delete [] description;
  name = mud_str_dup(a.name);
  short_desc = mud_str_dup(a.short_desc);
  long_desc = mud_str_dup(a.long_desc);
  description = mud_str_dup(a.description);

  max_exist = a.max_exist;
  spec = a.spec;
  weight = a.weight;

  return *this;
}

indexData::indexData(const indexData &a) :
  virt(a.virt),
  pos(a.pos),
  number(a.number),
  max_exist(a.max_exist),
  spec(a.spec),
  weight(a.weight)
{
  name = mud_str_dup(a.name);
  short_desc = mud_str_dup(a.short_desc);
  long_desc = mud_str_dup(a.long_desc);
  description = mud_str_dup(a.description);
}

indexData::~indexData()
{
  delete [] name;
  delete [] short_desc;
  delete [] long_desc;
  delete [] description;
}

mobIndexData::mobIndexData() :
  faction(-99),
  Class(-99),
  level(-99),
  race(-99),
  doesLoad(false),
  numberLoad(0)
{
}

mobIndexData & mobIndexData::operator= (const mobIndexData &a)
{
  if (this == &a)
    return *this;

  indexData::operator=(a);

  faction = a.faction;
  Class = a.Class;
  level = a.level;
  race = a.race;
  doesLoad = a.doesLoad;
  numberLoad = a.numberLoad;

  return *this;
}

mobIndexData::mobIndexData(const mobIndexData &a) :
  indexData(a),
  faction(a.faction),
  Class(a.Class),
  level(a.level),
  race(a.race),
  doesLoad(a.doesLoad),
  numberLoad(a.numberLoad)
{
}

mobIndexData::~mobIndexData()
{
}

objIndexData::objIndexData() :
  ex_description(NULL),
  max_struct(-99),
  armor(-99),
  where_worn(0),
  itemtype(MAX_OBJ_TYPES),
  value(-99)
{
}

objIndexData & objIndexData::operator= (const objIndexData &a)
{
  if (this == &a)
    return *this;

  indexData::operator=(a);

  // use copy operator;
  if (a.ex_description)
    ex_description = new extraDescription(*a.ex_description);
  else
    ex_description = NULL;

  max_struct = a.max_struct;
  armor = a.armor;
  where_worn = a.where_worn;
  itemtype = a.itemtype;
  value = a.value;

  int i;
  for(i=0;i<MAX_OBJ_AFFECT;++i){
    affected[i]=a.affected[i];
  }

  return *this;
}

objIndexData::objIndexData(const objIndexData &a) :
  indexData(a),
  max_struct(a.max_struct),
  armor(a.armor),
  where_worn(a.where_worn),
  itemtype(a.itemtype),
  value(a.value)
{
  // use copy operator;
  if (a.ex_description)
    ex_description = new extraDescription(*a.ex_description);
  else
    ex_description = NULL;

  int i;
  for(i=0;i<MAX_OBJ_AFFECT;++i){
    affected[i]=a.affected[i];
  }
}

objIndexData::~objIndexData()
{
  extraDescription *tmp;
  while ((tmp = ex_description)) {
    ex_description = tmp->next;
    delete tmp;
  }
}

// generate index table for object
void generate_obj_index()
{
  objIndexData *tmpi = NULL;
  extraDescription *new_descr;
  int i=0;

  // to prevent constant resizing (slows boot), declare an appropriate initial
  // size.  Should be smallest power of 2 that will hold everything
  obj_index.reserve(8192);

  /****** extra ******/
  TDatabase extra_db(DB_SNEEZY);
  extra_db.query("select vnum, name, description from objextra order by vnum");
  extra_db.fetchRow();

  /****** affect ******/
  TDatabase affect_db(DB_SNEEZY);
  affect_db.query("select vnum, type, mod1, mod2 from objaffect order by vnum");
  affect_db.fetchRow();

  /********************/

  TDatabase db(DB_SNEEZY);
  db.query("select vnum, name, short_desc, long_desc, max_exist, spec_proc, weight, max_struct, wear_flag, type, price, action_desc from obj order by vnum");

  while(db.fetchRow()){
    tmpi = new objIndexData();
    if (!tmpi) {
      perror("indexData");
      exit(0);
    }

    tmpi->virt=convertTo<int>(db["vnum"]);
    tmpi->name=mud_str_dup(db["name"]);
    tmpi->short_desc=mud_str_dup(db["short_desc"]);
    tmpi->long_desc=mud_str_dup(db["long_desc"]);
    tmpi->max_exist=convertTo<int>(db["max_exist"]);

    // use 327 so we don't go over 32765 in calculation
    if (tmpi->max_exist < 327) {
      tmpi->max_exist *= (short) (stats.max_exist * 100);
      tmpi->max_exist /= 100;
    }
    if (tmpi->max_exist)
      tmpi->max_exist = max(tmpi->max_exist, (short int) 1);

    tmpi->spec=convertTo<int>(db["spec_proc"]);
    tmpi->weight=convertTo<float>(db["weight"]);
    tmpi->max_struct=convertTo<int>(db["max_struct"]);
    tmpi->where_worn=convertTo<int>(db["wear_flag"]);
    tmpi->itemtype=convertTo<int>(db["type"]);
    tmpi->value=convertTo<int>(db["price"]);
    if(!db["action_desc"].empty())
      tmpi->description=mud_str_dup(db["action_desc"]);
    else tmpi->description=NULL;

    while(!extra_db["vnum"].empty() && convertTo<int>(extra_db["vnum"]) < tmpi->virt){
      extra_db.fetchRow();
    }

    while(!extra_db["vnum"].empty() &&
	  convertTo<int>(extra_db["vnum"])==tmpi->virt){
      new_descr = new extraDescription();
      new_descr->keyword = mud_str_dup(extra_db["name"]);
      new_descr->description = mud_str_dup(extra_db["description"]);
      new_descr->next = tmpi->ex_description;
      tmpi->ex_description = new_descr;

      extra_db.fetchRow();
    }

    while(!affect_db["vnum"].empty() &&
	  convertTo<int>(affect_db["vnum"]) < tmpi->virt){
      affect_db.fetchRow();
    }

    i=0;
    while(!affect_db["vnum"].empty() &&
	  convertTo<int>(affect_db["vnum"])==tmpi->virt){
      tmpi->affected[i].location = mapFileToApply(convertTo<int>(affect_db["type"]));

      if (tmpi->affected[i].location == APPLY_SPELL)
	tmpi->affected[i].modifier = mapFileToSpellnum(convertTo<int>(affect_db["mod1"]));
      else
	tmpi->affected[i].modifier = convertTo<int>(affect_db["mod1"]);

      tmpi->affected[i].modifier2 = convertTo<int>(affect_db["mod2"]);
      tmpi->affected[i].type = TYPE_UNDEFINED;
      tmpi->affected[i].level = 0;
      tmpi->affected[i].bitvector = 0;

      affect_db.fetchRow();
      i++;
    }

    obj_index.push_back(*tmpi);
    delete tmpi;
  }
}

// generate index table for monster file
void generate_mob_index()
{
  mobIndexData *tmpi = NULL;
  TDatabase db(DB_SNEEZY);

  // to prevent constant resizing (slows boot), declare an appropriate initial
  // size.  Should be smallest power of 2 that will hold everything
  mob_index.reserve(8192);

  // start by reading
  db.query("select * from mob");

  while(db.fetchRow()){
    if (tmpi) {
      // push the previous one into the stack
      mob_index.push_back(*tmpi);
      delete tmpi;
    }

    // start a new data member
    tmpi = new mobIndexData();
    if (!tmpi) {
      perror("mobIndexData");
      exit(0);
    }

    tmpi->virt = convertTo<int>(db["vnum"]);

    // read the sstrings
    tmpi->name = mud_str_dup(db["name"]);
    tmpi->short_desc = mud_str_dup(db["short_desc"]);
    tmpi->long_desc = mud_str_dup(db["long_desc"]);
    tmpi->description = mud_str_dup(db["description"]);

    long fac=convertTo<int>(db["faction"]);

    tmpi->faction = fac;

    long Class=convertTo<int>(db["class"]);
    float arm=convertTo<int>(db["ac"]);
    float hp=convertTo<int>(db["hpbonus"]);
    float daml=convertTo<int>(db["damage_level"]);

    long lev = (long)((arm + hp + daml) / 3);

    tmpi->Class = Class;
    tmpi->level = lev;

    long race=convertTo<int>(db["race"]);
    long wgt=convertTo<int>(db["weight"]);

    tmpi->race = race;
    tmpi->weight = wgt;

    long spec=convertTo<int>(db["spec_proc"]);

    tmpi->spec = spec;

    long maxe=convertTo<int>(db["max_exist"]);

    tmpi->max_exist = maxe;

    // handle some stat counters
    if (lev <= 5) {
      stats.mobs_1_5++;
    } else if (lev <= 10) {
      stats.mobs_6_10++;
    } else if (lev <= 15) {
      stats.mobs_11_15++;
    } else if (lev <= 20) {
      stats.mobs_16_20++;
    } else if (lev <= 25) {
      stats.mobs_21_25++;
    } else if (lev <= 30) {
      stats.mobs_26_30++;
    } else if (lev <= 40) {
      stats.mobs_31_40++;
    } else if (lev <= 50) {
      stats.mobs_41_50++;
    } else if (lev <= 60) {
      stats.mobs_51_60++;
    } else if (lev <= 70) {
      stats.mobs_61_70++;
    } else if (lev <= 100) {
      stats.mobs_71_100++;
    } else {
      stats.mobs_101_127++;
    }
    // end stat counters
  }
  // and push the last one into the stack
  // ... if it exists, ie. we have at least one mob.
  if (tmpi) {
    mob_index.push_back(*tmpi);
    delete tmpi;
  }
}
<commit_msg>Fixed ctags not finding mob_index<commit_after>//////////////////////////////////////////////////////////////////////////
//
// SneezyMUD - All rights reserved, SneezyMUD Coding Team
//
//////////////////////////////////////////////////////////////////////////

#include <stdio.h>

#include "extern.h"
#include "configuration.h"
#include "statistics.h"
#include "database.h"

extern FILE *obj_f;
extern FILE *mob_f;

std::vector<mobIndexData> mob_index;
std::vector<objIndexData> obj_index;

indexData::indexData() :
  virt(0),
  pos(0),
  number(0),
  name(NULL),
  short_desc(NULL),
  long_desc(NULL),
  description(NULL),
  max_exist(-99),
  spec(0),
  weight(0)
{
}

indexData & indexData::operator= (const indexData &a)
{
  if (this == &a)
    return *this;

  virt = a.virt;
  pos = a.pos;
  number = a.number;
  delete [] name;
  delete [] short_desc;
  delete [] long_desc;
  delete [] description;
  name = mud_str_dup(a.name);
  short_desc = mud_str_dup(a.short_desc);
  long_desc = mud_str_dup(a.long_desc);
  description = mud_str_dup(a.description);

  max_exist = a.max_exist;
  spec = a.spec;
  weight = a.weight;

  return *this;
}

indexData::indexData(const indexData &a) :
  virt(a.virt),
  pos(a.pos),
  number(a.number),
  max_exist(a.max_exist),
  spec(a.spec),
  weight(a.weight)
{
  name = mud_str_dup(a.name);
  short_desc = mud_str_dup(a.short_desc);
  long_desc = mud_str_dup(a.long_desc);
  description = mud_str_dup(a.description);
}

indexData::~indexData()
{
  delete [] name;
  delete [] short_desc;
  delete [] long_desc;
  delete [] description;
}

mobIndexData::mobIndexData() :
  faction(-99),
  Class(-99),
  level(-99),
  race(-99),
  doesLoad(false),
  numberLoad(0)
{
}

mobIndexData & mobIndexData::operator= (const mobIndexData &a)
{
  if (this == &a)
    return *this;

  indexData::operator=(a);

  faction = a.faction;
  Class = a.Class;
  level = a.level;
  race = a.race;
  doesLoad = a.doesLoad;
  numberLoad = a.numberLoad;

  return *this;
}

mobIndexData::mobIndexData(const mobIndexData &a) :
  indexData(a),
  faction(a.faction),
  Class(a.Class),
  level(a.level),
  race(a.race),
  doesLoad(a.doesLoad),
  numberLoad(a.numberLoad)
{
}

mobIndexData::~mobIndexData()
{
}

objIndexData::objIndexData() :
  ex_description(NULL),
  max_struct(-99),
  armor(-99),
  where_worn(0),
  itemtype(MAX_OBJ_TYPES),
  value(-99)
{
}

objIndexData & objIndexData::operator= (const objIndexData &a)
{
  if (this == &a)
    return *this;

  indexData::operator=(a);

  // use copy operator;
  if (a.ex_description)
    ex_description = new extraDescription(*a.ex_description);
  else
    ex_description = NULL;

  max_struct = a.max_struct;
  armor = a.armor;
  where_worn = a.where_worn;
  itemtype = a.itemtype;
  value = a.value;

  int i;
  for(i=0;i<MAX_OBJ_AFFECT;++i){
    affected[i]=a.affected[i];
  }

  return *this;
}

objIndexData::objIndexData(const objIndexData &a) :
  indexData(a),
  max_struct(a.max_struct),
  armor(a.armor),
  where_worn(a.where_worn),
  itemtype(a.itemtype),
  value(a.value)
{
  // use copy operator;
  if (a.ex_description)
    ex_description = new extraDescription(*a.ex_description);
  else
    ex_description = NULL;

  int i;
  for(i=0;i<MAX_OBJ_AFFECT;++i){
    affected[i]=a.affected[i];
  }
}

objIndexData::~objIndexData()
{
  extraDescription *tmp;
  while ((tmp = ex_description)) {
    ex_description = tmp->next;
    delete tmp;
  }
}

// generate index table for object
void generate_obj_index()
{
  objIndexData *tmpi = NULL;
  extraDescription *new_descr;
  int i=0;

  // to prevent constant resizing (slows boot), declare an appropriate initial
  // size.  Should be smallest power of 2 that will hold everything
  obj_index.reserve(8192);

  /****** extra ******/
  TDatabase extra_db(DB_SNEEZY);
  extra_db.query("select vnum, name, description from objextra order by vnum");
  extra_db.fetchRow();

  /****** affect ******/
  TDatabase affect_db(DB_SNEEZY);
  affect_db.query("select vnum, type, mod1, mod2 from objaffect order by vnum");
  affect_db.fetchRow();

  /********************/

  TDatabase db(DB_SNEEZY);
  db.query("select vnum, name, short_desc, long_desc, max_exist, spec_proc, weight, max_struct, wear_flag, type, price, action_desc from obj order by vnum");

  while(db.fetchRow()){
    tmpi = new objIndexData();
    if (!tmpi) {
      perror("indexData");
      exit(0);
    }

    tmpi->virt=convertTo<int>(db["vnum"]);
    tmpi->name=mud_str_dup(db["name"]);
    tmpi->short_desc=mud_str_dup(db["short_desc"]);
    tmpi->long_desc=mud_str_dup(db["long_desc"]);
    tmpi->max_exist=convertTo<int>(db["max_exist"]);

    // use 327 so we don't go over 32765 in calculation
    if (tmpi->max_exist < 327) {
      tmpi->max_exist *= (short) (stats.max_exist * 100);
      tmpi->max_exist /= 100;
    }
    if (tmpi->max_exist)
      tmpi->max_exist = max(tmpi->max_exist, (short int) 1);

    tmpi->spec=convertTo<int>(db["spec_proc"]);
    tmpi->weight=convertTo<float>(db["weight"]);
    tmpi->max_struct=convertTo<int>(db["max_struct"]);
    tmpi->where_worn=convertTo<int>(db["wear_flag"]);
    tmpi->itemtype=convertTo<int>(db["type"]);
    tmpi->value=convertTo<int>(db["price"]);
    if(!db["action_desc"].empty())
      tmpi->description=mud_str_dup(db["action_desc"]);
    else tmpi->description=NULL;

    while(!extra_db["vnum"].empty() && convertTo<int>(extra_db["vnum"]) < tmpi->virt){
      extra_db.fetchRow();
    }

    while(!extra_db["vnum"].empty() &&
	  convertTo<int>(extra_db["vnum"])==tmpi->virt){
      new_descr = new extraDescription();
      new_descr->keyword = mud_str_dup(extra_db["name"]);
      new_descr->description = mud_str_dup(extra_db["description"]);
      new_descr->next = tmpi->ex_description;
      tmpi->ex_description = new_descr;

      extra_db.fetchRow();
    }

    while(!affect_db["vnum"].empty() &&
	  convertTo<int>(affect_db["vnum"]) < tmpi->virt){
      affect_db.fetchRow();
    }

    i=0;
    while(!affect_db["vnum"].empty() &&
	  convertTo<int>(affect_db["vnum"])==tmpi->virt){
      tmpi->affected[i].location = mapFileToApply(convertTo<int>(affect_db["type"]));

      if (tmpi->affected[i].location == APPLY_SPELL)
	tmpi->affected[i].modifier = mapFileToSpellnum(convertTo<int>(affect_db["mod1"]));
      else
	tmpi->affected[i].modifier = convertTo<int>(affect_db["mod1"]);

      tmpi->affected[i].modifier2 = convertTo<int>(affect_db["mod2"]);
      tmpi->affected[i].type = TYPE_UNDEFINED;
      tmpi->affected[i].level = 0;
      tmpi->affected[i].bitvector = 0;

      affect_db.fetchRow();
      i++;
    }

    obj_index.push_back(*tmpi);
    delete tmpi;
  }
}

// generate index table for monster file
void generate_mob_index()
{
  mobIndexData *tmpi = NULL;
  TDatabase db(DB_SNEEZY);

  // to prevent constant resizing (slows boot), declare an appropriate initial
  // size.  Should be smallest power of 2 that will hold everything
  mob_index.reserve(8192);

  // start by reading
  db.query("select * from mob");

  while(db.fetchRow()){
    if (tmpi) {
      // push the previous one into the stack
      mob_index.push_back(*tmpi);
      delete tmpi;
    }

    // start a new data member
    tmpi = new mobIndexData();
    if (!tmpi) {
      perror("mobIndexData");
      exit(0);
    }

    tmpi->virt = convertTo<int>(db["vnum"]);

    // read the sstrings
    tmpi->name = mud_str_dup(db["name"]);
    tmpi->short_desc = mud_str_dup(db["short_desc"]);
    tmpi->long_desc = mud_str_dup(db["long_desc"]);
    tmpi->description = mud_str_dup(db["description"]);

    long fac=convertTo<int>(db["faction"]);

    tmpi->faction = fac;

    long Class=convertTo<int>(db["class"]);
    float arm=convertTo<int>(db["ac"]);
    float hp=convertTo<int>(db["hpbonus"]);
    float daml=convertTo<int>(db["damage_level"]);

    long lev = (long)((arm + hp + daml) / 3);

    tmpi->Class = Class;
    tmpi->level = lev;

    long race=convertTo<int>(db["race"]);
    long wgt=convertTo<int>(db["weight"]);

    tmpi->race = race;
    tmpi->weight = wgt;

    long spec=convertTo<int>(db["spec_proc"]);

    tmpi->spec = spec;

    long maxe=convertTo<int>(db["max_exist"]);

    tmpi->max_exist = maxe;

    // handle some stat counters
    if (lev <= 5) {
      stats.mobs_1_5++;
    } else if (lev <= 10) {
      stats.mobs_6_10++;
    } else if (lev <= 15) {
      stats.mobs_11_15++;
    } else if (lev <= 20) {
      stats.mobs_16_20++;
    } else if (lev <= 25) {
      stats.mobs_21_25++;
    } else if (lev <= 30) {
      stats.mobs_26_30++;
    } else if (lev <= 40) {
      stats.mobs_31_40++;
    } else if (lev <= 50) {
      stats.mobs_41_50++;
    } else if (lev <= 60) {
      stats.mobs_51_60++;
    } else if (lev <= 70) {
      stats.mobs_61_70++;
    } else if (lev <= 100) {
      stats.mobs_71_100++;
    } else {
      stats.mobs_101_127++;
    }
    // end stat counters
  }
  // and push the last one into the stack
  // ... if it exists, ie. we have at least one mob.
  if (tmpi) {
    mob_index.push_back(*tmpi);
    delete tmpi;
  }
}
<|endoftext|>


<commit_before>/*
 * Copyright (C) 2008, 2009 Nokia Corporation.
 *
 * Contact: Marius Vollmer <marius.vollmer@nokia.com>
 *
 * 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., 51 Franklin St, Fifth Floor, Boston, MA
 * 02110-1301 USA
 *
 */

#include "provider.h"
#include "iproviderplugin.h"
#include "handlesignalrouter.h"
#include "sconnect.h"
#include "contextkitplugin.h"
#include "logging.h"
#include "loggingfeatures.h"
#include <QTimer>
#include <QMutexLocker>
#include <QCoreApplication>
#include <QThread>
#include <QLibrary>

namespace ContextSubscriber {

/*!
  \class IProviderPlugin
  \brief Interface for provider plugins.

  Note: this interface is private, currently it is not advised to use
  it and create ContextKit subscriber plugins on your own, we can and
  will change this interface anytime in the future even between small
  bugfix releases.

  Every Provider instance contains exactly one plugin (pointer) with
  this interface which is constructed on initialization time and never
  change after that.  This way the concrete protocol (dbus, shared
  memory, etc.) between the library and the provider is abstracted.

  The Provider instance communicates need for subscribe and
  unsubscribe calls (on the wire) using the \c subscribe and \c
  unsubscribe methods.

  The plugin can fail or became ready anytime because of things
  happening on the wire inside the plugin (socket closed, dbus service
  appears/disappears).  Whenever the plugin has new information about
  this it should emit the signal \c ready or \c failed accordingly.

  When the plugin is ready, it has to be able to handle \c subscribe
  and \c unsubscribe function calls.  Also, after emitting \c ready it
  should be in a state where it is not subscribed to anything on the
  wire, since immediately after \c ready is emitted, the provider will
  place a subscribe call with all of the properties that should be
  subscribed.

  Subscription failures or successes can be signaled with emitting \c
  subscribeFailed and \c subscribeFinished.

  At last, but not least, the plugin can emit \c valueChanged, when it
  has a new value for any property.  It is not required to only signal
  new values, the library takes care of keeping the old value and only
  emit change signals to the upper layers if the new value is really
  new.

  An implementation of this interface doesn't have to care about
  threads at all, all of the methods, starting from the constructor
  will be only called from inside the Qt event loop of the main
  thread.  This means that neither the constructor nor the \c
  subscribe, \c unsubscribe calls should block.  They have to finish
  as soon as possible and signal the results later via signals.

  \class Provider
  \brief Connects to a group of properties via the help of a plugin.

  Each instance of this class keeps a plugin dependent communication
  channel (DBus, shared memory, etc.) open and handles subscriptions,
  value changes of the properties belonging to the provider on the
  other end of the channel.

  This class is thread safe, the \c instance, \c subscribe and \c
  unsubscribe methods can be called from any threads.  However this
  class also guarantees that the signal \c subscribeFinished and \c
  valueChanged will be always emitted from inside the main thread's
  main loop.

  \fn void Provider::subscribeFinished(QSet<QString> keys)
  \brief Emitted when the subscription procedure for \c keys finished
  (either succeeded, either failed) */

/// Stores the passed plugin name and construction paramater, then
/// moves into the main thread and queues a constructPlugin call.
Provider::Provider(const QString &plugin, const QString &constructionString)
    : plugin(0), pluginState(INITIALIZING), pluginName(plugin), constructionString(constructionString)
{
    // Move the PropertyHandle (and all children) to main thread.
    moveToThread(QCoreApplication::instance()->thread());

    queueOnce("constructPlugin");
}

/// Decides which plugin to instantiate based on the \c plugin passed
/// to the constructor.  Always called in the main loop after the
/// constructor is finished.  Each plugin library implements a
/// function which can create new instances of that plugin (TODO: come
/// up with the name of the function).
void Provider::constructPlugin()
{
    contextDebug() << F_PLUGINS;
    if (pluginName == "contextkit-dbus") {
        plugin = contextKitPluginFactory(constructionString);
    }
    else if (pluginName.startsWith("/")) { // Require the plugin name to start with /
        // Enable overriding the plugin location with an environment variable
        const char *pluginPath = getenv("CONTEXT_SUBSCRIBER_PLUGINS");
        if (! pluginPath)
            pluginPath = DEFAULT_CONTEXT_SUBSCRIBER_PLUGINS;

        QString pluginFilename(pluginPath);
        // Allow pluginPath to have a trailing / or not
        if (pluginFilename.endsWith("/")) {
            pluginFilename.chop(1);
        }

        pluginFilename.append(pluginName);

        QLibrary library(pluginFilename);
        library.load();

        if (library.isLoaded()) {
            PluginFactoryFunc factory = (PluginFactoryFunc) library.resolve("pluginFactory");
            if (factory) {
                contextDebug() << "Resolved factory function";
                plugin = factory(constructionString);
            } else {
                contextCritical() << "Error resolving function pluginFactory from plugin" << pluginFilename;
            }
        }
        else {
            contextCritical() << "Error loading plugin" << pluginFilename << ":" << library.errorString();
        }
    }
    else {
        contextCritical() << "Illegal plugin name" << pluginName << ", doesn't start with /";
    }

    if (plugin == 0) {
        pluginState = FAILED;
        handleSubscribes();
        return;
    }

    // Connect the signal of changing values to the class who handles it
    HandleSignalRouter* handleSignalRouter = HandleSignalRouter::instance();
    sconnect(plugin, SIGNAL(valueChanged(QString, QVariant)),
             this, SLOT(onPluginValueChanged(QString, QVariant)));
    sconnect(this, SIGNAL(valueChanged(QString, QVariant)),
             handleSignalRouter, SLOT(onValueChanged(QString, QVariant)));

    sconnect(plugin, SIGNAL(ready()),
             this, SLOT(onPluginReady()));
    sconnect(plugin, SIGNAL(failed(QString)),
             this, SLOT(onPluginFailed(QString)));

    sconnect(plugin, SIGNAL(subscribeFinished(QString)),
             this, SLOT(onPluginSubscribeFinished(QString)), Qt::QueuedConnection);
    sconnect(plugin, SIGNAL(subscribeFailed(QString, QString)),
             this, SLOT(onPluginSubscribeFailed(QString, QString)), Qt::QueuedConnection);
    sconnect(this, SIGNAL(subscribeFinished(QString)),
             handleSignalRouter, SLOT(onSubscribeFinished(QString)));
}

/// Updates \c pluginState to \c READY and requests subscription for
/// the keys that should be subscribed.
void Provider::onPluginReady()
{
    contextDebug();

    QMutexLocker lock(&subscribeLock);
    // Renew the subscriptions (if any).
    // Renewing happens when a provider has disappeared and now it appeared again.
    toUnsubscribe.clear();
    toSubscribe.clear();
    toSubscribe += subscribedKeys;
    pluginState = READY;
    lock.unlock();
    handleSubscribes();
}

/// Updates \c pluginState to \c FAILED and signals subscribeFinished
/// for keys we are trying to subscribe to.
void Provider::onPluginFailed(QString error)
{
    contextWarning() << error;

    QMutexLocker lock(&subscribeLock);
    pluginState = FAILED;
    lock.unlock();
    handleSubscribes();
}

/// The plugin has finished subscribing to a key, signals this fact to
/// the upper layer.  The final API for this is the
/// <tt>waitForSubscription()</tt> method in \c ContextProperty.
void Provider::signalSubscribeFinished(QString key)
{
    QMutexLocker lock(&subscribeLock);
    if (subscribedKeys.contains(key))
        emit subscribeFinished(key);
}

/// Forwards the call to \c signalSubscribeFinished.
void Provider::onPluginSubscribeFinished(QString key)
{
    contextDebug() << key;

    signalSubscribeFinished(key);
}

/// Forwards the call to \c signalSubscribeFinished, after logging a
/// warning.
void Provider::onPluginSubscribeFailed(QString key, QString error)
{
    contextWarning() << key << error;

    signalSubscribeFinished(key);
}

/// Schedules a property to be subscribed to.  Returns true if and
/// only if the main loop has to run for the subscription to be
/// finalized.
bool Provider::subscribe(const QString &key)
{
    contextDebug() << "plugin" << pluginName << constructionString;

    QMutexLocker lock(&subscribeLock);
    // Note: the intention is saved in all cases; whether we can really subscribe or not.
    subscribedKeys.insert(key);

    // If the key was scheduled to be unsubscribed then remove that
    // scheduling, and return false.
    if (toUnsubscribe.contains(key)) {
        toUnsubscribe.remove(key);
        return false;
    }

    // Schedule the key to be subscribed to and return true
    contextDebug() << "Inserting the key to toSubscribe" << QThread::currentThread();

    // Really schedule the key to be subscribed to
    toSubscribe.insert(key);

    queueOnce("handleSubscribes");

    return true;
}

/// Schedules a property to be unsubscribed from when the main loop is
/// entered the next time.
void Provider::unsubscribe(const QString &key)
{
    contextDebug() << "Provider::unsubscribe, plugin" << pluginName << constructionString;

    QMutexLocker lock(&subscribeLock);
    // Save the intention of the higher level
    subscribedKeys.remove(key);

    // Schedule the key to be unsubscribed from
    if (toSubscribe.contains(key)) {
        // The key was scheduled to be subscribed
        // Remove that scheduling, and nothing else needs to be done.
        toSubscribe.remove(key);
    }
    else {
        // Really schedule the key to be unsubscribed from
        toUnsubscribe.insert(key);

        queueOnce("handleSubscribes");
    }
}

/// Executed when the main loop is entered and we have previously
/// scheduled subscriptions / unsubscriptions.
void Provider::handleSubscribes()
{
    contextDebug() << "Provider::handleSubscribes in thread" << QThread::currentThread();

    QMutexLocker lock(&subscribeLock);

    switch (pluginState) {
    case READY:
        if (toSubscribe.size() > 0) plugin->subscribe(toSubscribe);
        if (toUnsubscribe.size() > 0) plugin->unsubscribe(toUnsubscribe);
        toSubscribe.clear();
        toUnsubscribe.clear();
        break;
    case FAILED:
        // it failed for good.
        contextDebug() << "Plugin init has failed";
        if (toSubscribe.size() > 0)
            foreach (QString key, toSubscribe)
                emit subscribeFinished(key);
        toSubscribe.clear();
        toUnsubscribe.clear();
        break;
    case INITIALIZING:
        // we just have to wait,
        break;
    }

    contextDebug() << "Provider::handleSubscribes processed";
}

/// Forwards the \c newValue for \c key received from the plugin to
/// the upper layers via \c HandleSignalRouter.
void Provider::onPluginValueChanged(QString key, QVariant newValue)
{
    QMutexLocker lock(&subscribeLock);
    if (subscribedKeys.contains(key))
        emit valueChanged(key, newValue);
    else
        contextWarning() << "Received a property not subscribed to:" << key;
}

/// Returns a singleton for the named \c plugin with the \c constructionString.
Provider* Provider::instance(const QString& plugin, const QString& constructionString)
{
    // Singleton instance container
    // plugin path, constructionstring -> Provider
    static QMap<QPair<QString, QString>, Provider*> providerInstances;
    QPair<QString, QString> lookupValue(plugin, constructionString);

    static QMutex providerInstancesLock;
    QMutexLocker locker(&providerInstancesLock);
    if (!providerInstances.contains(lookupValue))
        providerInstances.insert(lookupValue, new Provider(plugin, constructionString));

    contextDebug() << "Returning provider instance for" << plugin << ":" << constructionString;

    return providerInstances[lookupValue];
}

} // end namespace
<commit_msg>libcontextsubscriber documentation: Small clarification to the plugin documentation.<commit_after>/*
 * Copyright (C) 2008, 2009 Nokia Corporation.
 *
 * Contact: Marius Vollmer <marius.vollmer@nokia.com>
 *
 * 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., 51 Franklin St, Fifth Floor, Boston, MA
 * 02110-1301 USA
 *
 */

#include "provider.h"
#include "iproviderplugin.h"
#include "handlesignalrouter.h"
#include "sconnect.h"
#include "contextkitplugin.h"
#include "logging.h"
#include "loggingfeatures.h"
#include <QTimer>
#include <QMutexLocker>
#include <QCoreApplication>
#include <QThread>
#include <QLibrary>

namespace ContextSubscriber {

/*!
  \class IProviderPlugin
  \brief Interface for provider plugins.

  Note: this interface is private, currently it is not advised to use
  it and create ContextKit subscriber plugins on your own, we can and
  will change this interface anytime in the future even between small
  bugfix releases.

  Every Provider instance contains exactly one plugin (pointer) with
  this interface which is constructed on initialization time and never
  change after that.  This way the concrete protocol (dbus, shared
  memory, etc.) between the library and the provider is abstracted.

  The Provider instance communicates need for subscribe and
  unsubscribe calls (on the wire) using the \c subscribe and \c
  unsubscribe methods.

  When the plugin is constructed, it should emit the signal ready()
  when it is ready to take in subscriptions. However, the signal
  ready() should not be emitted in the plugin constructor. If the
  plugin is able to take in subscriptions immediately, you can use
  QMetaObject::invokeMethod with QueuedConnection to emit the signal
  when the main loop is entered the next time.

  The plugin can fail or became ready again anytime because of things
  happening on the wire inside the plugin (socket closed, dbus service
  appears/disappears).  Whenever the plugin has new information about
  this it should emit the signal \c ready or \c failed accordingly.

  When the plugin is ready, it has to be able to handle \c subscribe
  and \c unsubscribe function calls.  Also, after emitting \c ready it
  should be in a state where it is not subscribed to anything on the
  wire, since immediately after \c ready is emitted, the provider will
  place a subscribe call with all of the properties that should be
  subscribed.

  Subscription failures or successes can be signaled with emitting \c
  subscribeFailed and \c subscribeFinished.

  At last, but not least, the plugin can emit \c valueChanged, when it
  has a new value for any property.  It is not required to only signal
  new values, the library takes care of keeping the old value and only
  emit change signals to the upper layers if the new value is really
  new.

  An implementation of this interface doesn't have to care about
  threads at all, all of the methods, starting from the constructor
  will be only called from inside the Qt event loop of the main
  thread.  This means that neither the constructor nor the \c
  subscribe, \c unsubscribe calls should block.  They have to finish
  as soon as possible and signal the results later via signals.

  \class Provider
  \brief Connects to a group of properties via the help of a plugin.

  Each instance of this class keeps a plugin dependent communication
  channel (DBus, shared memory, etc.) open and handles subscriptions,
  value changes of the properties belonging to the provider on the
  other end of the channel.

  This class is thread safe, the \c instance, \c subscribe and \c
  unsubscribe methods can be called from any threads.  However this
  class also guarantees that the signal \c subscribeFinished and \c
  valueChanged will be always emitted from inside the main thread's
  main loop.

  \fn void Provider::subscribeFinished(QSet<QString> keys)
  \brief Emitted when the subscription procedure for \c keys finished
  (either succeeded, either failed) */

/// Stores the passed plugin name and construction paramater, then
/// moves into the main thread and queues a constructPlugin call.
Provider::Provider(const QString &plugin, const QString &constructionString)
    : plugin(0), pluginState(INITIALIZING), pluginName(plugin), constructionString(constructionString)
{
    // Move the PropertyHandle (and all children) to main thread.
    moveToThread(QCoreApplication::instance()->thread());

    queueOnce("constructPlugin");
}

/// Decides which plugin to instantiate based on the \c plugin passed
/// to the constructor.  Always called in the main loop after the
/// constructor is finished.  Each plugin library implements a
/// function which can create new instances of that plugin (TODO: come
/// up with the name of the function).
void Provider::constructPlugin()
{
    contextDebug() << F_PLUGINS;
    if (pluginName == "contextkit-dbus") {
        plugin = contextKitPluginFactory(constructionString);
    }
    else if (pluginName.startsWith("/")) { // Require the plugin name to start with /
        // Enable overriding the plugin location with an environment variable
        const char *pluginPath = getenv("CONTEXT_SUBSCRIBER_PLUGINS");
        if (! pluginPath)
            pluginPath = DEFAULT_CONTEXT_SUBSCRIBER_PLUGINS;

        QString pluginFilename(pluginPath);
        // Allow pluginPath to have a trailing / or not
        if (pluginFilename.endsWith("/")) {
            pluginFilename.chop(1);
        }

        pluginFilename.append(pluginName);

        QLibrary library(pluginFilename);
        library.load();

        if (library.isLoaded()) {
            PluginFactoryFunc factory = (PluginFactoryFunc) library.resolve("pluginFactory");
            if (factory) {
                contextDebug() << "Resolved factory function";
                plugin = factory(constructionString);
            } else {
                contextCritical() << "Error resolving function pluginFactory from plugin" << pluginFilename;
            }
        }
        else {
            contextCritical() << "Error loading plugin" << pluginFilename << ":" << library.errorString();
        }
    }
    else {
        contextCritical() << "Illegal plugin name" << pluginName << ", doesn't start with /";
    }

    if (plugin == 0) {
        pluginState = FAILED;
        handleSubscribes();
        return;
    }

    // Connect the signal of changing values to the class who handles it
    HandleSignalRouter* handleSignalRouter = HandleSignalRouter::instance();
    sconnect(plugin, SIGNAL(valueChanged(QString, QVariant)),
             this, SLOT(onPluginValueChanged(QString, QVariant)));
    sconnect(this, SIGNAL(valueChanged(QString, QVariant)),
             handleSignalRouter, SLOT(onValueChanged(QString, QVariant)));

    sconnect(plugin, SIGNAL(ready()),
             this, SLOT(onPluginReady()));
    sconnect(plugin, SIGNAL(failed(QString)),
             this, SLOT(onPluginFailed(QString)));

    sconnect(plugin, SIGNAL(subscribeFinished(QString)),
             this, SLOT(onPluginSubscribeFinished(QString)), Qt::QueuedConnection);
    sconnect(plugin, SIGNAL(subscribeFailed(QString, QString)),
             this, SLOT(onPluginSubscribeFailed(QString, QString)), Qt::QueuedConnection);
    sconnect(this, SIGNAL(subscribeFinished(QString)),
             handleSignalRouter, SLOT(onSubscribeFinished(QString)));
}

/// Updates \c pluginState to \c READY and requests subscription for
/// the keys that should be subscribed.
void Provider::onPluginReady()
{
    contextDebug();

    QMutexLocker lock(&subscribeLock);
    // Renew the subscriptions (if any).
    // Renewing happens when a provider has disappeared and now it appeared again.
    toUnsubscribe.clear();
    toSubscribe.clear();
    toSubscribe += subscribedKeys;
    pluginState = READY;
    lock.unlock();
    handleSubscribes();
}

/// Updates \c pluginState to \c FAILED and signals subscribeFinished
/// for keys we are trying to subscribe to.
void Provider::onPluginFailed(QString error)
{
    contextWarning() << error;

    QMutexLocker lock(&subscribeLock);
    pluginState = FAILED;
    lock.unlock();
    handleSubscribes();
}

/// The plugin has finished subscribing to a key, signals this fact to
/// the upper layer.  The final API for this is the
/// <tt>waitForSubscription()</tt> method in \c ContextProperty.
void Provider::signalSubscribeFinished(QString key)
{
    QMutexLocker lock(&subscribeLock);
    if (subscribedKeys.contains(key))
        emit subscribeFinished(key);
}

/// Forwards the call to \c signalSubscribeFinished.
void Provider::onPluginSubscribeFinished(QString key)
{
    contextDebug() << key;

    signalSubscribeFinished(key);
}

/// Forwards the call to \c signalSubscribeFinished, after logging a
/// warning.
void Provider::onPluginSubscribeFailed(QString key, QString error)
{
    contextWarning() << key << error;

    signalSubscribeFinished(key);
}

/// Schedules a property to be subscribed to.  Returns true if and
/// only if the main loop has to run for the subscription to be
/// finalized.
bool Provider::subscribe(const QString &key)
{
    contextDebug() << "plugin" << pluginName << constructionString;

    QMutexLocker lock(&subscribeLock);
    // Note: the intention is saved in all cases; whether we can really subscribe or not.
    subscribedKeys.insert(key);

    // If the key was scheduled to be unsubscribed then remove that
    // scheduling, and return false.
    if (toUnsubscribe.contains(key)) {
        toUnsubscribe.remove(key);
        return false;
    }

    // Schedule the key to be subscribed to and return true
    contextDebug() << "Inserting the key to toSubscribe" << QThread::currentThread();

    // Really schedule the key to be subscribed to
    toSubscribe.insert(key);

    queueOnce("handleSubscribes");

    return true;
}

/// Schedules a property to be unsubscribed from when the main loop is
/// entered the next time.
void Provider::unsubscribe(const QString &key)
{
    contextDebug() << "Provider::unsubscribe, plugin" << pluginName << constructionString;

    QMutexLocker lock(&subscribeLock);
    // Save the intention of the higher level
    subscribedKeys.remove(key);

    // Schedule the key to be unsubscribed from
    if (toSubscribe.contains(key)) {
        // The key was scheduled to be subscribed
        // Remove that scheduling, and nothing else needs to be done.
        toSubscribe.remove(key);
    }
    else {
        // Really schedule the key to be unsubscribed from
        toUnsubscribe.insert(key);

        queueOnce("handleSubscribes");
    }
}

/// Executed when the main loop is entered and we have previously
/// scheduled subscriptions / unsubscriptions.
void Provider::handleSubscribes()
{
    contextDebug() << "Provider::handleSubscribes in thread" << QThread::currentThread();

    QMutexLocker lock(&subscribeLock);

    switch (pluginState) {
    case READY:
        if (toSubscribe.size() > 0) plugin->subscribe(toSubscribe);
        if (toUnsubscribe.size() > 0) plugin->unsubscribe(toUnsubscribe);
        toSubscribe.clear();
        toUnsubscribe.clear();
        break;
    case FAILED:
        // it failed for good.
        contextDebug() << "Plugin init has failed";
        if (toSubscribe.size() > 0)
            foreach (QString key, toSubscribe)
                emit subscribeFinished(key);
        toSubscribe.clear();
        toUnsubscribe.clear();
        break;
    case INITIALIZING:
        // we just have to wait,
        break;
    }

    contextDebug() << "Provider::handleSubscribes processed";
}

/// Forwards the \c newValue for \c key received from the plugin to
/// the upper layers via \c HandleSignalRouter.
void Provider::onPluginValueChanged(QString key, QVariant newValue)
{
    QMutexLocker lock(&subscribeLock);
    if (subscribedKeys.contains(key))
        emit valueChanged(key, newValue);
    else
        contextWarning() << "Received a property not subscribed to:" << key;
}

/// Returns a singleton for the named \c plugin with the \c constructionString.
Provider* Provider::instance(const QString& plugin, const QString& constructionString)
{
    // Singleton instance container
    // plugin path, constructionstring -> Provider
    static QMap<QPair<QString, QString>, Provider*> providerInstances;
    QPair<QString, QString> lookupValue(plugin, constructionString);

    static QMutex providerInstancesLock;
    QMutexLocker locker(&providerInstancesLock);
    if (!providerInstances.contains(lookupValue))
        providerInstances.insert(lookupValue, new Provider(plugin, constructionString));

    contextDebug() << "Returning provider instance for" << plugin << ":" << constructionString;

    return providerInstances[lookupValue];
}

} // end namespace
<|endoftext|>


<commit_before>/*
    kopeteemoticons.cpp - Kopete Preferences Container-Class

    Copyright (c) 2002      by Stefan Gehn            <sgehn@gmx.net>
    Copyright (c) 2002      by Olivier Goffart        <ogoffart@tiscalinet.be>

    Kopete    (c) 2002-2003 by the Kopete developers  <kopete-devel@kde.org>

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

#include "kopeteemoticons.h"

#include "kopeteprefs.h"

#include <qdom.h>
#include <qfile.h>
#include <qregexp.h>
#include <qstylesheet.h>
#include <qimage.h>

#include <kapplication.h>
#include <kdebug.h>
#include <kstandarddirs.h>

KopeteEmoticons *KopeteEmoticons::s_instance = 0L;

KopeteEmoticons *KopeteEmoticons::emoticons()
{
	if( !s_instance )
		s_instance = new KopeteEmoticons;
	return s_instance;
}

KopeteEmoticons::KopeteEmoticons( const QString &theme ) : QObject( kapp, "KopeteEmoticons" )
{
//	kdDebug(14010) << "KopeteEmoticons::KopeteEmoticons" << endl;
	if(theme.isNull())
	{
		initEmoticons();
		connect( KopetePrefs::prefs(), SIGNAL(saved()), this, SLOT(initEmoticons()) );
	}
	else
	{
		initEmoticons( theme );
	}
}

void KopeteEmoticons::addIfPossible( const QString& filenameNoExt, QStringList emoticons )
{
	KStandardDirs *dir = KGlobal::dirs();
	QString pic;

	//maybe an extention was given, so try to find the exact file
	pic = dir->findResource( "data", QString::fromLatin1( "kopete/pics/emoticons/" ) + m_theme +
		QString::fromLatin1( "/" ) + filenameNoExt );

	if( pic.isNull() )
		pic = dir->findResource( "data", QString::fromLatin1( "kopete/pics/emoticons/" ) + m_theme +
			QString::fromLatin1( "/" ) + filenameNoExt + QString::fromLatin1( ".mng" ) );
	if ( pic.isNull() )
		pic = dir->findResource( "data", QString::fromLatin1( "kopete/pics/emoticons/" ) +
			m_theme + QString::fromLatin1( "/" ) + filenameNoExt + QString::fromLatin1( ".png" ) );
	if ( pic.isNull() )
		pic = dir->findResource( "data", QString::fromLatin1( "kopete/pics/emoticons/" ) +
			m_theme + QString::fromLatin1( "/" ) + filenameNoExt + QString::fromLatin1( ".gif" ) );

	if( !pic.isNull() ) // only add if we found one file
	{
//		kdDebug(14010) << "KopeteEmoticons::addIfPossible : found pixmap for emoticons" <<endl;
		map[pic] = emoticons;
	}
}

void KopeteEmoticons::initEmoticons( const QString &theme )
{
	if(theme.isNull())
	{
		if ( m_theme == KopetePrefs::prefs()->iconTheme() )
			return;

		m_theme = KopetePrefs::prefs()->iconTheme();
	}
	else
		m_theme = theme;

//	kdDebug(14010) << k_funcinfo << "Called" << endl;
	map.clear(); // empty the mapping

	QDomDocument emoticonMap( QString::fromLatin1( "messaging-emoticon-map" ) );
	QString filename = KGlobal::dirs()->findResource( "data", QString::fromLatin1( "kopete/pics/emoticons/" ) +
		m_theme + QString::fromLatin1( "/emoticons.xml" ) );

	if( filename.isEmpty() )
	{
		kdDebug(14010) << "KopeteEmoticons::initEmoticons : WARNING: emoticon-map not found" <<endl;
		return ;
	}

	QFile mapFile( filename );
	mapFile.open( IO_ReadOnly );
	emoticonMap.setContent( &mapFile );

	QDomElement list = emoticonMap.documentElement();
	QDomNode node = list.firstChild();
	while( !node.isNull() )
	{
		QDomElement element = node.toElement();
		if( !element.isNull() )
		{
			if( element.tagName() == QString::fromLatin1( "emoticon" ) )
			{
				QString emoticon_file = element.attribute(
					QString::fromLatin1( "file" ), QString::null );
				QStringList items;

				QDomNode emoticonNode = node.firstChild();
				while( !emoticonNode.isNull() )
				{
					QDomElement emoticonElement = emoticonNode.toElement();
					if( !emoticonElement.isNull() )
					{
						if( emoticonElement.tagName() == QString::fromLatin1( "string" ) )
						{
							items << emoticonElement.text();
						}
						else
						{
							kdDebug(14010) << k_funcinfo <<
								"Warning: Unknown element '" << element.tagName() <<
								"' in emoticon data" << endl;
						}
					}
					emoticonNode = emoticonNode.nextSibling();
				}

				addIfPossible ( emoticon_file, items );
			}
			else
			{
				kdDebug(14010) << k_funcinfo << "Warning: Unknown element '" <<
					element.tagName() << "' in map file" << endl;
			}
		}
		node = node.nextSibling();
	}
	mapFile.close();
}

QString KopeteEmoticons::emoticonToPicPath ( const QString& em )
{
	EmoticonMap::Iterator it;
	for ( it = map.begin(); it != map.end(); ++it )
	{
		// search in QStringList data for emoticon
		if ( it.data().findIndex(em) != -1 )
			return it.key();
		// if found return path for corresponding animation or pixmap
	}

	return QString();
}

QStringList KopeteEmoticons::picPathToEmoticon ( const QString& path )
{
	EmoticonMap::Iterator it = map.find( path );
	if ( it != map.end() )
		return it.data();

	return QStringList();
}

QStringList KopeteEmoticons::emoticonList()
{
	QStringList retVal;
	EmoticonMap::Iterator it;

	for ( it = map.begin(); it != map.end(); ++it )
		retVal += it.data();

	return retVal;
}

QStringList KopeteEmoticons::picList()
{
	QStringList retVal;
	EmoticonMap::Iterator it;

	for ( it = map.begin(); it != map.end(); ++it )
		retVal += it.key();

	return retVal;
}

QMap<QString, QString> KopeteEmoticons::emoticonAndPicList()
{
	QMap<QString, QString> retVal;
	EmoticonMap::Iterator it;

	for ( it = map.begin(); it != map.end(); ++it )
		retVal[it.data().first()] = it.key();

	return retVal;
}

QString KopeteEmoticons::parseEmoticons( QString message )
{
	// if emoticons are disabled, we do nothing
	if ( !KopetePrefs::prefs()->useEmoticons() )
		return message;

	QStringList emoticons = KopeteEmoticons::emoticons()->emoticonList();

	for ( QStringList::Iterator it = emoticons.begin(); it != emoticons.end(); ++it )
	{
		if(message.contains( QStyleSheet::escape(*it) ))
		{
			QString em = QRegExp::escape( QStyleSheet::escape(*it) );

			QString imgPath = KopeteEmoticons::emoticons()->emoticonToPicPath( *it );

			QImage iconImage(imgPath);

			message.replace( QRegExp(QString::fromLatin1( "(^|[\\W\\s]|%1)(%1)(?!\\w)" ).arg(em).arg(em)),
				QString::fromLatin1("\\1" )
				);
		}
	}

	return message;
}

#include "kopeteemoticons.moc"
// vim: set noet ts=4 sts=4 sw=4:
<commit_msg>Add a title to the emoticon to show a tool-tip showing the original text<commit_after>/*
    kopeteemoticons.cpp - Kopete Preferences Container-Class

    Copyright (c) 2002      by Stefan Gehn            <sgehn@gmx.net>
    Copyright (c) 2002      by Olivier Goffart        <ogoffart@tiscalinet.be>

    Kopete    (c) 2002-2003 by the Kopete developers  <kopete-devel@kde.org>

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

#include "kopeteemoticons.h"

#include "kopeteprefs.h"

#include <qdom.h>
#include <qfile.h>
#include <qregexp.h>
#include <qstylesheet.h>
#include <qimage.h>

#include <kapplication.h>
#include <kdebug.h>
#include <kstandarddirs.h>

KopeteEmoticons *KopeteEmoticons::s_instance = 0L;

KopeteEmoticons *KopeteEmoticons::emoticons()
{
	if( !s_instance )
		s_instance = new KopeteEmoticons;
	return s_instance;
}

KopeteEmoticons::KopeteEmoticons( const QString &theme ) : QObject( kapp, "KopeteEmoticons" )
{
//	kdDebug(14010) << "KopeteEmoticons::KopeteEmoticons" << endl;
	if(theme.isNull())
	{
		initEmoticons();
		connect( KopetePrefs::prefs(), SIGNAL(saved()), this, SLOT(initEmoticons()) );
	}
	else
	{
		initEmoticons( theme );
	}
}

void KopeteEmoticons::addIfPossible( const QString& filenameNoExt, QStringList emoticons )
{
	KStandardDirs *dir = KGlobal::dirs();
	QString pic;

	//maybe an extention was given, so try to find the exact file
	pic = dir->findResource( "data", QString::fromLatin1( "kopete/pics/emoticons/" ) + m_theme +
		QString::fromLatin1( "/" ) + filenameNoExt );

	if( pic.isNull() )
		pic = dir->findResource( "data", QString::fromLatin1( "kopete/pics/emoticons/" ) + m_theme +
			QString::fromLatin1( "/" ) + filenameNoExt + QString::fromLatin1( ".mng" ) );
	if ( pic.isNull() )
		pic = dir->findResource( "data", QString::fromLatin1( "kopete/pics/emoticons/" ) +
			m_theme + QString::fromLatin1( "/" ) + filenameNoExt + QString::fromLatin1( ".png" ) );
	if ( pic.isNull() )
		pic = dir->findResource( "data", QString::fromLatin1( "kopete/pics/emoticons/" ) +
			m_theme + QString::fromLatin1( "/" ) + filenameNoExt + QString::fromLatin1( ".gif" ) );

	if( !pic.isNull() ) // only add if we found one file
	{
//		kdDebug(14010) << "KopeteEmoticons::addIfPossible : found pixmap for emoticons" <<endl;
		map[pic] = emoticons;
	}
}

void KopeteEmoticons::initEmoticons( const QString &theme )
{
	if(theme.isNull())
	{
		if ( m_theme == KopetePrefs::prefs()->iconTheme() )
			return;

		m_theme = KopetePrefs::prefs()->iconTheme();
	}
	else
		m_theme = theme;

//	kdDebug(14010) << k_funcinfo << "Called" << endl;
	map.clear(); // empty the mapping

	QDomDocument emoticonMap( QString::fromLatin1( "messaging-emoticon-map" ) );
	QString filename = KGlobal::dirs()->findResource( "data", QString::fromLatin1( "kopete/pics/emoticons/" ) +
		m_theme + QString::fromLatin1( "/emoticons.xml" ) );

	if( filename.isEmpty() )
	{
		kdDebug(14010) << "KopeteEmoticons::initEmoticons : WARNING: emoticon-map not found" <<endl;
		return ;
	}

	QFile mapFile( filename );
	mapFile.open( IO_ReadOnly );
	emoticonMap.setContent( &mapFile );

	QDomElement list = emoticonMap.documentElement();
	QDomNode node = list.firstChild();
	while( !node.isNull() )
	{
		QDomElement element = node.toElement();
		if( !element.isNull() )
		{
			if( element.tagName() == QString::fromLatin1( "emoticon" ) )
			{
				QString emoticon_file = element.attribute(
					QString::fromLatin1( "file" ), QString::null );
				QStringList items;

				QDomNode emoticonNode = node.firstChild();
				while( !emoticonNode.isNull() )
				{
					QDomElement emoticonElement = emoticonNode.toElement();
					if( !emoticonElement.isNull() )
					{
						if( emoticonElement.tagName() == QString::fromLatin1( "string" ) )
						{
							items << emoticonElement.text();
						}
						else
						{
							kdDebug(14010) << k_funcinfo <<
								"Warning: Unknown element '" << element.tagName() <<
								"' in emoticon data" << endl;
						}
					}
					emoticonNode = emoticonNode.nextSibling();
				}

				addIfPossible ( emoticon_file, items );
			}
			else
			{
				kdDebug(14010) << k_funcinfo << "Warning: Unknown element '" <<
					element.tagName() << "' in map file" << endl;
			}
		}
		node = node.nextSibling();
	}
	mapFile.close();
}

QString KopeteEmoticons::emoticonToPicPath ( const QString& em )
{
	EmoticonMap::Iterator it;
	for ( it = map.begin(); it != map.end(); ++it )
	{
		// search in QStringList data for emoticon
		if ( it.data().findIndex(em) != -1 )
			return it.key();
		// if found return path for corresponding animation or pixmap
	}

	return QString();
}

QStringList KopeteEmoticons::picPathToEmoticon ( const QString& path )
{
	EmoticonMap::Iterator it = map.find( path );
	if ( it != map.end() )
		return it.data();

	return QStringList();
}

QStringList KopeteEmoticons::emoticonList()
{
	QStringList retVal;
	EmoticonMap::Iterator it;

	for ( it = map.begin(); it != map.end(); ++it )
		retVal += it.data();

	return retVal;
}

QStringList KopeteEmoticons::picList()
{
	QStringList retVal;
	EmoticonMap::Iterator it;

	for ( it = map.begin(); it != map.end(); ++it )
		retVal += it.key();

	return retVal;
}

QMap<QString, QString> KopeteEmoticons::emoticonAndPicList()
{
	QMap<QString, QString> retVal;
	EmoticonMap::Iterator it;

	for ( it = map.begin(); it != map.end(); ++it )
		retVal[it.data().first()] = it.key();

	return retVal;
}

QString KopeteEmoticons::parseEmoticons( QString message )
{
	// if emoticons are disabled, we do nothing
	if ( !KopetePrefs::prefs()->useEmoticons() )
		return message;

	QStringList emoticons = KopeteEmoticons::emoticons()->emoticonList();

	for ( QStringList::Iterator it = emoticons.begin(); it != emoticons.end(); ++it )
	{
		if(message.contains( QStyleSheet::escape(*it) ))
		{
			QString em = QRegExp::escape( QStyleSheet::escape(*it) );

			QString imgPath = KopeteEmoticons::emoticons()->emoticonToPicPath( *it );

			QImage iconImage(imgPath);

			message.replace( QRegExp(QString::fromLatin1( "(^|[\\W\\s]|%1)(%1)(?!\\w)" ).arg(em).arg(em)),
				QString::fromLatin1("\\1" ) );
		}
	}

	return message;
}

#include "kopeteemoticons.moc"
// vim: set noet ts=4 sts=4 sw=4:
<|endoftext|>