<commit_before>/*************************************************************************
 *
 *  $RCSfile: appdata.hxx,v $
 *
 *  $Revision: 1.11 $
 *
 *  last change: $Author: kz $ $Date: 2004-10-04 20:58:06 $
 *
 *  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 _SFX_APPDATA_HXX
#define _SFX_APPDATA_HXX

#include <tools/link.hxx>
#include <tools/list.hxx>
#include <svtools/lstner.hxx>
#include <vcl/timer.hxx>
#include <tools/string.hxx>
#include "rtl/ref.hxx"

#include "bitset.hxx"

class SfxApplication;
class SvStrings;
class Config;
class SfxBmkMenu;
class SfxProgress;
class SfxChildWinFactArr_Impl;
class SfxToolBoxConfig;
class SfxDdeDocTopics_Impl;
class DdeService;
class SfxEventConfiguration;
class SfxMacroConfig;
class SfxItemPool;
class SfxInitLinkList;
class SfxFilterMatcher;
class SvUShorts;
struct SfxFrameObjectFactoryPtr;
struct SfxPluginObjectFactoryPtr;
class ISfxTemplateCommon;
class SfxFilterMatcher;
class SfxCancelManager;
class SfxStatusDispatcher;
class SfxDdeTriggerTopic_Impl;
class SfxMiscCfg;
class SfxDocumentTemplates;
class SfxFrameArr_Impl;
class SvtSaveOptions;
class SvtUndoOptions;
class SvtHelpOptions;
class SfxObjectFactory;
class SfxObjectShell;
class ResMgr;
class Window;
namespace sfx2 { namespace appl { class ImeStatusWindow; } }

//=========================================================================
// SfxAppData_Impl
//=========================================================================

class SfxAppData_Impl : public SfxListener
{
public:
    IndexBitSet                         aIndexBitSet;           // for counting noname documents
    List                                aPendingInitFactories;  // late filter init
    Timer                               aLateInitTimer;
    String                              aLastDir;               // for IO dialog
    String                              aLastFilter;            // for IO dialog
    String                              aLastNewURL;            // for AppControl
    String                              aOpenList;              // command line arguments
    String                              aPrintList;             // command line arguments
    String                              aPortalConnect;         // command line arguments
    bool                                bServer;                // command line arguments

    // DDE stuff
    DdeService*                         pDdeService;
    SfxDdeDocTopics_Impl*               pDocTopics;
    SfxDdeTriggerTopic_Impl*            pTriggerTopic;
    DdeService*                         pDdeService2;

    // single instance classes
    SfxChildWinFactArr_Impl*            pFactArr;
    SfxPluginObjectFactoryPtr*          pSfxPluginObjectFactoryPtr;
    SfxObjectFactory*                   pSfxPlugInObjectShellFactory;
    SfxFrameObjectFactoryPtr*           pSfxFrameObjectFactoryPtr;
    SfxFrameArr_Impl*                   pTopFrames;

    // special members
    SfxInitLinkList*                    pInitLinkList;

    // application members
    SfxFilterMatcher*                   pMatcher;
    SfxCancelManager*                   pCancelMgr;
    ResMgr*                             pLabelResMgr;
    SfxStatusDispatcher*                pAppDispatch;
    SfxDocumentTemplates*               pTemplates;

    // global pointers
    Config*                             pFilterIni;
    SfxItemPool*                        pPool;
    SfxEventConfiguration*              pEventConfig;
    SvUShorts*                          pDisabledSlotList;
    SvStrings*                          pSecureURLs;
    SfxMiscCfg*                         pMiscConfig;
    SvtSaveOptions*                     pSaveOptions;
    SvtUndoOptions*                     pUndoOptions;
    SvtHelpOptions*                     pHelpOptions;

    // "current" functionality
    SfxObjectShell*                     pThisDocument;
    SfxProgress*                        pProgress;
    Window*                             pDefFocusWin;
    ISfxTemplateCommon*                 pTemplateCommon;

    USHORT                              nDocModalMode;              // counts documents in modal mode
    USHORT                              nAutoTabPageId;
    USHORT                              nExecutingSID;
    USHORT                              nBasicCallLevel;
    USHORT                              nRescheduleLocks;
    USHORT                              nInReschedule;
    USHORT                              nAsynchronCalls;
    USHORT                              nAppEvent;                  // command line interpretation

    rtl::Reference< sfx2::appl::ImeStatusWindow > m_xImeStatusWindow;

    BOOL                                bDirectAliveCount : 1;
    BOOL                                bInQuit : 1;
    BOOL                                bInvalidateOnUnlock : 1;
    BOOL                                bBean : 1;
    BOOL                                bMinimized : 1;
    BOOL                                bInvisible : 1;
    BOOL                                bInException : 1;
    BOOL                                bPlugged : 1;
    BOOL                                bOLEResize : 1;

                                        SfxAppData_Impl( SfxApplication* );
                                        ~SfxAppData_Impl();

    virtual void                        Notify( SfxBroadcaster &rBC, const SfxHint &rHint );
    void                                UpdateApplicationSettings( BOOL bDontHide );
    SfxDocumentTemplates*               GetDocumentTemplates();
    DECL_STATIC_LINK(                   SfxAppData_Impl, CreateDocumentTemplates, void* );
    void                                DeInitDDE();
};

#endif // #ifndef _SFX_APPDATA_HXX

<commit_msg>INTEGRATION: CWS ooo19126 (1.11.434); FILE MERGED 2005/09/06 13:05:21 rt 1.11.434.1: #i54170# Change license header: remove SISSL<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: appdata.hxx,v $
 *
 *  $Revision: 1.12 $
 *
 *  last change: $Author: rt $ $Date: 2005-09-07 18:54:34 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/
#ifndef _SFX_APPDATA_HXX
#define _SFX_APPDATA_HXX

#include <tools/link.hxx>
#include <tools/list.hxx>
#include <svtools/lstner.hxx>
#include <vcl/timer.hxx>
#include <tools/string.hxx>
#include "rtl/ref.hxx"

#include "bitset.hxx"

class SfxApplication;
class SvStrings;
class Config;
class SfxBmkMenu;
class SfxProgress;
class SfxChildWinFactArr_Impl;
class SfxToolBoxConfig;
class SfxDdeDocTopics_Impl;
class DdeService;
class SfxEventConfiguration;
class SfxMacroConfig;
class SfxItemPool;
class SfxInitLinkList;
class SfxFilterMatcher;
class SvUShorts;
struct SfxFrameObjectFactoryPtr;
struct SfxPluginObjectFactoryPtr;
class ISfxTemplateCommon;
class SfxFilterMatcher;
class SfxCancelManager;
class SfxStatusDispatcher;
class SfxDdeTriggerTopic_Impl;
class SfxMiscCfg;
class SfxDocumentTemplates;
class SfxFrameArr_Impl;
class SvtSaveOptions;
class SvtUndoOptions;
class SvtHelpOptions;
class SfxObjectFactory;
class SfxObjectShell;
class ResMgr;
class Window;
namespace sfx2 { namespace appl { class ImeStatusWindow; } }

//=========================================================================
// SfxAppData_Impl
//=========================================================================

class SfxAppData_Impl : public SfxListener
{
public:
    IndexBitSet                         aIndexBitSet;           // for counting noname documents
    List                                aPendingInitFactories;  // late filter init
    Timer                               aLateInitTimer;
    String                              aLastDir;               // for IO dialog
    String                              aLastFilter;            // for IO dialog
    String                              aLastNewURL;            // for AppControl
    String                              aOpenList;              // command line arguments
    String                              aPrintList;             // command line arguments
    String                              aPortalConnect;         // command line arguments
    bool                                bServer;                // command line arguments

    // DDE stuff
    DdeService*                         pDdeService;
    SfxDdeDocTopics_Impl*               pDocTopics;
    SfxDdeTriggerTopic_Impl*            pTriggerTopic;
    DdeService*                         pDdeService2;

    // single instance classes
    SfxChildWinFactArr_Impl*            pFactArr;
    SfxPluginObjectFactoryPtr*          pSfxPluginObjectFactoryPtr;
    SfxObjectFactory*                   pSfxPlugInObjectShellFactory;
    SfxFrameObjectFactoryPtr*           pSfxFrameObjectFactoryPtr;
    SfxFrameArr_Impl*                   pTopFrames;

    // special members
    SfxInitLinkList*                    pInitLinkList;

    // application members
    SfxFilterMatcher*                   pMatcher;
    SfxCancelManager*                   pCancelMgr;
    ResMgr*                             pLabelResMgr;
    SfxStatusDispatcher*                pAppDispatch;
    SfxDocumentTemplates*               pTemplates;

    // global pointers
    Config*                             pFilterIni;
    SfxItemPool*                        pPool;
    SfxEventConfiguration*              pEventConfig;
    SvUShorts*                          pDisabledSlotList;
    SvStrings*                          pSecureURLs;
    SfxMiscCfg*                         pMiscConfig;
    SvtSaveOptions*                     pSaveOptions;
    SvtUndoOptions*                     pUndoOptions;
    SvtHelpOptions*                     pHelpOptions;

    // "current" functionality
    SfxObjectShell*                     pThisDocument;
    SfxProgress*                        pProgress;
    Window*                             pDefFocusWin;
    ISfxTemplateCommon*                 pTemplateCommon;

    USHORT                              nDocModalMode;              // counts documents in modal mode
    USHORT                              nAutoTabPageId;
    USHORT                              nExecutingSID;
    USHORT                              nBasicCallLevel;
    USHORT                              nRescheduleLocks;
    USHORT                              nInReschedule;
    USHORT                              nAsynchronCalls;
    USHORT                              nAppEvent;                  // command line interpretation

    rtl::Reference< sfx2::appl::ImeStatusWindow > m_xImeStatusWindow;

    BOOL                                bDirectAliveCount : 1;
    BOOL                                bInQuit : 1;
    BOOL                                bInvalidateOnUnlock : 1;
    BOOL                                bBean : 1;
    BOOL                                bMinimized : 1;
    BOOL                                bInvisible : 1;
    BOOL                                bInException : 1;
    BOOL                                bPlugged : 1;
    BOOL                                bOLEResize : 1;

                                        SfxAppData_Impl( SfxApplication* );
                                        ~SfxAppData_Impl();

    virtual void                        Notify( SfxBroadcaster &rBC, const SfxHint &rHint );
    void                                UpdateApplicationSettings( BOOL bDontHide );
    SfxDocumentTemplates*               GetDocumentTemplates();
    DECL_STATIC_LINK(                   SfxAppData_Impl, CreateDocumentTemplates, void* );
    void                                DeInitDDE();
};

#endif // #ifndef _SFX_APPDATA_HXX

<|endoftext|>


<commit_before>/*
    This file is part of KMail.

    Copyright (c) 2005 Cornelius Schumacher <schumacher@kde.org>

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

    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
    Library General Public License for more details.

    You should have received a copy of the GNU Library General Public License
    along with this library; see the file COPYING.LIB.  If not, write to
    the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
    Boston, MA 02111-1307, USA.
*/

#include "recipientspicker.h"

#include <libkdepim/recentaddresses.h>

#include <klistview.h>
#include <klocale.h>
#include <kabc/stdaddressbook.h>
#include <kabc/resource.h>
#include <kiconloader.h>
#include <kdialog.h>
#include <kwin.h>
#include <kabc/distributionlist.h>

#include <qlayout.h>
#include <qcombobox.h>
#include <qpushbutton.h>
#include <qlabel.h>

RecipientItem::RecipientItem()
  : mDistributionList( 0 )
{
}

void RecipientItem::setDistributionList( KABC::DistributionList *list )
{
  mDistributionList = list;

  mIcon = KGlobal::iconLoader()->loadIcon( "kdmconfig", KIcon::Small );

  mKey = "D" + list->name();
}

void RecipientItem::setAddressee( const KABC::Addressee &a )
{
  mAddressee = a;

  QImage img = a.photo().data();
  if ( !img.isNull() )
    mIcon = img.smoothScale( 20, 20, QImage::ScaleMin );
  else
    mIcon = KGlobal::iconLoader()->loadIcon( "personal", KIcon::Small );

  mKey = "A" + a.preferredEmail();
}

QPixmap RecipientItem::icon() const
{
  return mIcon;
}

QString RecipientItem::name() const
{
  if ( !mAddressee.isEmpty() ) return mAddressee.realName();
  else if ( mDistributionList ) return mDistributionList->name();
  else return QString::null;
}

QString RecipientItem::email() const
{
  if ( !mAddressee.isEmpty() ) return mAddressee.preferredEmail();
  else if ( mDistributionList ) {
    int count = mDistributionList->entries().count();
    return i18n( "1 email address", "%n email addresses", count );
  }
  else return QString::null;
}

QString RecipientItem::recipient() const
{
  QString r;
  if ( !mAddressee.isEmpty() ) r = mAddressee.fullEmail();
  else if ( mDistributionList ) r = mDistributionList->name();
  return r;
}

void RecipientItem::setRecipientType( const QString &type )
{
  mType = type;
}

QString RecipientItem::recipientType() const
{
  return mType;
}

RecipientViewItem::RecipientViewItem( RecipientItem *item, KListView *listView )
  : KListViewItem( listView ), mRecipientItem( item )
{
  setText( 0, item->recipientType() );
  setText( 1, item->name() );
  setText( 2, item->email() );

  setPixmap( 1, item->icon() );
}

RecipientItem *RecipientViewItem::recipientItem() const
{
  return mRecipientItem;
}

RecipientsCollection::RecipientsCollection()
{
}

void RecipientsCollection::setTitle( const QString &title )
{
  mTitle = title;
}

QString RecipientsCollection::title() const
{
  return mTitle;
}

void RecipientsCollection::addItem( RecipientItem *item )
{
  mItems.append( item );

  mKeyMap.insert( item->key(), item );
}

RecipientItem::List RecipientsCollection::items() const
{
  return mItems;
}

bool RecipientsCollection::hasEquivalentItem( RecipientItem *item ) const
{
  return mKeyMap.find( item->key() ) != mKeyMap.end();
}

SearchLine::SearchLine( QWidget *parent, KListView *listView )
  : KListViewSearchLine( parent, listView )
{
}

void SearchLine::keyPressEvent( QKeyEvent *ev )
{
  if ( ev->key() == Key_Down ) emit downPressed();

  KListViewSearchLine::keyPressEvent( ev );
}

RecipientsPicker::RecipientsPicker( QWidget *parent )
  : QWidget( parent, "RecipientsPicker", WType_Dialog ),
  mDistributionListManager( 0 )
{
//  KWin::setType( winId(), NET::Dock );

  setCaption( i18n("Select Recipient") );

  QBoxLayout *topLayout = new QVBoxLayout( this );
  topLayout->setSpacing( KDialog::spacingHint() );
  topLayout->setMargin( KDialog::marginHint() );

  QBoxLayout *resLayout = new QHBoxLayout( topLayout );

  QLabel *label = new QLabel( i18n("AddressBook:"), this );
  resLayout->addWidget( label );

  mCollectionCombo = new QComboBox( this );
  resLayout->addWidget( mCollectionCombo );
  connect( mCollectionCombo, SIGNAL( highlighted( int ) ),
    SLOT( updateList() ) );
  connect( mCollectionCombo, SIGNAL( activated( int ) ),
    SLOT( updateList() ) );

  QBoxLayout *searchLayout = new QHBoxLayout( topLayout );

  label = new QLabel( i18n("&Search:"), this );
  searchLayout->addWidget( label );

  mRecipientList = new KListView( this );
  mRecipientList->setSelectionMode( QListView::Multi );
  mRecipientList->setAllColumnsShowFocus( true );
  topLayout->addWidget( mRecipientList );
  mRecipientList->addColumn( i18n("->") );
  mRecipientList->addColumn( i18n("Name") );
  mRecipientList->addColumn( i18n("Email") );
  connect( mRecipientList, SIGNAL( doubleClicked( QListViewItem *,
    const QPoint &, int ) ), SLOT( slotPicked( QListViewItem * ) ) );
  connect( mRecipientList, SIGNAL( returnPressed( QListViewItem * ) ),
    SLOT( slotPicked( QListViewItem * ) ) );

  mSearchLine = new SearchLine( this, mRecipientList );
  searchLayout->addWidget( mSearchLine );
  label->setBuddy( label );
  connect( mSearchLine, SIGNAL( downPressed() ), SLOT( setFocusList() ) );

  QBoxLayout *buttonLayout = new QHBoxLayout( topLayout );

  buttonLayout->addStretch( 1 );

  mToButton = new QPushButton( i18n("Add As To"), this );
  buttonLayout->addWidget( mToButton );
  connect( mToButton, SIGNAL( clicked() ), SLOT( slotToClicked() ) );

  mCcButton = new QPushButton( i18n("Add As CC"), this );
  buttonLayout->addWidget( mCcButton );
  connect( mCcButton, SIGNAL( clicked() ), SLOT( slotCcClicked() ) );

  mBccButton = new QPushButton( i18n("Add As BCC"), this );
  buttonLayout->addWidget( mBccButton );
  connect( mBccButton, SIGNAL( clicked() ), SLOT( slotBccClicked() ) );
  // BCC isn't commonly used, so hide it for now
  mBccButton->hide();

  QPushButton *okButton = new QPushButton( i18n("&OK"), this );
  buttonLayout->addWidget( okButton );
  connect( okButton, SIGNAL( clicked() ), SLOT( slotOk() ) );
  // It might be confusing to have "Add As ..." in addition to "Ok", so we might
  // want to hide this button.
  // okButton->hide();

  QPushButton *cancelButton = new QPushButton( i18n("&Cancel"), this );
  buttonLayout->addWidget( cancelButton );
  connect( cancelButton, SIGNAL( clicked() ), SLOT( close() ) );

  initCollections();

  mCollectionCombo->setCurrentItem( 0 );

  updateList();

  mSearchLine->setFocus();

  readConfig();

  setTabOrder( mCollectionCombo, mSearchLine );
  setTabOrder( mSearchLine, mRecipientList );
  setTabOrder( mRecipientList, okButton );
  setTabOrder( okButton, cancelButton );
  setTabOrder( cancelButton, mCollectionCombo );
}

RecipientsPicker::~RecipientsPicker()
{
  writeConfig();

  delete mDistributionListManager;
}

void RecipientsPicker::initCollections()
{
  KABC::StdAddressBook *addressbook = KABC::StdAddressBook::self();

  QMap<KABC::Resource *,RecipientsCollection *> collectionMap;

  QPtrList<KABC::Resource> resources = addressbook->resources();
  KABC::Resource *res;
  for( res = resources.first(); res; res = resources.next() ) {
    RecipientsCollection *collection = new RecipientsCollection;
    collectionMap.insert( res, collection );
    collection->setTitle( res->resourceName() );
  }

  mAllRecipients = new RecipientsCollection;
  mAllRecipients->setTitle( i18n("All") );

  KABC::AddressBook::Iterator it;
  for( it = addressbook->begin(); it != addressbook->end(); ++it ) {
    RecipientItem *item = new RecipientItem;
    item->setAddressee( *it );
    mAllRecipients->addItem( item );

    QMap<KABC::Resource *,RecipientsCollection *>::ConstIterator collIt;
    collIt = collectionMap.find( it->resource() );
    if ( collIt != collectionMap.end() ) {
      (*collIt)->addItem( item );
    }
  }

  insertCollection( mAllRecipients );

  QMap<KABC::Resource *,RecipientsCollection *>::ConstIterator it2;
  for( it2 = collectionMap.begin(); it2 != collectionMap.end(); ++it2 ) {
    insertCollection( *it2 );
  }

  insertDistributionLists();

  insertRecentAddresses();
}

void RecipientsPicker::insertDistributionLists()
{
  RecipientsCollection *collection = new RecipientsCollection;
  collection->setTitle( i18n("Distribution Lists") );

  delete mDistributionListManager;
  mDistributionListManager =
    new KABC::DistributionListManager( KABC::StdAddressBook::self( true ) );

  mDistributionListManager->load();

  QStringList lists = mDistributionListManager->listNames();

  QStringList::Iterator listIt;
  for ( listIt = lists.begin(); listIt != lists.end(); ++listIt ) {
    KABC::DistributionList *list = mDistributionListManager->list( *listIt );
    RecipientItem *item = new RecipientItem;
    item->setDistributionList( list );
    mAllRecipients->addItem( item );
    collection->addItem( item );
  }

  insertCollection( collection );
}

void RecipientsPicker::insertRecentAddresses()
{
  RecipientsCollection *collection = new RecipientsCollection;
  collection->setTitle( i18n("Recent Addresses") );

  KConfig config( "kmailrc" );
  KABC::Addressee::List recents =
    KRecentAddress::RecentAddresses::self( &config )->kabcAddresses();

  KABC::Addressee::List::ConstIterator it;
  for( it = recents.begin(); it != recents.end(); ++it ) {
    RecipientItem *item = new RecipientItem;
    item->setAddressee( *it );
    if ( !mAllRecipients->hasEquivalentItem( item ) ) {
      mAllRecipients->addItem( item );
    }
    collection->addItem( item );
  }

  insertCollection( collection );
}

void RecipientsPicker::insertCollection( RecipientsCollection *coll )
{
  int index = mCollectionMap.count();

  kdDebug() << "RecipientsPicker::insertCollection() " << coll->title()
    << "  index: " << index << endl;

  mCollectionCombo->insertItem( coll->title(), index );
  mCollectionMap.insert( index, coll );
}

void RecipientsPicker::setRecipients( const Recipient::List &recipients )
{
  RecipientItem::List allRecipients = mAllRecipients->items();
  RecipientItem::List::ConstIterator itAll;
  for( itAll = allRecipients.begin(); itAll != allRecipients.end(); ++itAll ) {
    (*itAll)->setRecipientType( QString::null );
  }

  Recipient::List::ConstIterator it;
  for( it = recipients.begin(); it != recipients.end(); ++it ) {
    for( itAll = allRecipients.begin(); itAll != allRecipients.end(); ++itAll ) {
      if ( (*itAll)->recipient() == (*it).email() ) {
        (*itAll)->setRecipientType( (*it).typeLabel() );
      }
    }
  }

  updateList();
}

void RecipientsPicker::updateList()
{
  mRecipientList->clear();

  RecipientsCollection *coll = mCollectionMap[ mCollectionCombo->currentItem() ];

  RecipientItem::List items = coll->items();
  RecipientItem::List::ConstIterator it;
  for( it = items.begin(); it != items.end(); ++it ) {
    new RecipientViewItem( *it, mRecipientList );
  }

  mSearchLine->updateSearch();
}

void RecipientsPicker::slotToClicked()
{
  pick( Recipient::To );
}

void RecipientsPicker::slotCcClicked()
{
  pick( Recipient::Cc );
}

void RecipientsPicker::slotBccClicked()
{
  pick( Recipient::Bcc );
}

void RecipientsPicker::slotOk()
{
  pick( Recipient::Undefined );
}

void RecipientsPicker::slotPicked( QListViewItem *viewItem )
{
  kdDebug() << "RecipientsPicker::slotPicked()" << endl;

  RecipientViewItem *item = static_cast<RecipientViewItem *>( viewItem );
  if ( item ) {
    RecipientItem *i = item->recipientItem();
    emit pickedRecipient( Recipient( i->recipient(), Recipient::Undefined ) );
  }
  close();
}

void RecipientsPicker::pick( Recipient::Type type )
{
  QListViewItem *viewItem;
  for( viewItem = mRecipientList->firstChild(); viewItem;
       viewItem = viewItem->nextSibling() ) {
    if ( viewItem->isSelected() ) {
      RecipientViewItem *item = static_cast<RecipientViewItem *>( viewItem );
      if ( item ) {
        RecipientItem *i = item->recipientItem();
        Recipient r = i->recipient();
        r.setType( type );
        emit pickedRecipient( r );
      }
    }
  }
  close();
}

void RecipientsPicker::keyPressEvent( QKeyEvent *ev )
{
  if ( ev->key() == Key_Escape ) close();

  QWidget::keyPressEvent( ev );
}

void RecipientsPicker::readConfig()
{
  KConfig *cfg = KGlobal::config();
  cfg->setGroup( "RecipientsPicker" );
  QSize size = cfg->readSizeEntry( "Size" );
  if ( !size.isEmpty() ) {
    resize( size );
  }
  int currentCollection = cfg->readNumEntry( "CurrentCollection", -1 );
  if ( currentCollection >= 0 &&
       currentCollection < mCollectionCombo->count() ) {
    mCollectionCombo->setCurrentItem( currentCollection );
  }
}

void RecipientsPicker::writeConfig()
{
  KConfig *cfg = KGlobal::config();
  cfg->setGroup( "RecipientsPicker" );
  cfg->writeEntry( "Size", size() );
  cfg->writeEntry( "CurrentCollection", mCollectionCombo->currentItem() );
}

void RecipientsPicker::setFocusList()
{
  mRecipientList->setFocus();
}

#include "recipientspicker.moc"
<commit_msg>Make Ctrl/Shift selections work.<commit_after>/*
    This file is part of KMail.

    Copyright (c) 2005 Cornelius Schumacher <schumacher@kde.org>

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

    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
    Library General Public License for more details.

    You should have received a copy of the GNU Library General Public License
    along with this library; see the file COPYING.LIB.  If not, write to
    the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
    Boston, MA 02111-1307, USA.
*/

#include "recipientspicker.h"

#include <libkdepim/recentaddresses.h>

#include <klistview.h>
#include <klocale.h>
#include <kabc/stdaddressbook.h>
#include <kabc/resource.h>
#include <kiconloader.h>
#include <kdialog.h>
#include <kwin.h>
#include <kabc/distributionlist.h>

#include <qlayout.h>
#include <qcombobox.h>
#include <qpushbutton.h>
#include <qlabel.h>

RecipientItem::RecipientItem()
  : mDistributionList( 0 )
{
}

void RecipientItem::setDistributionList( KABC::DistributionList *list )
{
  mDistributionList = list;

  mIcon = KGlobal::iconLoader()->loadIcon( "kdmconfig", KIcon::Small );

  mKey = "D" + list->name();
}

void RecipientItem::setAddressee( const KABC::Addressee &a )
{
  mAddressee = a;

  QImage img = a.photo().data();
  if ( !img.isNull() )
    mIcon = img.smoothScale( 20, 20, QImage::ScaleMin );
  else
    mIcon = KGlobal::iconLoader()->loadIcon( "personal", KIcon::Small );

  mKey = "A" + a.preferredEmail();
}

QPixmap RecipientItem::icon() const
{
  return mIcon;
}

QString RecipientItem::name() const
{
  if ( !mAddressee.isEmpty() ) return mAddressee.realName();
  else if ( mDistributionList ) return mDistributionList->name();
  else return QString::null;
}

QString RecipientItem::email() const
{
  if ( !mAddressee.isEmpty() ) return mAddressee.preferredEmail();
  else if ( mDistributionList ) {
    int count = mDistributionList->entries().count();
    return i18n( "1 email address", "%n email addresses", count );
  }
  else return QString::null;
}

QString RecipientItem::recipient() const
{
  QString r;
  if ( !mAddressee.isEmpty() ) r = mAddressee.fullEmail();
  else if ( mDistributionList ) r = mDistributionList->name();
  return r;
}

void RecipientItem::setRecipientType( const QString &type )
{
  mType = type;
}

QString RecipientItem::recipientType() const
{
  return mType;
}

RecipientViewItem::RecipientViewItem( RecipientItem *item, KListView *listView )
  : KListViewItem( listView ), mRecipientItem( item )
{
  setText( 0, item->recipientType() );
  setText( 1, item->name() );
  setText( 2, item->email() );

  setPixmap( 1, item->icon() );
}

RecipientItem *RecipientViewItem::recipientItem() const
{
  return mRecipientItem;
}

RecipientsCollection::RecipientsCollection()
{
}

void RecipientsCollection::setTitle( const QString &title )
{
  mTitle = title;
}

QString RecipientsCollection::title() const
{
  return mTitle;
}

void RecipientsCollection::addItem( RecipientItem *item )
{
  mItems.append( item );

  mKeyMap.insert( item->key(), item );
}

RecipientItem::List RecipientsCollection::items() const
{
  return mItems;
}

bool RecipientsCollection::hasEquivalentItem( RecipientItem *item ) const
{
  return mKeyMap.find( item->key() ) != mKeyMap.end();
}

SearchLine::SearchLine( QWidget *parent, KListView *listView )
  : KListViewSearchLine( parent, listView )
{
}

void SearchLine::keyPressEvent( QKeyEvent *ev )
{
  if ( ev->key() == Key_Down ) emit downPressed();

  KListViewSearchLine::keyPressEvent( ev );
}

RecipientsPicker::RecipientsPicker( QWidget *parent )
  : QWidget( parent, "RecipientsPicker", WType_Dialog ),
  mDistributionListManager( 0 )
{
//  KWin::setType( winId(), NET::Dock );

  setCaption( i18n("Select Recipient") );

  QBoxLayout *topLayout = new QVBoxLayout( this );
  topLayout->setSpacing( KDialog::spacingHint() );
  topLayout->setMargin( KDialog::marginHint() );

  QBoxLayout *resLayout = new QHBoxLayout( topLayout );

  QLabel *label = new QLabel( i18n("AddressBook:"), this );
  resLayout->addWidget( label );

  mCollectionCombo = new QComboBox( this );
  resLayout->addWidget( mCollectionCombo );
  connect( mCollectionCombo, SIGNAL( highlighted( int ) ),
    SLOT( updateList() ) );
  connect( mCollectionCombo, SIGNAL( activated( int ) ),
    SLOT( updateList() ) );

  QBoxLayout *searchLayout = new QHBoxLayout( topLayout );

  label = new QLabel( i18n("&Search:"), this );
  searchLayout->addWidget( label );

  mRecipientList = new KListView( this );
  mRecipientList->setSelectionMode( QListView::Extended );
  mRecipientList->setAllColumnsShowFocus( true );
  topLayout->addWidget( mRecipientList );
  mRecipientList->addColumn( i18n("->") );
  mRecipientList->addColumn( i18n("Name") );
  mRecipientList->addColumn( i18n("Email") );
  connect( mRecipientList, SIGNAL( doubleClicked( QListViewItem *,
    const QPoint &, int ) ), SLOT( slotPicked( QListViewItem * ) ) );
  connect( mRecipientList, SIGNAL( returnPressed( QListViewItem * ) ),
    SLOT( slotPicked( QListViewItem * ) ) );

  mSearchLine = new SearchLine( this, mRecipientList );
  searchLayout->addWidget( mSearchLine );
  label->setBuddy( label );
  connect( mSearchLine, SIGNAL( downPressed() ), SLOT( setFocusList() ) );

  QBoxLayout *buttonLayout = new QHBoxLayout( topLayout );

  buttonLayout->addStretch( 1 );

  mToButton = new QPushButton( i18n("Add As To"), this );
  buttonLayout->addWidget( mToButton );
  connect( mToButton, SIGNAL( clicked() ), SLOT( slotToClicked() ) );

  mCcButton = new QPushButton( i18n("Add As CC"), this );
  buttonLayout->addWidget( mCcButton );
  connect( mCcButton, SIGNAL( clicked() ), SLOT( slotCcClicked() ) );

  mBccButton = new QPushButton( i18n("Add As BCC"), this );
  buttonLayout->addWidget( mBccButton );
  connect( mBccButton, SIGNAL( clicked() ), SLOT( slotBccClicked() ) );
  // BCC isn't commonly used, so hide it for now
  mBccButton->hide();

  QPushButton *okButton = new QPushButton( i18n("&OK"), this );
  buttonLayout->addWidget( okButton );
  connect( okButton, SIGNAL( clicked() ), SLOT( slotOk() ) );
  // It might be confusing to have "Add As ..." in addition to "Ok", so we might
  // want to hide this button.
  // okButton->hide();

  QPushButton *cancelButton = new QPushButton( i18n("&Cancel"), this );
  buttonLayout->addWidget( cancelButton );
  connect( cancelButton, SIGNAL( clicked() ), SLOT( close() ) );

  initCollections();

  mCollectionCombo->setCurrentItem( 0 );

  updateList();

  mSearchLine->setFocus();

  readConfig();

  setTabOrder( mCollectionCombo, mSearchLine );
  setTabOrder( mSearchLine, mRecipientList );
  setTabOrder( mRecipientList, okButton );
  setTabOrder( okButton, cancelButton );
  setTabOrder( cancelButton, mCollectionCombo );
}

RecipientsPicker::~RecipientsPicker()
{
  writeConfig();

  delete mDistributionListManager;
}

void RecipientsPicker::initCollections()
{
  KABC::StdAddressBook *addressbook = KABC::StdAddressBook::self();

  QMap<KABC::Resource *,RecipientsCollection *> collectionMap;

  QPtrList<KABC::Resource> resources = addressbook->resources();
  KABC::Resource *res;
  for( res = resources.first(); res; res = resources.next() ) {
    RecipientsCollection *collection = new RecipientsCollection;
    collectionMap.insert( res, collection );
    collection->setTitle( res->resourceName() );
  }

  mAllRecipients = new RecipientsCollection;
  mAllRecipients->setTitle( i18n("All") );

  KABC::AddressBook::Iterator it;
  for( it = addressbook->begin(); it != addressbook->end(); ++it ) {
    RecipientItem *item = new RecipientItem;
    item->setAddressee( *it );
    mAllRecipients->addItem( item );

    QMap<KABC::Resource *,RecipientsCollection *>::ConstIterator collIt;
    collIt = collectionMap.find( it->resource() );
    if ( collIt != collectionMap.end() ) {
      (*collIt)->addItem( item );
    }
  }

  insertCollection( mAllRecipients );

  QMap<KABC::Resource *,RecipientsCollection *>::ConstIterator it2;
  for( it2 = collectionMap.begin(); it2 != collectionMap.end(); ++it2 ) {
    insertCollection( *it2 );
  }

  insertDistributionLists();

  insertRecentAddresses();
}

void RecipientsPicker::insertDistributionLists()
{
  RecipientsCollection *collection = new RecipientsCollection;
  collection->setTitle( i18n("Distribution Lists") );

  delete mDistributionListManager;
  mDistributionListManager =
    new KABC::DistributionListManager( KABC::StdAddressBook::self( true ) );

  mDistributionListManager->load();

  QStringList lists = mDistributionListManager->listNames();

  QStringList::Iterator listIt;
  for ( listIt = lists.begin(); listIt != lists.end(); ++listIt ) {
    KABC::DistributionList *list = mDistributionListManager->list( *listIt );
    RecipientItem *item = new RecipientItem;
    item->setDistributionList( list );
    mAllRecipients->addItem( item );
    collection->addItem( item );
  }

  insertCollection( collection );
}

void RecipientsPicker::insertRecentAddresses()
{
  RecipientsCollection *collection = new RecipientsCollection;
  collection->setTitle( i18n("Recent Addresses") );

  KConfig config( "kmailrc" );
  KABC::Addressee::List recents =
    KRecentAddress::RecentAddresses::self( &config )->kabcAddresses();

  KABC::Addressee::List::ConstIterator it;
  for( it = recents.begin(); it != recents.end(); ++it ) {
    RecipientItem *item = new RecipientItem;
    item->setAddressee( *it );
    if ( !mAllRecipients->hasEquivalentItem( item ) ) {
      mAllRecipients->addItem( item );
    }
    collection->addItem( item );
  }

  insertCollection( collection );
}

void RecipientsPicker::insertCollection( RecipientsCollection *coll )
{
  int index = mCollectionMap.count();

  kdDebug() << "RecipientsPicker::insertCollection() " << coll->title()
    << "  index: " << index << endl;

  mCollectionCombo->insertItem( coll->title(), index );
  mCollectionMap.insert( index, coll );
}

void RecipientsPicker::setRecipients( const Recipient::List &recipients )
{
  RecipientItem::List allRecipients = mAllRecipients->items();
  RecipientItem::List::ConstIterator itAll;
  for( itAll = allRecipients.begin(); itAll != allRecipients.end(); ++itAll ) {
    (*itAll)->setRecipientType( QString::null );
  }

  Recipient::List::ConstIterator it;
  for( it = recipients.begin(); it != recipients.end(); ++it ) {
    for( itAll = allRecipients.begin(); itAll != allRecipients.end(); ++itAll ) {
      if ( (*itAll)->recipient() == (*it).email() ) {
        (*itAll)->setRecipientType( (*it).typeLabel() );
      }
    }
  }

  updateList();
}

void RecipientsPicker::updateList()
{
  mRecipientList->clear();

  RecipientsCollection *coll = mCollectionMap[ mCollectionCombo->currentItem() ];

  RecipientItem::List items = coll->items();
  RecipientItem::List::ConstIterator it;
  for( it = items.begin(); it != items.end(); ++it ) {
    new RecipientViewItem( *it, mRecipientList );
  }

  mSearchLine->updateSearch();
}

void RecipientsPicker::slotToClicked()
{
  pick( Recipient::To );
}

void RecipientsPicker::slotCcClicked()
{
  pick( Recipient::Cc );
}

void RecipientsPicker::slotBccClicked()
{
  pick( Recipient::Bcc );
}

void RecipientsPicker::slotOk()
{
  pick( Recipient::Undefined );
}

void RecipientsPicker::slotPicked( QListViewItem *viewItem )
{
  kdDebug() << "RecipientsPicker::slotPicked()" << endl;

  RecipientViewItem *item = static_cast<RecipientViewItem *>( viewItem );
  if ( item ) {
    RecipientItem *i = item->recipientItem();
    emit pickedRecipient( Recipient( i->recipient(), Recipient::Undefined ) );
  }
  close();
}

void RecipientsPicker::pick( Recipient::Type type )
{
  QListViewItem *viewItem;
  for( viewItem = mRecipientList->firstChild(); viewItem;
       viewItem = viewItem->nextSibling() ) {
    if ( viewItem->isSelected() ) {
      RecipientViewItem *item = static_cast<RecipientViewItem *>( viewItem );
      if ( item ) {
        RecipientItem *i = item->recipientItem();
        Recipient r = i->recipient();
        r.setType( type );
        emit pickedRecipient( r );
      }
    }
  }
  close();
}

void RecipientsPicker::keyPressEvent( QKeyEvent *ev )
{
  if ( ev->key() == Key_Escape ) close();

  QWidget::keyPressEvent( ev );
}

void RecipientsPicker::readConfig()
{
  KConfig *cfg = KGlobal::config();
  cfg->setGroup( "RecipientsPicker" );
  QSize size = cfg->readSizeEntry( "Size" );
  if ( !size.isEmpty() ) {
    resize( size );
  }
  int currentCollection = cfg->readNumEntry( "CurrentCollection", -1 );
  if ( currentCollection >= 0 &&
       currentCollection < mCollectionCombo->count() ) {
    mCollectionCombo->setCurrentItem( currentCollection );
  }
}

void RecipientsPicker::writeConfig()
{
  KConfig *cfg = KGlobal::config();
  cfg->setGroup( "RecipientsPicker" );
  cfg->writeEntry( "Size", size() );
  cfg->writeEntry( "CurrentCollection", mCollectionCombo->currentItem() );
}

void RecipientsPicker::setFocusList()
{
  mRecipientList->setFocus();
}

#include "recipientspicker.moc"
<|endoftext|>


<commit_before>// Own header
#include "master_glyph.h"

// Project headers
#include "text_renderer_aa_internals.h"

// Standard headers
#include <algorithm>
#include <math.h>
#include <limits.h>

static const unsigned NUM_GAPS = 20;    // Number of samples (in the Y dimension) to use to calculate the kerning distance.

static bool GetPixelFromGdiBuffer(unsigned char *buf, int byteW, int h, int x, int y)
{
    y = h - y - 1;
    unsigned char *line = buf + y * byteW;
    unsigned char pixelByte = line[x / 8];
    unsigned char shiftedPixelByte = pixelByte >> ((7 - x) & 0x7);
    return shiftedPixelByte & 1;
}

void MasterGlyph::CreateFromGdiPixels(unsigned char *gdiPixels, int gdiPixelsWidth, int gdiPixelsHeight, bool fixedWidth)
{
    unsigned gdiByteWidth = (int)ceil(gdiPixelsWidth / 32.0) * 4;

    int minX = INT_MAX;
    int maxX = -1;
    int maxY = -1;

    // Find the dimensions of the glyph
    for (int y = 0; y < gdiPixelsHeight; y++)
    {
        for (int x = 0; x < gdiPixelsWidth; x++)
        {
            bool p = GetPixelFromGdiBuffer(gdiPixels, gdiByteWidth, gdiPixelsHeight, x, y);
            if (p)
            {
                minX = std::min(x, minX);
                maxX = std::max(x, maxX);
                maxY = std::max(y, maxY);
            }
        }
    }

    if (fixedWidth)
        minX = 0;

    if (maxX == 0 || maxY < 0)
    {
        m_width = 0;
        m_widthBytes = 0;
        m_height = 0;
        m_pixelData = NULL;
        m_gapsAtLeft = m_gapsAtRight = NULL;
    }
    else
    {
        m_width = maxX - minX + 1;
        m_widthBytes = (int)ceil(m_width / 8.0);
        m_height = maxY;
        m_pixelData = new unsigned char [m_widthBytes * m_height];
        memset(m_pixelData, 0, m_widthBytes * m_height);

        // Copy the pixel data from the GDI bitmap into this glyph's own store.
        for (int y = 0; y < m_height; y++)
        {
            for (int x = 0; x < m_width; x++)
            {
                if (GetPixelFromGdiBuffer(gdiPixels, gdiByteWidth, gdiPixelsHeight, x + minX, y))
                {
                    PutPix(x, y);
                }
            }
        }

        m_gapsAtLeft = new int[NUM_GAPS];
        m_gapsAtRight = new int[NUM_GAPS];
        for (unsigned i = 0; i < NUM_GAPS; i++)
        {
            CalcGapAtLeft(i);
            CalcGapAtRight(i);
        }
    }
}

// Find the right-hand end of the glyph at the specified scan-line. Return
// the distance from that point to the right-hand edge of the glyph's bounding
// box.
void MasterGlyph::CalcGapAtRight(int i)
{
    //     01234    (m_width = 5)
    //    +-----+
    //    |*    |   y = 1, gap = 4
    //    |*    |   y = 2, gap = 4
    //    |**** |   y = 3, gap = 1
    //    |*   *|   y = 4, gap = 0
    //    |**** |   y = 5, gap = 1
    //    |     |   y = 6, gap = 5
    //    +-----|

    int y = (int)((double)MASTER_GLYPH_RESOLUTION * (double)i / (double)NUM_GAPS);

    if (y < 0 || y >= m_height)
    {
        m_gapsAtRight[i] = m_width;
        return;
    }

    for (int x = m_width - 1; x >= 0; x--)
    {
        if (GetPix(x, y))
        {
            m_gapsAtRight[i] = m_width - x;
            return;
        }
    }

    m_gapsAtRight[i] = m_width; // TODO, should this be zero?
}

void MasterGlyph::CalcGapAtLeft(int i)
{
    int y = (int)((double)MASTER_GLYPH_RESOLUTION * (double)i / (double)NUM_GAPS);

    if (y < 0 || y >= m_height)
    {
        m_gapsAtLeft[i] = m_width;
        return;
    }

    for (int x = 0; x < m_width; x++)
    {
        if (GetPix(x, y))
        {
            m_gapsAtLeft[i] = x;
            return;
        }
    }

    m_gapsAtLeft[i] = m_width; // TODO, should this be zero?
}

void MasterGlyph::KerningCalculationComplete()
{
    delete [] m_gapsAtLeft;
    delete [] m_gapsAtRight;
    m_gapsAtLeft = m_gapsAtRight = NULL;
}

bool MasterGlyph::GetPix(unsigned x, unsigned y)
{
    unsigned char *line = m_pixelData + y * m_widthBytes;
    unsigned char pixelByte = line[x / 8];
    unsigned char shiftedPixelByte = pixelByte >> (x & 0x7);
    return shiftedPixelByte & 1;
}

void MasterGlyph::PutPix(unsigned x, unsigned y)
{
    unsigned char *line = m_pixelData + y * m_widthBytes;
    unsigned char pixelMask = 1 << (x & 0x7);
    line[x / 8] |= pixelMask;
}
<commit_msg>Fixed an-off-by one in MasterGlyph height calculation<commit_after>// Own header
#include "master_glyph.h"

// Project headers
#include "text_renderer_aa_internals.h"

// Standard headers
#include <algorithm>
#include <math.h>
#include <limits.h>

static const unsigned NUM_GAPS = 20;    // Number of samples (in the Y dimension) to use to calculate the kerning distance.

static bool GetPixelFromGdiBuffer(unsigned char *buf, int byteW, int h, int x, int y)
{
    y = h - y - 1;
    unsigned char *line = buf + y * byteW;
    unsigned char pixelByte = line[x / 8];
    unsigned char shiftedPixelByte = pixelByte >> ((7 - x) & 0x7);
    return shiftedPixelByte & 1;
}

void MasterGlyph::CreateFromGdiPixels(unsigned char *gdiPixels, int gdiPixelsWidth, int gdiPixelsHeight, bool fixedWidth)
{
    unsigned gdiByteWidth = (int)ceil(gdiPixelsWidth / 32.0) * 4;

    int minX = INT_MAX;
    int maxX = -1;
    int maxY = -1;

    // Find the dimensions of the glyph
    for (int y = 0; y < gdiPixelsHeight; y++)
    {
        for (int x = 0; x < gdiPixelsWidth; x++)
        {
            bool p = GetPixelFromGdiBuffer(gdiPixels, gdiByteWidth, gdiPixelsHeight, x, y);
            if (p)
            {
                minX = std::min(x, minX);
                maxX = std::max(x, maxX);
                maxY = std::max(y, maxY);
            }
        }
    }

    if (fixedWidth)
        minX = 0;

    if (maxX == 0 || maxY < 0)
    {
        m_width = 0;
        m_widthBytes = 0;
        m_height = 0;
        m_pixelData = NULL;
        m_gapsAtLeft = m_gapsAtRight = NULL;
    }
    else
    {
        m_width = maxX - minX + 1;
        m_widthBytes = (int)ceil(m_width / 8.0);
        m_height = maxY + 1;
        m_pixelData = new unsigned char [m_widthBytes * m_height];
        memset(m_pixelData, 0, m_widthBytes * m_height);

        // Copy the pixel data from the GDI bitmap into this glyph's own store.
        for (int y = 0; y < m_height; y++)
        {
            for (int x = 0; x < m_width; x++)
            {
                if (GetPixelFromGdiBuffer(gdiPixels, gdiByteWidth, gdiPixelsHeight, x + minX, y))
                {
                    PutPix(x, y);
                }
            }
        }

        m_gapsAtLeft = new int[NUM_GAPS];
        m_gapsAtRight = new int[NUM_GAPS];
        for (unsigned i = 0; i < NUM_GAPS; i++)
        {
            CalcGapAtLeft(i);
            CalcGapAtRight(i);
        }
    }
}

// Find the right-hand end of the glyph at the specified scan-line. Return
// the distance from that point to the right-hand edge of the glyph's bounding
// box.
void MasterGlyph::CalcGapAtRight(int i)
{
    //     01234    (m_width = 5)
    //    +-----+
    //    |*    |   y = 1, gap = 4
    //    |*    |   y = 2, gap = 4
    //    |**** |   y = 3, gap = 1
    //    |*   *|   y = 4, gap = 0
    //    |**** |   y = 5, gap = 1
    //    |     |   y = 6, gap = 5
    //    +-----|

    int y = (int)((double)MASTER_GLYPH_RESOLUTION * (double)i / (double)NUM_GAPS);

    if (y < 0 || y >= m_height)
    {
        m_gapsAtRight[i] = m_width;
        return;
    }

    for (int x = m_width - 1; x >= 0; x--)
    {
        if (GetPix(x, y))
        {
            m_gapsAtRight[i] = m_width - x;
            return;
        }
    }

    m_gapsAtRight[i] = m_width; // TODO, should this be zero?
}

void MasterGlyph::CalcGapAtLeft(int i)
{
    int y = (int)((double)MASTER_GLYPH_RESOLUTION * (double)i / (double)NUM_GAPS);

    if (y < 0 || y >= m_height)
    {
        m_gapsAtLeft[i] = m_width;
        return;
    }

    for (int x = 0; x < m_width; x++)
    {
        if (GetPix(x, y))
        {
            m_gapsAtLeft[i] = x;
            return;
        }
    }

    m_gapsAtLeft[i] = m_width; // TODO, should this be zero?
}

void MasterGlyph::KerningCalculationComplete()
{
    delete [] m_gapsAtLeft;
    delete [] m_gapsAtRight;
    m_gapsAtLeft = m_gapsAtRight = NULL;
}

bool MasterGlyph::GetPix(unsigned x, unsigned y)
{
    unsigned char *line = m_pixelData + y * m_widthBytes;
    unsigned char pixelByte = line[x / 8];
    unsigned char shiftedPixelByte = pixelByte >> (x & 0x7);
    return shiftedPixelByte & 1;
}

void MasterGlyph::PutPix(unsigned x, unsigned y)
{
    unsigned char *line = m_pixelData + y * m_widthBytes;
    unsigned char pixelMask = 1 << (x & 0x7);
    line[x / 8] |= pixelMask;
}
<|endoftext|>


<commit_before>/*=========================================================================

  Program:   Visualization Toolkit
  Module:    TestRandomPContingencyStatisticsMPI.cxx

  Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
  All rights reserved.
  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notice for more information.

=========================================================================*/
/*
 * Copyright 2009 Sandia Corporation.
 * Under the terms of Contract DE-AC04-94AL85000, there is a non-exclusive
 * license for use of this work by or on behalf of the
 * U.S. Government. Redistribution and use in source and binary forms, with
 * or without modification, are permitted provided that this Notice and any
 * statement of authorship are reproduced on all copies.
 */
// .SECTION Thanks
// Thanks to Philippe Pebay for implementing this test.

#include <mpi.h>
#include <time.h>

#include "vtkContingencyStatistics.h"
#include "vtkPContingencyStatistics.h"

#include "vtkIntArray.h"
#include "vtkMath.h"
#include "vtkMPIController.h"
#include "vtkMultiBlockDataSet.h"
#include "vtkStdString.h"
#include "vtkTable.h"
#include "vtkVariantArray.h"

// For debugging purposes, output results of serial engines ran on each slice of the distributed data set
#define PRINT_ALL_SERIAL_STATS 0

struct RandomSampleStatisticsArgs
{
  int nVals;
  int* retVal;
  int ioRank;
  int argc;
  char** argv;
};

// This will be called by all processes
void RandomSampleStatistics( vtkMultiProcessController* controller, void* arg )
{
  // Get test parameters
  RandomSampleStatisticsArgs* args = reinterpret_cast<RandomSampleStatisticsArgs*>( arg );
  *(args->retVal) = 0;

  // Get MPI communicator
  vtkMPICommunicator* com = vtkMPICommunicator::SafeDownCast( controller->GetCommunicator() );

  // Get local rank
  int myRank = com->GetLocalProcessId();

  // Seed random number generator
  vtkMath::RandomSeed( static_cast<int>( time( NULL ) ) * ( myRank + 1 ) );

  // Generate an input table that contains samples of mutually independent discrete random variables
  int nVariables = 2;
  vtkIntArray* intArray[2];
  vtkStdString columnNames[] = { "Uniform 0",
                                 "Uniform 1" };

  vtkTable* inputData = vtkTable::New();
  // Discrete uniform samples
  for ( int c = 0; c < nVariables; ++ c )
    {
    intArray[c] = vtkIntArray::New();
    intArray[c]->SetNumberOfComponents( 1 );
    intArray[c]->SetName( columnNames[c] );

    int x;
    for ( int r = 0; r < args->nVals; ++ r )
      {
      x = floor( vtkMath::Random() * 100. );
      intArray[c]->InsertNextValue( x );
      }

    inputData->AddColumn( intArray[c] );
    intArray[c]->Delete();
    }

  // ************************** Contingency Statistics **************************

  // Synchronize and start clock
  com->Barrier();
  time_t t0;
  time ( &t0 );

  // Instantiate a parallel contingency statistics engine and set its ports
  vtkPContingencyStatistics* pcs = vtkPContingencyStatistics::New();
  pcs->SetInput( 0, inputData );
  vtkTable* outputData = pcs->GetOutput( 0 );
  vtkMultiBlockDataSet* outputMetaDS = vtkMultiBlockDataSet::SafeDownCast( pcs->GetOutputDataObject( 1 ) );

  // Select column pairs (uniform vs. uniform, normal vs. normal)
  pcs->AddColumnPair( columnNames[0], columnNames[1] );

  // Test (in parallel) with Learn, Derive, and Assess options turned on
  pcs->SetLearn( true );
  pcs->SetDerive( true );
  pcs->SetAssess( true );
  pcs->Update();

    // Synchronize and stop clock
  com->Barrier();
  time_t t1;
  time ( &t1 );

  if ( com->GetLocalProcessId() == args->ioRank )
    {
    cout << "\n## Completed parallel calculation of contingency statistics (with assessment):\n"
         << " \n"
         << "   Wall time: "
         << difftime( t1, t0 )
         << outputMetaDS->GetNumberOfBlocks()
         << " sec.\n";

//    for ( unsigned int b = 0; b < outputMetaDS->GetNumberOfBlocks(); ++ b )
    for ( unsigned int b = 0; b < 2; ++ b )
      {
      vtkTable* outputMeta = vtkTable::SafeDownCast( outputMetaDS->GetBlock( b ) );
      outputMeta->Dump();
      }
    }

  com->Barrier();
  outputData->Dump();

  // Clean up
  pcs->Delete();
}

//----------------------------------------------------------------------------
int main( int argc, char** argv )
{
  // **************************** MPI Initialization ***************************
  vtkMPIController* controller = vtkMPIController::New();
  controller->Initialize( &argc, &argv );

  // If an MPI controller was not created, terminate in error.
  if ( ! controller->IsA( "vtkMPIController" ) )
    {
    vtkGenericWarningMacro("Failed to initialize a MPI controller.");
    controller->Delete();
    return 1;
    }

  vtkMPICommunicator* com = vtkMPICommunicator::SafeDownCast( controller->GetCommunicator() );

  // ************************** Find an I/O node ********************************
  int* ioPtr;
  int ioRank;
  int flag;

  MPI_Attr_get( MPI_COMM_WORLD,
                MPI_IO,
                &ioPtr,
                &flag );

  if ( ( ! flag ) || ( *ioPtr == MPI_PROC_NULL ) )
    {
    // Getting MPI attributes did not return any I/O node found.
    ioRank = MPI_PROC_NULL;
    vtkGenericWarningMacro("No MPI I/O nodes found.");

    // As no I/O node was found, we need an unambiguous way to report the problem.
    // This is the only case when a testValue of -1 will be returned
    controller->Finalize();
    controller->Delete();

    return -1;
    }
  else
    {
    if ( *ioPtr == MPI_ANY_SOURCE )
      {
      // Anyone can do the I/O trick--just pick node 0.
      ioRank = 0;
      }
    else
      {
      // Only some nodes can do I/O. Make sure everyone agrees on the choice (min).
      com->AllReduce( ioPtr,
                      &ioRank,
                      1,
                      vtkCommunicator::MIN_OP );
      }
    }

  // ************************** Initialize test *********************************
  if ( com->GetLocalProcessId() == ioRank )
    {
    cout << "\n# Houston, this is process "
         << ioRank
         << " speaking. I'll be the I/O node.\n";
    }

  // Check how many processes have been made available
  int numProcs = controller->GetNumberOfProcesses();
  if ( controller->GetLocalProcessId() == ioRank )
    {
    cout << "\n# Running test with "
         << numProcs
         << " processes...\n";
    }

  // Parameters for regression test.
  int testValue = 0;
  RandomSampleStatisticsArgs args;
  args.nVals = 20;
  args.retVal = &testValue;
  args.ioRank = ioRank;
  args.argc = argc;
  args.argv = argv;

  // Execute the function named "process" on both processes
  controller->SetSingleMethod( RandomSampleStatistics, &args );
  controller->SingleMethodExecute();

  // Clean up and exit
  if ( com->GetLocalProcessId() == ioRank )
    {
    cout << "\n# Test completed.\n\n";
    }

  controller->Finalize();
  controller->Delete();

  return testValue;
}
<commit_msg>STYLE: removed printing out of number of blocks<commit_after>/*=========================================================================

  Program:   Visualization Toolkit
  Module:    TestRandomPContingencyStatisticsMPI.cxx

  Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
  All rights reserved.
  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notice for more information.

=========================================================================*/
/*
 * Copyright 2009 Sandia Corporation.
 * Under the terms of Contract DE-AC04-94AL85000, there is a non-exclusive
 * license for use of this work by or on behalf of the
 * U.S. Government. Redistribution and use in source and binary forms, with
 * or without modification, are permitted provided that this Notice and any
 * statement of authorship are reproduced on all copies.
 */
// .SECTION Thanks
// Thanks to Philippe Pebay for implementing this test.

#include <mpi.h>
#include <time.h>

#include "vtkContingencyStatistics.h"
#include "vtkPContingencyStatistics.h"

#include "vtkIntArray.h"
#include "vtkMath.h"
#include "vtkMPIController.h"
#include "vtkMultiBlockDataSet.h"
#include "vtkStdString.h"
#include "vtkTable.h"
#include "vtkVariantArray.h"

// For debugging purposes, output results of serial engines ran on each slice of the distributed data set
#define PRINT_ALL_SERIAL_STATS 0

struct RandomSampleStatisticsArgs
{
  int nVals;
  int* retVal;
  int ioRank;
  int argc;
  char** argv;
};

// This will be called by all processes
void RandomSampleStatistics( vtkMultiProcessController* controller, void* arg )
{
  // Get test parameters
  RandomSampleStatisticsArgs* args = reinterpret_cast<RandomSampleStatisticsArgs*>( arg );
  *(args->retVal) = 0;

  // Get MPI communicator
  vtkMPICommunicator* com = vtkMPICommunicator::SafeDownCast( controller->GetCommunicator() );

  // Get local rank
  int myRank = com->GetLocalProcessId();

  // Seed random number generator
  vtkMath::RandomSeed( static_cast<int>( time( NULL ) ) * ( myRank + 1 ) );

  // Generate an input table that contains samples of mutually independent discrete random variables
  int nVariables = 2;
  vtkIntArray* intArray[2];
  vtkStdString columnNames[] = { "Uniform 0",
                                 "Uniform 1" };

  vtkTable* inputData = vtkTable::New();
  // Discrete uniform samples
  for ( int c = 0; c < nVariables; ++ c )
    {
    intArray[c] = vtkIntArray::New();
    intArray[c]->SetNumberOfComponents( 1 );
    intArray[c]->SetName( columnNames[c] );

    int x;
    for ( int r = 0; r < args->nVals; ++ r )
      {
      x = floor( vtkMath::Random() * 100. );
      intArray[c]->InsertNextValue( x );
      }

    inputData->AddColumn( intArray[c] );
    intArray[c]->Delete();
    }

  // ************************** Contingency Statistics **************************

  // Synchronize and start clock
  com->Barrier();
  time_t t0;
  time ( &t0 );

  // Instantiate a parallel contingency statistics engine and set its ports
  vtkPContingencyStatistics* pcs = vtkPContingencyStatistics::New();
  pcs->SetInput( 0, inputData );
  vtkTable* outputData = pcs->GetOutput( 0 );
  vtkMultiBlockDataSet* outputMetaDS = vtkMultiBlockDataSet::SafeDownCast( pcs->GetOutputDataObject( 1 ) );

  // Select column pairs (uniform vs. uniform, normal vs. normal)
  pcs->AddColumnPair( columnNames[0], columnNames[1] );

  // Test (in parallel) with Learn, Derive, and Assess options turned on
  pcs->SetLearn( true );
  pcs->SetDerive( true );
  pcs->SetAssess( true );
  pcs->Update();

    // Synchronize and stop clock
  com->Barrier();
  time_t t1;
  time ( &t1 );

  if ( com->GetLocalProcessId() == args->ioRank )
    {
    cout << "\n## Completed parallel calculation of contingency statistics (with assessment):\n"
         << " \n"
         << "   Wall time: "
         << difftime( t1, t0 )
         << " sec.\n";

//    for ( unsigned int b = 0; b < outputMetaDS->GetNumberOfBlocks(); ++ b )
    for ( unsigned int b = 0; b < 2; ++ b )
      {
      vtkTable* outputMeta = vtkTable::SafeDownCast( outputMetaDS->GetBlock( b ) );
      outputMeta->Dump();
      }
    }

  com->Barrier();
  outputData->Dump();

  // Clean up
  pcs->Delete();
}

//----------------------------------------------------------------------------
int main( int argc, char** argv )
{
  // **************************** MPI Initialization ***************************
  vtkMPIController* controller = vtkMPIController::New();
  controller->Initialize( &argc, &argv );

  // If an MPI controller was not created, terminate in error.
  if ( ! controller->IsA( "vtkMPIController" ) )
    {
    vtkGenericWarningMacro("Failed to initialize a MPI controller.");
    controller->Delete();
    return 1;
    }

  vtkMPICommunicator* com = vtkMPICommunicator::SafeDownCast( controller->GetCommunicator() );

  // ************************** Find an I/O node ********************************
  int* ioPtr;
  int ioRank;
  int flag;

  MPI_Attr_get( MPI_COMM_WORLD,
                MPI_IO,
                &ioPtr,
                &flag );

  if ( ( ! flag ) || ( *ioPtr == MPI_PROC_NULL ) )
    {
    // Getting MPI attributes did not return any I/O node found.
    ioRank = MPI_PROC_NULL;
    vtkGenericWarningMacro("No MPI I/O nodes found.");

    // As no I/O node was found, we need an unambiguous way to report the problem.
    // This is the only case when a testValue of -1 will be returned
    controller->Finalize();
    controller->Delete();

    return -1;
    }
  else
    {
    if ( *ioPtr == MPI_ANY_SOURCE )
      {
      // Anyone can do the I/O trick--just pick node 0.
      ioRank = 0;
      }
    else
      {
      // Only some nodes can do I/O. Make sure everyone agrees on the choice (min).
      com->AllReduce( ioPtr,
                      &ioRank,
                      1,
                      vtkCommunicator::MIN_OP );
      }
    }

  // ************************** Initialize test *********************************
  if ( com->GetLocalProcessId() == ioRank )
    {
    cout << "\n# Houston, this is process "
         << ioRank
         << " speaking. I'll be the I/O node.\n";
    }

  // Check how many processes have been made available
  int numProcs = controller->GetNumberOfProcesses();
  if ( controller->GetLocalProcessId() == ioRank )
    {
    cout << "\n# Running test with "
         << numProcs
         << " processes...\n";
    }

  // Parameters for regression test.
  int testValue = 0;
  RandomSampleStatisticsArgs args;
  args.nVals = 20;
  args.retVal = &testValue;
  args.ioRank = ioRank;
  args.argc = argc;
  args.argv = argv;

  // Execute the function named "process" on both processes
  controller->SetSingleMethod( RandomSampleStatistics, &args );
  controller->SingleMethodExecute();

  // Clean up and exit
  if ( com->GetLocalProcessId() == ioRank )
    {
    cout << "\n# Test completed.\n\n";
    }

  controller->Finalize();
  controller->Delete();

  return testValue;
}
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: mnucfga.hxx,v $
 *
 *  $Revision: 1.4 $
 *
 *  last change: $Author: hr $ $Date: 2006-06-19 22:33:10 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/
#ifndef _SFXMNUCFGA_HXX
#define _SFXMNUCFGA_HXX

#ifndef _STRING_HXX //autogen
#include <tools/string.hxx>
#endif
#ifndef _SFXMINARRAY_HXX
#include "minarray.hxx"
#endif

//==================================================================

class SfxMenuCfgItemArr;

struct SfxMenuCfgItem
{
    USHORT             nId;        // id of the binding or 0 if none
    String             aTitle;     // title of the item
    String             aHelpText;  // Hilfetext
    String              aCommand;
    SfxMenuCfgItemArr* pPopup;     // pointer to a popup menu (if any)
};

DECL_PTRARRAY(SfxMenuCfgItemArr, SfxMenuCfgItem*, 4, 4 )

#endif

<commit_msg>INTEGRATION: CWS vgbugs07 (1.4.308); FILE MERGED 2007/06/04 13:34:57 vg 1.4.308.1: #i76605# Remove -I .../inc/module hack introduced by hedaburemove01<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: mnucfga.hxx,v $
 *
 *  $Revision: 1.5 $
 *
 *  last change: $Author: hr $ $Date: 2007-06-27 23:27:38 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/
#ifndef _SFXMNUCFGA_HXX
#define _SFXMNUCFGA_HXX

#ifndef _STRING_HXX //autogen
#include <tools/string.hxx>
#endif
#ifndef _SFXMINARRAY_HXX
#include <sfx2/minarray.hxx>
#endif

//==================================================================

class SfxMenuCfgItemArr;

struct SfxMenuCfgItem
{
    USHORT             nId;        // id of the binding or 0 if none
    String             aTitle;     // title of the item
    String             aHelpText;  // Hilfetext
    String              aCommand;
    SfxMenuCfgItemArr* pPopup;     // pointer to a popup menu (if any)
};

DECL_PTRARRAY(SfxMenuCfgItemArr, SfxMenuCfgItem*, 4, 4 )

#endif

<|endoftext|>


<commit_before>/*
 * Copyright(c) Sophist Solutions, Inc. 1990-2019.  All rights reserved
 */
#include "../../StroikaPreComp.h"

#include "../../Characters/Format.h"
#include "../../Execution/Exceptions.h"
#include "../../Execution/ProcessRunner.h"
#include "../../Streams/MemoryStream.h"
#include "../../Streams/TextReader.h"

#include "Neighbors.h"

using namespace Stroika::Foundation;
using namespace Stroika::Foundation::Characters;
using namespace Stroika::Foundation::Containers;
using namespace Stroika::Foundation::Execution;
using namespace Stroika::Foundation::Memory;
using namespace Stroika::Foundation::IO;
using namespace Stroika::Foundation::IO::Network;

using Neighbor = NeighborsMonitor::Neighbor;

// @todo
//- https://www.midnightfreddie.com/how-to-arp-a-in-ipv6.html
//-http ://man7.org/linux/man-pages/man8/ip-neighbour.8.html
//  -arp - a
//  - ip neigh show
//  - ip - 6 neigh show
//  - cat / proc / net / arp
//  - use that to fill in new devices / info for discovery
//
// @todo perhaps add ability - background thread - to monitor, and always report up to date list?
//
namespace {
    Collection<Neighbor> ArpDashA_ ()
    {
        Collection<Neighbor> result;
        using std::byte;
        ProcessRunner                    pr (L"arp -a");
        Streams::MemoryStream<byte>::Ptr useStdOut = Streams::MemoryStream<byte>::New ();
        pr.SetStdOut (useStdOut);
        pr.Run ();
        String                   out;
        Streams::TextReader::Ptr stdOut = Streams::TextReader::New (useStdOut);
        for (String i = stdOut.ReadLine (); not i.empty (); i = stdOut.ReadLine ()) {
#if qPlatform_POSIX
            Sequence<String> s = i.Tokenize ();
            if (s.length () >= 4) {
                // raspberrypi.34ChurchStreet.sophists.com (192.168.244.32) at b8:27:eb:cc:c7:80 [ether] on enp0s31f6
                // ? (192.168.244.173) at b8:3e:59:88:71:06 [ether] on enp0s31f6
                if (s[1].StartsWith (L"(") and s[1].EndsWith (L")")) {
                    result += ArpRec_{InternetAddress{s[1].SubString (1, -1)}, s[3]};
                }
            }
#elif qPlatform_Windows
            if (i.StartsWith (L" ")) {
                Sequence<String> s = i.Tokenize ();
                if (s.length () >= 3 and (s[2] == L"static" or s[2] == L"dynamic")) {
                    result += Neighbor{InternetAddress{s[0]}, s[1]};
                }
            }
#endif
        }
        return result;
    }
}

/*
 ********************************************************************************
 ******************************** NeighborsMonitor ******************************
 ********************************************************************************
 */
class NeighborsMonitor::Rep_ {
public:
    Rep_ (const Options& o)
        : fOptions_{o}
    {
    }
    Collection<NeighborsMonitor::Neighbor> GetNeighbors () const
    {
        return ArpDashA_ ();
    }
    Options fOptions_;
};

NeighborsMonitor::NeighborsMonitor (const Options& options)
    : fRep_ (make_shared<Rep_> (options))
{
}

Collection<NeighborsMonitor::Neighbor> NeighborsMonitor::GetNeighbors () const
{
    return fRep_->GetNeighbors ();
}

<commit_msg>cosmetic<commit_after>/*
 * Copyright(c) Sophist Solutions, Inc. 1990-2019.  All rights reserved
 */
#include "../../StroikaPreComp.h"

#include "../../Characters/Format.h"
#include "../../Execution/Exceptions.h"
#include "../../Execution/ProcessRunner.h"
#include "../../Streams/MemoryStream.h"
#include "../../Streams/TextReader.h"

#include "Neighbors.h"

using namespace Stroika::Foundation;
using namespace Stroika::Foundation::Characters;
using namespace Stroika::Foundation::Containers;
using namespace Stroika::Foundation::Execution;
using namespace Stroika::Foundation::Memory;
using namespace Stroika::Foundation::IO;
using namespace Stroika::Foundation::IO::Network;

using Neighbor = NeighborsMonitor::Neighbor;

// @todo
//- https://www.midnightfreddie.com/how-to-arp-a-in-ipv6.html
//-http ://man7.org/linux/man-pages/man8/ip-neighbour.8.html
//  -arp - a
//  - ip neigh show
//  - ip - 6 neigh show
//  - cat / proc / net / arp
//  - use that to fill in new devices / info for discovery
//
// @todo perhaps add ability - background thread - to monitor, and always report up to date list?
//
namespace {
    Collection<Neighbor> ArpDashA_ ()
    {
        Collection<Neighbor> result;
        using std::byte;
        ProcessRunner                    pr (L"arp -a");
        Streams::MemoryStream<byte>::Ptr useStdOut = Streams::MemoryStream<byte>::New ();
        pr.SetStdOut (useStdOut);
        pr.Run ();
        String                   out;
        Streams::TextReader::Ptr stdOut = Streams::TextReader::New (useStdOut);
        for (String i = stdOut.ReadLine (); not i.empty (); i = stdOut.ReadLine ()) {
#if qPlatform_POSIX
            Sequence<String> s = i.Tokenize ();
            if (s.length () >= 4) {
                // raspberrypi.34ChurchStreet.sophists.com (192.168.244.32) at b8:27:eb:cc:c7:80 [ether] on enp0s31f6
                // ? (192.168.244.173) at b8:3e:59:88:71:06 [ether] on enp0s31f6
                if (s[1].StartsWith (L"(") and s[1].EndsWith (L")")) {
                    result += ArpRec_{InternetAddress{s[1].SubString (1, -1)}, s[3]};
                }
            }
#elif qPlatform_Windows
            if (i.StartsWith (L" ")) {
                Sequence<String> s = i.Tokenize ();
                if (s.length () >= 3 and (s[2] == L"static" or s[2] == L"dynamic")) {
                    result += Neighbor{InternetAddress{s[0]}, s[1]};
                }
            }
#endif
        }
        return result;
    }
}

/*
 ********************************************************************************
 ******************************** NeighborsMonitor ******************************
 ********************************************************************************
 */
class NeighborsMonitor::Rep_ {
public:
    Rep_ (const Options& o)
        : fOptions_{o}
    {
    }
    Collection<NeighborsMonitor::Neighbor> GetNeighbors () const
    {
        return ArpDashA_ ();
    }
    Options fOptions_;
};

NeighborsMonitor::NeighborsMonitor (const Options& options)
    : fRep_ (make_shared<Rep_> (options))
{
}

Collection<NeighborsMonitor::Neighbor> NeighborsMonitor::GetNeighbors () const
{
    return fRep_->GetNeighbors ();
}
<|endoftext|>


<commit_before>/*
 * Copyright(c) Sophist Solutions, Inc. 1990-2011.  All rights reserved
 */
#ifndef	_Stroika_Foundation_Memory_SharedByValue_inl_
#define	_Stroika_Foundation_Memory_SharedByValue_inl_	1

/*
 ********************************************************************************
 ***************************** Implementation Details ***************************
 ********************************************************************************
 */
#include	"../Execution/AtomicOperations.h"

#include	"BlockAllocated.h"

namespace	Stroika {
	namespace	Foundation {
		namespace	Memory {

			#if		!qCompilerAndStdLib_Supports_lambda_default_argument
			template	<typename	T>
				T*	SharedByValue_CopyByFunction::DefaultElementCopier_ (const T& t)
					{
						return new T (t);
					}
			#endif
			template	<typename	T>
				inline	SharedByValue_CopyByFunction<T>::SharedByValue_CopyByFunction (T* (*copier) (const T&))
					: fCopier_ (copier)
					{
					}
			template	<typename	T>
				inline	T*	SharedByValue_CopyByFunction<T>::Copy (const T& t) const
					{
						return (*fCopier_) (t);
					}

			template	<typename	T>
				inline	T*	SharedByValue_CopyByDefault<T>::Copy (const T& t)
					{
						return new T (t);
					}

			template    <typename	T, typename COPIER, typename SHARED_IMLP>
				inline	SharedByValue<T,COPIER,SHARED_IMLP>::SharedByValue ()
					: SHARED_IMLP ()
					, fCopier_ (COPIER ())
					{
					}
			template    <typename	T, typename COPIER, typename SHARED_IMLP>
				inline	SharedByValue<T,COPIER,SHARED_IMLP>::SharedByValue (const SharedByValue<T,COPIER,SHARED_IMLP>& from)
					: SHARED_IMLP (from)
					, fCopier_ (from.fCopier_)
					{
					}
			template    <typename	T, typename COPIER, typename SHARED_IMLP>
				inline	SharedByValue<T,COPIER,SHARED_IMLP>::SharedByValue (const SHARED_IMLP& from, const COPIER& copier)
					: SHARED_IMLP (from)
					, fCopier_ (copier)
					{
					}
			template    <typename	T, typename COPIER, typename SHARED_IMLP>
				inline	SharedByValue<T,COPIER,SHARED_IMLP>::SharedByValue (T* from, const COPIER& copier)
					: SHARED_IMLP (from)
					, fCopier_ (copier)
					{
					}
			template    <typename	T, typename COPIER, typename SHARED_IMLP>
				inline	SharedByValue<T,COPIER,SHARED_IMLP>& SharedByValue<T,COPIER,SHARED_IMLP>::operator= (const SharedByValue<T,COPIER,SHARED_IMLP>& src)
					{
						SHARED_IMLP::operator= (src);
						fCopier_ = src.fCopier_;
						return *this;
					}
			template    <typename	T, typename COPIER, typename SHARED_IMLP>
				inline	const T*	SharedByValue<T,COPIER,SHARED_IMLP>::GetPointer () const
					{
						return (SHARED_IMLP::get ());
					}
			template    <typename	T, typename COPIER, typename SHARED_IMLP>
				T* SharedByValue<T,COPIER,SHARED_IMLP>::GetPointer ()
					{
						T*	ptr	=	SHARED_IMLP::get ();
						/*
						 * For non-const pointing, we must clone ourselves (if there are
						 * extra referneces). If we are a nullptr pointer, nobody could actually
						 * rereference it anyhow, so don't bother with the Assure1Reference()
						 * in that case.
						 */
						if (ptr == nullptr) {
							return nullptr;
						}
						Assure1Reference ();
						ptr = SHARED_IMLP::get ();
						EnsureNotNull (ptr);
						return (ptr);
					}
			template    <typename	T, typename COPIER, typename SHARED_IMLP>
				inline	const T*	SharedByValue<T,COPIER,SHARED_IMLP>::operator-> () const
					{
						return (SHARED_IMLP::get ());
					}
			template    <typename	T, typename COPIER, typename SHARED_IMLP>
				inline	T* SharedByValue<T,COPIER,SHARED_IMLP>::operator-> ()
					{
						return GetPointer ();
					}
			template    <typename	T, typename COPIER, typename SHARED_IMLP>
				inline	const T&	SharedByValue<T,COPIER,SHARED_IMLP>::operator* () const
					{
						T*	ptr	=	GetPointer ();
						EnsureNotNull (ptr);
						return (*ptr);
					}
			template    <typename	T, typename COPIER, typename SHARED_IMLP>
				T& SharedByValue<T,COPIER,SHARED_IMLP>::operator* ()
					{
						T*	ptr	=	GetPointer ();
						/*
						 * For non-const dereferencing, we must clone ourselves (if there are
						 * extra referneces).
						 */
						Assure1Reference ();
						EnsureNotNull (ptr);
						return (*ptr);
					}
			template    <typename	T, typename COPIER, typename SHARED_IMLP>
				inline	void	SharedByValue<T,COPIER,SHARED_IMLP>::Assure1Reference ()
					{
						if (!SHARED_IMLP::unique ()) {
							BreakReferences_ ();
						}
					}
			template    <typename	T, typename COPIER, typename SHARED_IMLP>
				void	SharedByValue<T,COPIER,SHARED_IMLP>::BreakReferences_ ()
					{
						T*	ptr	=	SHARED_IMLP::get ();
						RequireNotNull (ptr);
						/*
						 *		For a valid pointer that is reference counted and multiply shared,
						 *	make a copy of that pointer via our fCloner function, and assign
						 *	that cloned reference to this.
						 *
						 *		Note that by doing so, we remove any references to the current
						 *	item, and end up with our having the sole reference to the new copy of fPtr.
						 *
						 *		Since we will be cloning the given pointer, we assume(assert) that
						 *	it is non-nullptr.
						 */
						//Require (!SHARED_IMLP::unique ());	This is not NECESSARILY so. Another thread could have just released this pointer, in which case
						// the creation of a new object was pointless, but harmless, as the assignemnt should decrement to zero the old
						// value and it shoudl go away.
						*this = SharedByValue<T,COPIER,SHARED_IMLP> (fCopier_.Copy (*ptr), fCopier_);
						Ensure (SHARED_IMLP::unique ());
					}

		}
	}
}
#endif	/*_Stroika_Foundation_Memory_SharedByValue_inl_*/
<commit_msg>fixed typo in SharedByValue_CopyByFunction<><commit_after>/*
 * Copyright(c) Sophist Solutions, Inc. 1990-2011.  All rights reserved
 */
#ifndef	_Stroika_Foundation_Memory_SharedByValue_inl_
#define	_Stroika_Foundation_Memory_SharedByValue_inl_	1

/*
 ********************************************************************************
 ***************************** Implementation Details ***************************
 ********************************************************************************
 */
#include	"../Execution/AtomicOperations.h"

#include	"BlockAllocated.h"

namespace	Stroika {
	namespace	Foundation {
		namespace	Memory {

			#if		!qCompilerAndStdLib_Supports_lambda_default_argument
			template	<typename	T>
				T*	SharedByValue_CopyByFunction<T>::DefaultElementCopier_ (const T& t)
					{
						return new T (t);
					}
			#endif
			template	<typename	T>
				inline	SharedByValue_CopyByFunction<T>::SharedByValue_CopyByFunction (T* (*copier) (const T&))
					: fCopier_ (copier)
					{
					}
			template	<typename	T>
				inline	T*	SharedByValue_CopyByFunction<T>::Copy (const T& t) const
					{
						return (*fCopier_) (t);
					}

			template	<typename	T>
				inline	T*	SharedByValue_CopyByDefault<T>::Copy (const T& t)
					{
						return new T (t);
					}

			template    <typename	T, typename COPIER, typename SHARED_IMLP>
				inline	SharedByValue<T,COPIER,SHARED_IMLP>::SharedByValue ()
					: SHARED_IMLP ()
					, fCopier_ (COPIER ())
					{
					}
			template    <typename	T, typename COPIER, typename SHARED_IMLP>
				inline	SharedByValue<T,COPIER,SHARED_IMLP>::SharedByValue (const SharedByValue<T,COPIER,SHARED_IMLP>& from)
					: SHARED_IMLP (from)
					, fCopier_ (from.fCopier_)
					{
					}
			template    <typename	T, typename COPIER, typename SHARED_IMLP>
				inline	SharedByValue<T,COPIER,SHARED_IMLP>::SharedByValue (const SHARED_IMLP& from, const COPIER& copier)
					: SHARED_IMLP (from)
					, fCopier_ (copier)
					{
					}
			template    <typename	T, typename COPIER, typename SHARED_IMLP>
				inline	SharedByValue<T,COPIER,SHARED_IMLP>::SharedByValue (T* from, const COPIER& copier)
					: SHARED_IMLP (from)
					, fCopier_ (copier)
					{
					}
			template    <typename	T, typename COPIER, typename SHARED_IMLP>
				inline	SharedByValue<T,COPIER,SHARED_IMLP>& SharedByValue<T,COPIER,SHARED_IMLP>::operator= (const SharedByValue<T,COPIER,SHARED_IMLP>& src)
					{
						SHARED_IMLP::operator= (src);
						fCopier_ = src.fCopier_;
						return *this;
					}
			template    <typename	T, typename COPIER, typename SHARED_IMLP>
				inline	const T*	SharedByValue<T,COPIER,SHARED_IMLP>::GetPointer () const
					{
						return (SHARED_IMLP::get ());
					}
			template    <typename	T, typename COPIER, typename SHARED_IMLP>
				T* SharedByValue<T,COPIER,SHARED_IMLP>::GetPointer ()
					{
						T*	ptr	=	SHARED_IMLP::get ();
						/*
						 * For non-const pointing, we must clone ourselves (if there are
						 * extra referneces). If we are a nullptr pointer, nobody could actually
						 * rereference it anyhow, so don't bother with the Assure1Reference()
						 * in that case.
						 */
						if (ptr == nullptr) {
							return nullptr;
						}
						Assure1Reference ();
						ptr = SHARED_IMLP::get ();
						EnsureNotNull (ptr);
						return (ptr);
					}
			template    <typename	T, typename COPIER, typename SHARED_IMLP>
				inline	const T*	SharedByValue<T,COPIER,SHARED_IMLP>::operator-> () const
					{
						return (SHARED_IMLP::get ());
					}
			template    <typename	T, typename COPIER, typename SHARED_IMLP>
				inline	T* SharedByValue<T,COPIER,SHARED_IMLP>::operator-> ()
					{
						return GetPointer ();
					}
			template    <typename	T, typename COPIER, typename SHARED_IMLP>
				inline	const T&	SharedByValue<T,COPIER,SHARED_IMLP>::operator* () const
					{
						T*	ptr	=	GetPointer ();
						EnsureNotNull (ptr);
						return (*ptr);
					}
			template    <typename	T, typename COPIER, typename SHARED_IMLP>
				T& SharedByValue<T,COPIER,SHARED_IMLP>::operator* ()
					{
						T*	ptr	=	GetPointer ();
						/*
						 * For non-const dereferencing, we must clone ourselves (if there are
						 * extra referneces).
						 */
						Assure1Reference ();
						EnsureNotNull (ptr);
						return (*ptr);
					}
			template    <typename	T, typename COPIER, typename SHARED_IMLP>
				inline	void	SharedByValue<T,COPIER,SHARED_IMLP>::Assure1Reference ()
					{
						if (!SHARED_IMLP::unique ()) {
							BreakReferences_ ();
						}
					}
			template    <typename	T, typename COPIER, typename SHARED_IMLP>
				void	SharedByValue<T,COPIER,SHARED_IMLP>::BreakReferences_ ()
					{
						T*	ptr	=	SHARED_IMLP::get ();
						RequireNotNull (ptr);
						/*
						 *		For a valid pointer that is reference counted and multiply shared,
						 *	make a copy of that pointer via our fCloner function, and assign
						 *	that cloned reference to this.
						 *
						 *		Note that by doing so, we remove any references to the current
						 *	item, and end up with our having the sole reference to the new copy of fPtr.
						 *
						 *		Since we will be cloning the given pointer, we assume(assert) that
						 *	it is non-nullptr.
						 */
						//Require (!SHARED_IMLP::unique ());	This is not NECESSARILY so. Another thread could have just released this pointer, in which case
						// the creation of a new object was pointless, but harmless, as the assignemnt should decrement to zero the old
						// value and it shoudl go away.
						*this = SharedByValue<T,COPIER,SHARED_IMLP> (fCopier_.Copy (*ptr), fCopier_);
						Ensure (SHARED_IMLP::unique ());
					}

		}
	}
}
#endif	/*_Stroika_Foundation_Memory_SharedByValue_inl_*/
<|endoftext|>


<commit_before>#include <QtWidgets/QAction>
#include <QtCore/QString>
#include <QtCore/QHash>
#include <QtGui/QKeySequence>
#include <QtCore/QDebug>
#include <QtGui/QWheelEvent>

#include "hotKeyManagerPage.h"
#include "ui_hotKeyManagerPage.h"
#include "hotKeyManager.h"

using namespace qReal;

PreferencesHotKeyManagerPage:: PreferencesHotKeyManagerPage(QWidget *parent)
	: PreferencesPage(parent)
	, mUi(new Ui::hotKeyManagerPage)
	, mCurrentId("")
	, mCurrentItem(NULL)
	, mCurrentModifiers(Qt::NoModifier)
{
	mUi->setupUi(this);

	mUi->hotKeysTable->horizontalHeader()->setResizeMode(QHeaderView::Stretch);

	connect(mUi->hotKeysTable, SIGNAL(cellClicked(int,int)), this, SLOT(activateShortcutLineEdit(int,int)));
	connect(mUi->hotKeysTable, SIGNAL(cellDoubleClicked(int,int)), this, SLOT(doubleClicked(int,int)));
	connect(mUi->shortcutLineEdit, SIGNAL(newModifiers(Qt::KeyboardModifiers)), this, SLOT(newModifiers(Qt::KeyboardModifiers)));
	connect(mUi->shortcutLineEdit, SIGNAL(newKey(int)), this, SLOT(newKey(int)));
	connect(mUi->resetShortcutPushButton, SIGNAL(pressed()), this, SLOT(resetShortcuts()));
	connect(mUi->resetAllPushButton, SIGNAL(pressed()), this, SLOT(resetAllShortcuts()));

	initTable();
	loadHotKeys();
}

PreferencesHotKeyManagerPage::~PreferencesHotKeyManagerPage()
{
	delete mUi;
}

void PreferencesHotKeyManagerPage::save()
{

}

void PreferencesHotKeyManagerPage::restoreSettings()
{

}

void PreferencesHotKeyManagerPage::resetShortcuts()
{
	if (mCurrentId != "") {
		HotKeyManager::deleteShortcut(mCurrentId, mCurrentItem->text());
		mCurrentItem->setText("");
		mUi->shortcutLineEdit->setText("");
	}
}

void PreferencesHotKeyManagerPage::resetAllShortcuts()
{
	HotKeyManager::resetAllShortcuts();
	mUi->hotKeysTable->clearContents();
	initTable();
	loadHotKeys();
}

void PreferencesHotKeyManagerPage::loadHotKeys()
{
	QHash<QString, QAction *> cmds = HotKeyManager::commands();
	QHash<QString, QString> shortcuts = HotKeyManager::shortcuts();

	QHash<QString, QAction *>::iterator i;
	int k;
	for (i = cmds.begin(), k = 0; i != cmds.end(); ++i, ++k) {
		QStringList sequences = shortcuts.keys(i.key());

		mUi->hotKeysTable->item(k, 0)->setText(i.key());
		mUi->hotKeysTable->item(k, 1)->setText(i.value()->whatsThis());

		int j = 0;

		foreach (QString const &sequence, sequences) {
			mUi->hotKeysTable->item(k, 2 + j)->setText(sequence);
			j++;
			if (j == 3) {
				break;
			}
		}
	}
}

void PreferencesHotKeyManagerPage::initTable()
{
	int const rows = HotKeyManager::commands().size();

	mUi->hotKeysTable->setRowCount(rows);

	for (int i = 0; i < rows; ++i) {
		for (int j = 0; j < 5; ++j) {
			mUi->hotKeysTable->setItem(i, j, new QTableWidgetItem(""));
		}
	}
}

void PreferencesHotKeyManagerPage::doubleClicked(const int row, const int column)
{
	mUi->shortcutLineEdit->setFocus();
	activateShortcutLineEdit(row, column);
}

void PreferencesHotKeyManagerPage::activateShortcutLineEdit(int const row, int const column)
{
	if (column > 1) {
		if (mCurrentItem != NULL) {
			mCurrentItem->setBackgroundColor(Qt::white);
		}
		mCurrentId = mUi->hotKeysTable->item(row, 0)->text();
		mCurrentItem = mUi->hotKeysTable->item(row, column);
		mCurrentItem->setBackgroundColor(Qt::lightGray);

		mUi->shortcutLineEdit->setText(mCurrentItem->text());
		mUi->shortcutLineEdit->setEnabled(true);

		setTextColor(mCurrentItem->textColor());

		if (HotKeyManager::setShortcut(mCurrentId, mCurrentItem->text())) {
			setTextColor(Qt::black);
		}
	} else {
		mCurrentId = "";
		mUi->shortcutLineEdit->clear();
		mUi->shortcutLineEdit->setEnabled(false);
	}
}

void PreferencesHotKeyManagerPage::newModifiers(Qt::KeyboardModifiers modifiers)
{
	mCurrentModifiers = modifiers;
}

void PreferencesHotKeyManagerPage::newKey(int const key)
{
	if (mCurrentId != "") {
		if (mCurrentItem->text() == "") {
			if (HotKeyManager::setShortcut(mCurrentId, QKeySequence(mCurrentModifiers + key))) {
				setTextColor(Qt::black);
			} else {
				setTextColor(Qt::red);
			}
			mCurrentItem->setText(QKeySequence(mCurrentModifiers + key).toString());
			mUi->shortcutLineEdit->setText(mCurrentItem->text());
		} else {
			int const parts = mCurrentItem->text().count(',');

			if (parts != 3) {
				QString const shortcut = QString("%1, %2").arg(
									mCurrentItem->text()
									, QKeySequence(mCurrentModifiers + key).toString()
								);

				if (mCurrentItem->textColor() == Qt::black) {
					HotKeyManager::deleteShortcut(mCurrentId, mCurrentItem->text());
				}

				if (HotKeyManager::setShortcut(mCurrentId, QKeySequence(shortcut))) {
					setTextColor(Qt::black);
					mCurrentItem->setText(shortcut);
					mUi->shortcutLineEdit->setText(mCurrentItem->text());
				} else {
					HotKeyManager::setShortcut(mCurrentId,  mCurrentItem->text());

					if (parts < 2) {
						setTextColor(Qt::red);
						mCurrentItem->setText(shortcut);
						mUi->shortcutLineEdit->setText(mCurrentItem->text());
					}
				}
			}
		}
		mCurrentModifiers = Qt::NoModifier;
	}
}

void PreferencesHotKeyManagerPage::setTextColor(QColor const &color)
{
	mCurrentItem->setTextColor(color);
	QPalette palette;
	palette.setColor(QPalette::Text, color);
	mUi->shortcutLineEdit->setPalette(palette);
}
<commit_msg>fixed problems with reset and error backlight<commit_after>#include <QtWidgets/QAction>
#include <QtCore/QString>
#include <QtCore/QHash>
#include <QtGui/QKeySequence>
#include <QtCore/QDebug>
#include <QtGui/QWheelEvent>

#include "hotKeyManagerPage.h"
#include "ui_hotKeyManagerPage.h"
#include "hotKeyManager.h"

using namespace qReal;

PreferencesHotKeyManagerPage:: PreferencesHotKeyManagerPage(QWidget *parent)
	: PreferencesPage(parent)
	, mUi(new Ui::hotKeyManagerPage)
	, mCurrentId("")
	, mCurrentItem(NULL)
	, mCurrentModifiers(Qt::NoModifier)
{
	mUi->setupUi(this);

	mUi->hotKeysTable->horizontalHeader()->setResizeMode(QHeaderView::Stretch);

	connect(mUi->hotKeysTable, SIGNAL(cellClicked(int,int)), this, SLOT(activateShortcutLineEdit(int,int)));
	connect(mUi->hotKeysTable, SIGNAL(cellDoubleClicked(int,int)), this, SLOT(doubleClicked(int,int)));
	connect(mUi->shortcutLineEdit, SIGNAL(newModifiers(Qt::KeyboardModifiers)), this, SLOT(newModifiers(Qt::KeyboardModifiers)));
	connect(mUi->shortcutLineEdit, SIGNAL(newKey(int)), this, SLOT(newKey(int)));
	connect(mUi->resetShortcutPushButton, SIGNAL(pressed()), this, SLOT(resetShortcuts()));
	connect(mUi->resetAllPushButton, SIGNAL(pressed()), this, SLOT(resetAllShortcuts()));

	initTable();
	loadHotKeys();
}

PreferencesHotKeyManagerPage::~PreferencesHotKeyManagerPage()
{
	delete mUi;
}

void PreferencesHotKeyManagerPage::save()
{

}

void PreferencesHotKeyManagerPage::restoreSettings()
{

}

void PreferencesHotKeyManagerPage::resetShortcuts()
{
	if (mCurrentId != "") {
		if (mCurrentItem->textColor() == Qt::black) {
			HotKeyManager::deleteShortcut(mCurrentId, mCurrentItem->text());
		}

		mCurrentItem->setText("");
		mUi->shortcutLineEdit->setText("");
		setTextColor(Qt::black);
	}
}

void PreferencesHotKeyManagerPage::resetAllShortcuts()
{
	HotKeyManager::resetAllShortcuts();
	mUi->hotKeysTable->clearContents();
	initTable();
	loadHotKeys();
}

void PreferencesHotKeyManagerPage::loadHotKeys()
{
	QHash<QString, QAction *> cmds = HotKeyManager::commands();
	QHash<QString, QString> shortcuts = HotKeyManager::shortcuts();

	QHash<QString, QAction *>::iterator i;
	int k;
	for (i = cmds.begin(), k = 0; i != cmds.end(); ++i, ++k) {
		QStringList sequences = shortcuts.keys(i.key());

		mUi->hotKeysTable->item(k, 0)->setText(i.key());
		mUi->hotKeysTable->item(k, 1)->setText(i.value()->whatsThis());

		int j = 0;

		foreach (QString const &sequence, sequences) {
			mUi->hotKeysTable->item(k, 2 + j)->setText(sequence);
			j++;
			if (j == 3) {
				break;
			}
		}
	}
}

void PreferencesHotKeyManagerPage::initTable()
{
	int const rows = HotKeyManager::commands().size();

	mUi->hotKeysTable->setRowCount(rows);

	for (int i = 0; i < rows; ++i) {
		for (int j = 0; j < 5; ++j) {
			mUi->hotKeysTable->setItem(i, j, new QTableWidgetItem(""));
			mUi->hotKeysTable->item(i, j)->setTextColor(Qt::black);
		}
	}
}

void PreferencesHotKeyManagerPage::doubleClicked(const int row, const int column)
{
	mUi->shortcutLineEdit->setFocus();
	activateShortcutLineEdit(row, column);
}

void PreferencesHotKeyManagerPage::activateShortcutLineEdit(int const row, int const column)
{
	if (column > 1) {
		if (mCurrentItem != NULL) {
			mCurrentItem->setBackgroundColor(Qt::white);
		}
		mCurrentId = mUi->hotKeysTable->item(row, 0)->text();
		mCurrentItem = mUi->hotKeysTable->item(row, column);
		mCurrentItem->setBackgroundColor(Qt::lightGray);

		mUi->shortcutLineEdit->setText(mCurrentItem->text());
		mUi->shortcutLineEdit->setEnabled(true);

		setTextColor(mCurrentItem->textColor());

		if (HotKeyManager::setShortcut(mCurrentId, mCurrentItem->text())) {
			setTextColor(Qt::black);
		}
	} else {
		mCurrentId = "";
		mUi->shortcutLineEdit->clear();
		mUi->shortcutLineEdit->setEnabled(false);
	}
}

void PreferencesHotKeyManagerPage::newModifiers(Qt::KeyboardModifiers modifiers)
{
	mCurrentModifiers = modifiers;
}

void PreferencesHotKeyManagerPage::newKey(int const key)
{
	if (mCurrentId != "") {
		if (mCurrentItem->text() == "") {
			if (HotKeyManager::setShortcut(mCurrentId, QKeySequence(mCurrentModifiers + key))) {
				setTextColor(Qt::black);
			} else {
				setTextColor(Qt::red);
			}
			mCurrentItem->setText(QKeySequence(mCurrentModifiers + key).toString());
			mUi->shortcutLineEdit->setText(mCurrentItem->text());
		} else {
			int const parts = mCurrentItem->text().count(',');

			if (parts != 3) {
				QString const shortcut = QString("%1, %2").arg(
									mCurrentItem->text()
									, QKeySequence(mCurrentModifiers + key).toString()
								);

				if (mCurrentItem->textColor() == Qt::black) {
					HotKeyManager::deleteShortcut(mCurrentId, mCurrentItem->text());
				}

				if (HotKeyManager::setShortcut(mCurrentId, QKeySequence(shortcut))) {
					setTextColor(Qt::black);
					mCurrentItem->setText(shortcut);
					mUi->shortcutLineEdit->setText(mCurrentItem->text());
				} else {
					HotKeyManager::setShortcut(mCurrentId,  mCurrentItem->text());

					if (parts < 2) {
						setTextColor(Qt::red);
						mCurrentItem->setText(shortcut);
						mUi->shortcutLineEdit->setText(mCurrentItem->text());
					}
				}
			}
		}
		mCurrentModifiers = Qt::NoModifier;
	}
}

void PreferencesHotKeyManagerPage::setTextColor(QColor const &color)
{
	mCurrentItem->setTextColor(color);
	QPalette palette;
	palette.setColor(QPalette::Text, color);
	mUi->shortcutLineEdit->setPalette(palette);
}
<|endoftext|>


<commit_before><commit_msg>[TTreeProcessorMT] Re-enable running test with different amount of threads<commit_after><|endoftext|>