<commit_before>/***************************************************************************
**
** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (directui@nokia.com)
**
** This file is part of libdui.
**
** If you have questions regarding the use of this file, please contact
** Nokia at directui@nokia.com.
**
** This library is free software; you can redistribute it and/or
** modify it under the terms of the GNU Lesser General Public
** License version 2.1 as published by the Free Software Foundation
** and appearing in the file LICENSE.LGPL included in the packaging
** of this file.
**
****************************************************************************/

#include <DuiDebug>
#include <DuiDismissEvent>
#include "duiscenewindow.h"
#include "duiscenewindowmodel.h"
#include "duiscenewindow_p.h"
#include "duiscene.h"
#include "duiscenemanager.h"
#include "duiscenemanager_p.h"
#include "duiapplication.h"
#include "duiscenewindowview.h"
#include "duiwindow.h"

#include "duiwidgetcreator.h"
DUI_REGISTER_WIDGET_NO_CREATE(DuiSceneWindow)

DuiSceneWindowPrivate::DuiSceneWindowPrivate()
{
    managedManually = false;
    shown = false;
    dismissed = false;
    policy = DuiSceneWindow::KeepWhenDone;
    effect = NULL;
}

void DuiSceneWindowPrivate::appear(bool now, DuiWindow *window, DuiSceneWindow::DeletionPolicy policy)
{
    Q_Q(DuiSceneWindow);

    if (!window) {
        window = DuiApplication::activeWindow();
        if (!window) {
            // TODO: Create and show() a Dui[Application]Window on the fly?
            duiWarning("DuiSceneWindow")
                    << "Construct and show DuiWindow before showing a scene window";
            return;
        }
    }

    if (now) {
        window->sceneManager()->showWindowNow(q, policy);
    } else {
        window->sceneManager()->showWindow(q, policy);
    }
}

DuiSceneWindow::DuiSceneWindow(QGraphicsItem *parent) :
    DuiWidgetController(new DuiSceneWindowPrivate, new DuiSceneWindowModel, parent)
{
    Q_D(DuiSceneWindow);

    d->windowType = PlainSceneWindow;

    // TODO: Remove this along with deprecated windowShown() and windowHidden()
    connect(this, SIGNAL(appeared()), SIGNAL(windowShown()));
    connect(this, SIGNAL(disappeared()), SIGNAL(windowHidden()));
}

bool DuiSceneWindowPrivate::dismiss(bool now)
{
    Q_Q(DuiSceneWindow);

    /* ABI FREEZE: Release this
    DuiDismissEvent dismissEvent;
    QApplication::sendEvent(q, &dismissEvent);

    if (!dismissEvent.isAccepted()) {
        return false;
    }
    */

    if (q->sceneManager()) {
        if (now) {
            q->sceneManager()->closeWindowNow(q);
        } else {
            q->sceneManager()->closeWindow(q);
        }
    }

    return true;
}

DuiSceneWindow::DuiSceneWindow(DuiSceneWindowPrivate *dd, DuiSceneWindowModel *model, DuiSceneWindow::WindowType windowType, const QString &viewType, QGraphicsItem *parent) :
    DuiWidgetController(dd, model, parent)
{
    Q_D(DuiSceneWindow);
    setViewType(viewType);

    d->windowType = windowType;

    // TODO: Remove this along with deprecated windowShown() and windowHidden()
    connect(this, SIGNAL(appeared()), SIGNAL(windowShown()));
    connect(this, SIGNAL(disappeared()), SIGNAL(windowHidden()));
}

DuiSceneWindow::~DuiSceneWindow()
{
    if (sceneManager())
        sceneManager()->d_func()->detachWindow(this);
}

DuiSceneWindow::WindowType DuiSceneWindow::windowType() const
{
    Q_D(const DuiSceneWindow);
    return d->windowType;
}

DuiSceneWindow::DeletionPolicy DuiSceneWindow::deletionPolicy() const
{
    Q_D(const DuiSceneWindow);
    return d->policy;
}

bool DuiSceneWindow::isManagedManually() const
{
    Q_D(const DuiSceneWindow);
    return d->managedManually;
}

void DuiSceneWindow::setManagedManually(bool managedManually)
{
    Q_D(DuiSceneWindow);
    d->managedManually = managedManually;
}

void DuiSceneWindow::appear(DuiWindow *window, DuiSceneWindow::DeletionPolicy policy)
{
    Q_D(DuiSceneWindow);
    d->appear(false, window, policy);
}

void DuiSceneWindow::appearNow(DuiWindow *window, DuiSceneWindow::DeletionPolicy policy)
{
    Q_D(DuiSceneWindow);
    d->appear(true, window, policy);
}

void DuiSceneWindow::appear(DuiSceneWindow::DeletionPolicy policy)
{
    Q_D(DuiSceneWindow);
    d->appear(false, 0, policy);
}

void DuiSceneWindow::appearNow(DuiSceneWindow::DeletionPolicy policy)
{
    Q_D(DuiSceneWindow);
    d->appear(true, 0, policy);
}

void DuiSceneWindow::disappear()
{
    if (sceneManager())
        sceneManager()->hideWindow(this);
}

void DuiSceneWindow::disappearNow()
{
    if (sceneManager())
        sceneManager()->hideWindowNow(this);
}

Qt::Alignment DuiSceneWindow::alignment() const
{
    Qt::Alignment result = 0;

    if (view()) {
        const DuiSceneWindowView *sceneWindowView =
            qobject_cast<const DuiSceneWindowView *>(view());

        if (sceneWindowView) {
            result = sceneWindowView->alignment();
        }
    }

    if (layoutDirection() == Qt::RightToLeft) {
        if (result.testFlag(Qt::AlignLeft)) {
            result &= ~Qt::AlignLeft;
            result |= Qt::AlignRight;
        } else if (result.testFlag(Qt::AlignRight)) {
            result &= ~Qt::AlignRight;
            result |= Qt::AlignLeft;
        }
    }

    return result;
}

QPointF DuiSceneWindow::offset() const
{
    QPointF result;

    if (view()) {
        const DuiSceneWindowView *sceneWindowView =
            qobject_cast<const DuiSceneWindowView *>(view());

        if (sceneWindowView) {
            result = sceneWindowView->offset();
        }
    } else {
        result = QPointF(0, 0);
    }

    return result;
}

bool DuiSceneWindow::dismiss()
{
    Q_D(DuiSceneWindow);
    return d->dismiss(false);
}

bool DuiSceneWindow::dismissNow()
{
    Q_D(DuiSceneWindow);
    return d->dismiss(true);
}

/* ABI FREEZE: Release this
void DuiSceneWindow::dismissEvent(DuiDismissEvent *event)
{
    event->accept();
}
*/

void DuiSceneWindow::closeEvent(QCloseEvent *event)
{
    event->ignore();
    dismiss();
}

bool DuiSceneWindow::event(QEvent *event)
{
    /* ABI FREEZE: Release this
    if (event->type() == DuiDismissEvent::eventType()) {
        dismissEvent(static_cast<DuiDismissEvent *>(event));
    }
    */

    return DuiWidgetController::event(event);
}
<commit_msg>Changes: Workaround for NB#157036 -  DuiDialog doesn't emit rejected when dialog is disposed on clicking the dimmed area.<commit_after>/***************************************************************************
**
** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (directui@nokia.com)
**
** This file is part of libdui.
**
** If you have questions regarding the use of this file, please contact
** Nokia at directui@nokia.com.
**
** This library is free software; you can redistribute it and/or
** modify it under the terms of the GNU Lesser General Public
** License version 2.1 as published by the Free Software Foundation
** and appearing in the file LICENSE.LGPL included in the packaging
** of this file.
**
****************************************************************************/

#include <DuiDebug>
#include <DuiDismissEvent>
#include "duiscenewindow.h"
#include "duiscenewindowmodel.h"
#include "duiscenewindow_p.h"
#include "duiscene.h"
#include "duiscenemanager.h"
#include "duiscenemanager_p.h"
#include "duiapplication.h"
#include "duiscenewindowview.h"
#include "duiwindow.h"
#include "duidialog.h"

#include "duiwidgetcreator.h"
DUI_REGISTER_WIDGET_NO_CREATE(DuiSceneWindow)

DuiSceneWindowPrivate::DuiSceneWindowPrivate()
{
    managedManually = false;
    shown = false;
    dismissed = false;
    policy = DuiSceneWindow::KeepWhenDone;
    effect = NULL;
}

void DuiSceneWindowPrivate::appear(bool now, DuiWindow *window, DuiSceneWindow::DeletionPolicy policy)
{
    Q_Q(DuiSceneWindow);

    if (!window) {
        window = DuiApplication::activeWindow();
        if (!window) {
            // TODO: Create and show() a Dui[Application]Window on the fly?
            duiWarning("DuiSceneWindow")
                    << "Construct and show DuiWindow before showing a scene window";
            return;
        }
    }

    if (now) {
        window->sceneManager()->showWindowNow(q, policy);
    } else {
        window->sceneManager()->showWindow(q, policy);
    }
}

DuiSceneWindow::DuiSceneWindow(QGraphicsItem *parent) :
    DuiWidgetController(new DuiSceneWindowPrivate, new DuiSceneWindowModel, parent)
{
    Q_D(DuiSceneWindow);

    d->windowType = PlainSceneWindow;

    // TODO: Remove this along with deprecated windowShown() and windowHidden()
    connect(this, SIGNAL(appeared()), SIGNAL(windowShown()));
    connect(this, SIGNAL(disappeared()), SIGNAL(windowHidden()));
}

bool DuiSceneWindowPrivate::dismiss(bool now)
{
    Q_Q(DuiSceneWindow);

    /* ABI FREEZE: Release this
    DuiDismissEvent dismissEvent;
    QApplication::sendEvent(q, &dismissEvent);

    if (!dismissEvent.isAccepted()) {
        return false;
    }
    */
    // BEGIN WORKAROUND: Remove it after abi freeze.
    DuiDialog* dlg = qobject_cast<DuiDialog*>(q);
    if (dlg) {
        dlg->done(DuiDialog::Rejected);
        return true;
    }
    // END WORKAROUND

    if (q->sceneManager()) {
        if (now) {
            q->sceneManager()->closeWindowNow(q);
        } else {
            q->sceneManager()->closeWindow(q);
        }
    }

    return true;
}

DuiSceneWindow::DuiSceneWindow(DuiSceneWindowPrivate *dd, DuiSceneWindowModel *model, DuiSceneWindow::WindowType windowType, const QString &viewType, QGraphicsItem *parent) :
    DuiWidgetController(dd, model, parent)
{
    Q_D(DuiSceneWindow);
    setViewType(viewType);

    d->windowType = windowType;

    // TODO: Remove this along with deprecated windowShown() and windowHidden()
    connect(this, SIGNAL(appeared()), SIGNAL(windowShown()));
    connect(this, SIGNAL(disappeared()), SIGNAL(windowHidden()));
}

DuiSceneWindow::~DuiSceneWindow()
{
    if (sceneManager())
        sceneManager()->d_func()->detachWindow(this);
}

DuiSceneWindow::WindowType DuiSceneWindow::windowType() const
{
    Q_D(const DuiSceneWindow);
    return d->windowType;
}

DuiSceneWindow::DeletionPolicy DuiSceneWindow::deletionPolicy() const
{
    Q_D(const DuiSceneWindow);
    return d->policy;
}

bool DuiSceneWindow::isManagedManually() const
{
    Q_D(const DuiSceneWindow);
    return d->managedManually;
}

void DuiSceneWindow::setManagedManually(bool managedManually)
{
    Q_D(DuiSceneWindow);
    d->managedManually = managedManually;
}

void DuiSceneWindow::appear(DuiWindow *window, DuiSceneWindow::DeletionPolicy policy)
{
    Q_D(DuiSceneWindow);
    d->appear(false, window, policy);
}

void DuiSceneWindow::appearNow(DuiWindow *window, DuiSceneWindow::DeletionPolicy policy)
{
    Q_D(DuiSceneWindow);
    d->appear(true, window, policy);
}

void DuiSceneWindow::appear(DuiSceneWindow::DeletionPolicy policy)
{
    Q_D(DuiSceneWindow);
    d->appear(false, 0, policy);
}

void DuiSceneWindow::appearNow(DuiSceneWindow::DeletionPolicy policy)
{
    Q_D(DuiSceneWindow);
    d->appear(true, 0, policy);
}

void DuiSceneWindow::disappear()
{
    if (sceneManager())
        sceneManager()->hideWindow(this);
}

void DuiSceneWindow::disappearNow()
{
    if (sceneManager())
        sceneManager()->hideWindowNow(this);
}

Qt::Alignment DuiSceneWindow::alignment() const
{
    Qt::Alignment result = 0;

    if (view()) {
        const DuiSceneWindowView *sceneWindowView =
            qobject_cast<const DuiSceneWindowView *>(view());

        if (sceneWindowView) {
            result = sceneWindowView->alignment();
        }
    }

    if (layoutDirection() == Qt::RightToLeft) {
        if (result.testFlag(Qt::AlignLeft)) {
            result &= ~Qt::AlignLeft;
            result |= Qt::AlignRight;
        } else if (result.testFlag(Qt::AlignRight)) {
            result &= ~Qt::AlignRight;
            result |= Qt::AlignLeft;
        }
    }

    return result;
}

QPointF DuiSceneWindow::offset() const
{
    QPointF result;

    if (view()) {
        const DuiSceneWindowView *sceneWindowView =
            qobject_cast<const DuiSceneWindowView *>(view());

        if (sceneWindowView) {
            result = sceneWindowView->offset();
        }
    } else {
        result = QPointF(0, 0);
    }

    return result;
}

bool DuiSceneWindow::dismiss()
{
    Q_D(DuiSceneWindow);
    return d->dismiss(false);
}

bool DuiSceneWindow::dismissNow()
{
    Q_D(DuiSceneWindow);
    return d->dismiss(true);
}

/* ABI FREEZE: Release this
void DuiSceneWindow::dismissEvent(DuiDismissEvent *event)
{
    event->accept();
}
*/

void DuiSceneWindow::closeEvent(QCloseEvent *event)
{
    event->ignore();
    dismiss();
}

bool DuiSceneWindow::event(QEvent *event)
{
    /* ABI FREEZE: Release this
    if (event->type() == DuiDismissEvent::eventType()) {
        dismissEvent(static_cast<DuiDismissEvent *>(event));
    }
    */

    return DuiWidgetController::event(event);
}
<|endoftext|>


<commit_before>/***************************************************************************
*   Copyright (C) 2004 by                                                 *
*   Jason Kivlighn (jkivlighn@gmail.com)                                  *
*   Unai Garro (ugarro@users.sourceforge.net)                             *
*                                                                         *
*   This program is free software; you can redistribute it and/or modify  *
*   it under the terms of the GNU General Public License as published by  *
*   the Free Software Foundation; either version 2 of the License, or     *
*   (at your option) any later version.                                   *
***************************************************************************/

#include "recipelistview.h"

#include <qintdict.h>
#include <qdatastream.h>
#include <qtooltip.h>

#include <kapplication.h>
#include <kdebug.h>
#include <kconfig.h>
#include <kglobal.h>
#include <klocale.h>
#include <kiconloader.h>
#include <kprogress.h>

#include "backends/recipedb.h"

class UncategorizedItem : public QListViewItem
{
public:
	UncategorizedItem( QListView *lv ) : QListViewItem( lv, i18n("Uncategorized") ){}
	int rtti() const { return 1006; }
};

RecipeItemDrag::RecipeItemDrag( RecipeListItem *recipeItem, QWidget *dragSource, const char *name )
		: QStoredDrag( RECIPEITEMMIMETYPE, dragSource, name )
{
	if ( recipeItem ) {
		QByteArray data;
		QDataStream out( data, IO_WriteOnly );
		out << recipeItem->recipeID();
		out << recipeItem->title();
		setEncodedData( data );
	}
}

bool RecipeItemDrag::canDecode( QMimeSource* e )
{
	return e->provides( RECIPEITEMMIMETYPE );
}

bool RecipeItemDrag::decode( const QMimeSource* e, RecipeListItem& item )
{
	if ( !e )
		return false;

	QByteArray data = e->encodedData( RECIPEITEMMIMETYPE );
	if ( data.isEmpty() )
		return false;

	QString title;
	int recipeID;
	QDataStream in( data, IO_ReadOnly );
	in >> recipeID;
	in >> title;

	item.setTitle( title );
	item.setRecipeID( recipeID );

	return true;
}

class RecipeListToolTip : public QToolTip
{
public:
	RecipeListToolTip( RecipeListView *view ) : QToolTip(view->viewport()), m_view(view)
	{}

	void maybeTip( const QPoint &point )
	{
		QListViewItem *item = m_view->itemAt( point );
		if ( item ) {
			QString text = m_view->tooltip(item,0);
			if ( !text.isEmpty() )
				tip( m_view->itemRect( item ), text );
		}
	}

private:
	RecipeListView *m_view;

};

RecipeListView::RecipeListView( QWidget *parent, RecipeDB *db ) : StdCategoryListView( parent, db ),
		flat_list( false ),
		m_uncat_item(0),
		m_progress_dlg(0)
{
	setColumnText( 0, i18n( "Recipe" ) );

	KConfig *config = KGlobal::config(); config->setGroup( "Performance" );
	curr_limit = config->readNumEntry("CategoryLimit",-1);

	KIconLoader il;
	setPixmap( il.loadIcon( "categories", KIcon::NoGroup, 16 ) );

	setSelectionMode( QListView::Extended );

	(void)new RecipeListToolTip(this);
}

void RecipeListView::init()
{
	connect( database, SIGNAL( recipeCreated( const Element &, const ElementList & ) ), SLOT( createRecipe( const Element &, const ElementList & ) ) );
	connect( database, SIGNAL( recipeRemoved( int ) ), SLOT( removeRecipe( int ) ) );
	connect( database, SIGNAL( recipeRemoved( int, int ) ), SLOT( removeRecipe( int, int ) ) );
	connect( database, SIGNAL( recipeModified( const Element &, const ElementList & ) ), SLOT( modifyRecipe( const Element &, const ElementList & ) ) );

	StdCategoryListView::init();
}

QDragObject *RecipeListView::dragObject()
{
	RecipeListItem * item = dynamic_cast<RecipeListItem*>( currentItem() );
	if ( item != 0 ) {
		RecipeItemDrag * obj = new RecipeItemDrag( item, this, "Recipe drag item" );
		/*const QPixmap *pm = item->pixmap(0);
		if( pm )
			obj->setPixmap( *pm );*/
		return obj;
	}
	return 0;
}

bool RecipeListView::acceptDrag( QDropEvent *event ) const
{
	return RecipeItemDrag::canDecode( event );
}

QString RecipeListView::tooltip(QListViewItem *item, int column) const
{
	if ( item->rtti() == RECIPELISTITEM_RTTI ) {
		RecipeListItem *recipe_it = (RecipeListItem*)item;

		Recipe r;
 		database->loadRecipe(&r,RecipeDB::Meta|RecipeDB::Noatime,recipe_it->recipeID() );

		KLocale *locale = KGlobal::locale();

		return QString("%7__________%1 %2
%3 %4
%5 %6")
		   .arg(i18n("Created:")).arg(locale->formatDateTime(r.ctime))
		   .arg(i18n("Modified:")).arg(locale->formatDateTime(r.mtime))
		   .arg(i18n("Last Accessed:")).arg(locale->formatDateTime(r.atime))
		   .arg(recipe_it->title());
	}/* Maybe this would be handy
	else if ( item->rtti() == CATEGORYLISTITEM_RTTI ) {
		CategoryListItem *cat_it = (CategoryListItem*)item;

		return QString("%1
%2: %3")
		   .arg(cat_it->categoryName())
		   .arg(i18n("Recipes"))
		   .arg(QString::number(WHATEVER THE CHILD COUNT IS));
	}*/

	return QString::null;
}

void RecipeListView::load(int limit, int offset)
{
	m_uncat_item = 0;

	if ( flat_list ) {
		ElementList recipeList;
		database->loadRecipeList( &recipeList );

		ElementList::const_iterator recipe_it;
		for ( recipe_it = recipeList.begin();recipe_it != recipeList.end();++recipe_it ) {
			Recipe recipe;
			recipe.recipeID = ( *recipe_it ).id;
			recipe.title = ( *recipe_it ).name;
			createRecipe( recipe, -1 );
		}
	}
	else {
		StdCategoryListView::load(limit,offset);

		if ( offset == 0 ) {
			ElementList recipeList;
			database->loadUncategorizedRecipes( &recipeList );

			ElementList::const_iterator recipe_it;
			for ( recipe_it = recipeList.begin();recipe_it != recipeList.end();++recipe_it ) {
				Recipe recipe;
				recipe.recipeID = ( *recipe_it ).id;
				recipe.title = ( *recipe_it ).name;
				createRecipe( recipe, -1 );
			}
		}
	}
}

void RecipeListView::populate( QListViewItem *item )
{
	CategoryItemInfo *cat_item = dynamic_cast<CategoryItemInfo*>(item);
	if ( !cat_item || cat_item->isPopulated() ) return;

	delete item->firstChild(); //delete the "pseudo item"

	if ( m_progress_dlg ){
		m_progress_dlg->progressBar()->advance(1);
		kapp->processEvents();
	}

	StdCategoryListView::populate(item);

	if ( !flat_list ) {
		int id = cat_item->categoryId();

		// Now show the recipes
		ElementList recipeList;
		database->loadRecipeList( &recipeList, id );

		ElementList::const_iterator recipe_it;
		for ( recipe_it = recipeList.begin(); recipe_it != recipeList.end(); ++recipe_it ) {
			Recipe recipe;
			recipe.recipeID = ( *recipe_it ).id;
			recipe.title = ( *recipe_it ).name;
			createRecipe( recipe, id );
		}
	}
}

void RecipeListView::populateAll( QListViewItem *parent )
{
	bool first = false;
	if ( !parent ) {
		first = true;
		m_progress_dlg = new KProgressDialog(this,"populate_all_prog_dlg",QString::null,i18n("Loading recipes"),true);
		m_progress_dlg->setAllowCancel(false);
		m_progress_dlg->progressBar()->setTotalSteps(0);
		m_progress_dlg->progressBar()->setPercentageVisible(false);

		m_progress_dlg->grabKeyboard(); //don't let the user keep hitting keys

		parent = firstChild();
	}
	else {
		populate( parent );
		parent = parent->firstChild();
	}

	for ( QListViewItem *item = parent; item; item = item->nextSibling() ) {
		if ( m_progress_dlg && m_progress_dlg->wasCancelled() )
			break;

		populateAll( item );
	}

	if ( first ) {
		delete m_progress_dlg;
		m_progress_dlg = 0;
	}
}

void RecipeListView::createRecipe( const Recipe &recipe, int parent_id )
{
	if ( parent_id == -1 ) {
		if ( !m_uncat_item && curr_offset == 0 ) {
			m_uncat_item = new UncategorizedItem(this);
			if ( childCount() == 1 ) 		//only call createElement if this is the only item in the list
				createElement(m_uncat_item);	//otherwise, this item won't stay at the top
		}

		if ( m_uncat_item )
			new RecipeListItem( m_uncat_item, recipe );
	}
	else {
		CategoryListItem *parent = (CategoryListItem*)items_map[ parent_id ];
		if ( parent && parent->isPopulated() )
			createElement(new RecipeListItem( parent, recipe ));
	}
}

void RecipeListView::createRecipe( const Element &recipe_el, const ElementList &categories )
{
	Recipe recipe;
	recipe.recipeID = recipe_el.id;
	recipe.title = recipe_el.name;

	if ( categories.count() == 0 ) {
		createRecipe( recipe, -1 );
	}
	else {
		for ( ElementList::const_iterator cat_it = categories.begin(); cat_it != categories.end(); ++cat_it ) {
			int cur_cat_id = ( *cat_it ).id;

			QListViewItemIterator iterator( this );
			while ( iterator.current() ) {
				if ( iterator.current() ->rtti() == 1001 ) {
					CategoryListItem * cat_item = ( CategoryListItem* ) iterator.current();
					if ( cat_item->categoryId() == cur_cat_id ) {
						createRecipe( recipe, cur_cat_id );
					}
				}
				++iterator;
			}
		}
	}
}

void RecipeListView::createElement( QListViewItem *item )
{
	CategoryItemInfo *cat_item = dynamic_cast<CategoryItemInfo*>(item);
	if ( !cat_item || cat_item->isPopulated() ) return;

	#if 0
	ElementList list;
	database->loadRecipeList( &list, cat_item->categoryId() );
	if ( list.count() > 0 )
	#endif
		new PseudoListItem( item );

	CategoryListView::createElement(item);
}

void RecipeListView::modifyRecipe( const Element &recipe, const ElementList &categories )
{
	removeRecipe( recipe.id );
	createRecipe( recipe, categories );
}

void RecipeListView::removeRecipe( int id )
{
	QListViewItemIterator iterator( this );
	while ( iterator.current() ) {
		if ( iterator.current() ->rtti() == 1000 ) {
			RecipeListItem * recipe_it = ( RecipeListItem* ) iterator.current();
			if ( recipe_it->recipeID() == id ) {
				removeElement(recipe_it);

				//delete the "Uncategorized" item if we removed the last recipe that was under it
				if ( m_uncat_item->childCount() == 0 ) {
					delete m_uncat_item;
					m_uncat_item = 0;
				}
			}
		}
		++iterator;
	}
}

void RecipeListView::removeRecipe( int recipe_id, int cat_id )
{
	QListViewItem * item = items_map[ cat_id ];

	//find out if this is the only category the recipe belongs to
	int finds = 0;
	QListViewItemIterator iterator( this );
	while ( iterator.current() ) {
		if ( iterator.current() ->rtti() == 1000 ) {
			RecipeListItem * recipe_it = ( RecipeListItem* ) iterator.current();

			if ( recipe_it->recipeID() == recipe_id ) {
				if ( finds > 1 )
					break;
				finds++;
			}
		}
		++iterator;
	}

	//do this to only iterate over children of 'item'
	QListViewItem *pEndItem = NULL;
	QListViewItem *pStartItem = item;
	do {
		if ( pStartItem->nextSibling() )
			pEndItem = pStartItem->nextSibling();
		else
			pStartItem = pStartItem->parent();
	}
	while ( pStartItem && !pEndItem );

	iterator = QListViewItemIterator( item );
	while ( iterator.current() != pEndItem ) {
		if ( iterator.current() ->rtti() == 1000 ) {
			RecipeListItem * recipe_it = ( RecipeListItem* ) iterator.current();

			if ( recipe_it->recipeID() == recipe_id ) {

				if ( finds == 1 ) {
					//the item is now uncategorized
					if ( !m_uncat_item && curr_offset == 0 )
						m_uncat_item = new UncategorizedItem(this);
					if ( m_uncat_item ) {
						Recipe r;
						r.title = recipe_it->title(); r.recipeID = recipe_id;
						new RecipeListItem(m_uncat_item,r);
					}
				}
				removeElement(recipe_it);
				break;
			}
		}
		++iterator;
	}
}

void RecipeListView::removeCategory( int id )
{
	QListViewItem * item = items_map[ id ];
	if ( !item )
		return ; //this may have been deleted already by its parent being deleted

	moveChildrenToRoot( item );

	StdCategoryListView::removeCategory( id );
}

void RecipeListView::moveChildrenToRoot( QListViewItem *item )
{
	QListViewItem * next_sibling;
	for ( QListViewItem * it = item->firstChild(); it; it = next_sibling ) {
		next_sibling = it->nextSibling();
		if ( it->rtti() == 1000 ) {
			RecipeListItem *recipe_it = (RecipeListItem*) it;
			Recipe r;
			r.title = recipe_it->title(); r.recipeID = recipe_it->recipeID();

			//the item is now uncategorized
			removeElement(it,false);
			it->parent() ->takeItem( it );
			if ( !m_uncat_item && curr_offset == 0 )
				m_uncat_item = new UncategorizedItem(this);
			if ( m_uncat_item )
				new RecipeListItem(m_uncat_item,r);
		}
		moveChildrenToRoot( it );
		delete it;
	}
}

#include "recipelistview.moc"
<commit_msg>Show recipes in alphabetical order (like it used to be)<commit_after>/***************************************************************************
*   Copyright (C) 2004 by                                                 *
*   Jason Kivlighn (jkivlighn@gmail.com)                                  *
*   Unai Garro (ugarro@users.sourceforge.net)                             *
*                                                                         *
*   This program is free software; you can redistribute it and/or modify  *
*   it under the terms of the GNU General Public License as published by  *
*   the Free Software Foundation; either version 2 of the License, or     *
*   (at your option) any later version.                                   *
***************************************************************************/

#include "recipelistview.h"

#include <qintdict.h>
#include <qdatastream.h>
#include <qtooltip.h>

#include <kapplication.h>
#include <kdebug.h>
#include <kconfig.h>
#include <kglobal.h>
#include <klocale.h>
#include <kiconloader.h>
#include <kprogress.h>

#include "backends/recipedb.h"

class UncategorizedItem : public QListViewItem
{
public:
	UncategorizedItem( QListView *lv ) : QListViewItem( lv, i18n("Uncategorized") ){}
	int rtti() const { return 1006; }
};

RecipeItemDrag::RecipeItemDrag( RecipeListItem *recipeItem, QWidget *dragSource, const char *name )
		: QStoredDrag( RECIPEITEMMIMETYPE, dragSource, name )
{
	if ( recipeItem ) {
		QByteArray data;
		QDataStream out( data, IO_WriteOnly );
		out << recipeItem->recipeID();
		out << recipeItem->title();
		setEncodedData( data );
	}
}

bool RecipeItemDrag::canDecode( QMimeSource* e )
{
	return e->provides( RECIPEITEMMIMETYPE );
}

bool RecipeItemDrag::decode( const QMimeSource* e, RecipeListItem& item )
{
	if ( !e )
		return false;

	QByteArray data = e->encodedData( RECIPEITEMMIMETYPE );
	if ( data.isEmpty() )
		return false;

	QString title;
	int recipeID;
	QDataStream in( data, IO_ReadOnly );
	in >> recipeID;
	in >> title;

	item.setTitle( title );
	item.setRecipeID( recipeID );

	return true;
}

class RecipeListToolTip : public QToolTip
{
public:
	RecipeListToolTip( RecipeListView *view ) : QToolTip(view->viewport()), m_view(view)
	{}

	void maybeTip( const QPoint &point )
	{
		QListViewItem *item = m_view->itemAt( point );
		if ( item ) {
			QString text = m_view->tooltip(item,0);
			if ( !text.isEmpty() )
				tip( m_view->itemRect( item ), text );
		}
	}

private:
	RecipeListView *m_view;

};

RecipeListView::RecipeListView( QWidget *parent, RecipeDB *db ) : StdCategoryListView( parent, db ),
		flat_list( false ),
		m_uncat_item(0),
		m_progress_dlg(0)
{
	setColumnText( 0, i18n( "Recipe" ) );

	KConfig *config = KGlobal::config(); config->setGroup( "Performance" );
	curr_limit = config->readNumEntry("CategoryLimit",-1);

	KIconLoader il;
	setPixmap( il.loadIcon( "categories", KIcon::NoGroup, 16 ) );

	setSelectionMode( QListView::Extended );

	(void)new RecipeListToolTip(this);
}

void RecipeListView::init()
{
	connect( database, SIGNAL( recipeCreated( const Element &, const ElementList & ) ), SLOT( createRecipe( const Element &, const ElementList & ) ) );
	connect( database, SIGNAL( recipeRemoved( int ) ), SLOT( removeRecipe( int ) ) );
	connect( database, SIGNAL( recipeRemoved( int, int ) ), SLOT( removeRecipe( int, int ) ) );
	connect( database, SIGNAL( recipeModified( const Element &, const ElementList & ) ), SLOT( modifyRecipe( const Element &, const ElementList & ) ) );

	StdCategoryListView::init();
}

QDragObject *RecipeListView::dragObject()
{
	RecipeListItem * item = dynamic_cast<RecipeListItem*>( currentItem() );
	if ( item != 0 ) {
		RecipeItemDrag * obj = new RecipeItemDrag( item, this, "Recipe drag item" );
		/*const QPixmap *pm = item->pixmap(0);
		if( pm )
			obj->setPixmap( *pm );*/
		return obj;
	}
	return 0;
}

bool RecipeListView::acceptDrag( QDropEvent *event ) const
{
	return RecipeItemDrag::canDecode( event );
}

QString RecipeListView::tooltip(QListViewItem *item, int column) const
{
	if ( item->rtti() == RECIPELISTITEM_RTTI ) {
		RecipeListItem *recipe_it = (RecipeListItem*)item;

		Recipe r;
 		database->loadRecipe(&r,RecipeDB::Meta|RecipeDB::Noatime,recipe_it->recipeID() );

		KLocale *locale = KGlobal::locale();

		return QString("%7__________%1 %2
%3 %4
%5 %6")
		   .arg(i18n("Created:")).arg(locale->formatDateTime(r.ctime))
		   .arg(i18n("Modified:")).arg(locale->formatDateTime(r.mtime))
		   .arg(i18n("Last Accessed:")).arg(locale->formatDateTime(r.atime))
		   .arg(recipe_it->title());
	}/* Maybe this would be handy
	else if ( item->rtti() == CATEGORYLISTITEM_RTTI ) {
		CategoryListItem *cat_it = (CategoryListItem*)item;

		return QString("%1
%2: %3")
		   .arg(cat_it->categoryName())
		   .arg(i18n("Recipes"))
		   .arg(QString::number(WHATEVER THE CHILD COUNT IS));
	}*/

	return QString::null;
}

void RecipeListView::load(int limit, int offset)
{
	m_uncat_item = 0;

	if ( flat_list ) {
		ElementList recipeList;
		database->loadRecipeList( &recipeList );

		ElementList::const_iterator recipe_it;
		for ( recipe_it = recipeList.begin();recipe_it != recipeList.end();++recipe_it ) {
			Recipe recipe;
			recipe.recipeID = ( *recipe_it ).id;
			recipe.title = ( *recipe_it ).name;
			createRecipe( recipe, -1 );
		}
	}
	else {
		StdCategoryListView::load(limit,offset);

		if ( offset == 0 ) {
			ElementList recipeList;
			database->loadUncategorizedRecipes( &recipeList );

			ElementList::const_iterator recipe_it;
			for ( recipe_it = recipeList.begin();recipe_it != recipeList.end();++recipe_it ) {
				Recipe recipe;
				recipe.recipeID = ( *recipe_it ).id;
				recipe.title = ( *recipe_it ).name;
				createRecipe( recipe, -1 );
			}
		}
	}
}

void RecipeListView::populate( QListViewItem *item )
{
	CategoryItemInfo *cat_item = dynamic_cast<CategoryItemInfo*>(item);
	if ( !cat_item || cat_item->isPopulated() ) return;

	delete item->firstChild(); //delete the "pseudo item"

	if ( m_progress_dlg ){
		m_progress_dlg->progressBar()->advance(1);
		kapp->processEvents();
	}

	StdCategoryListView::populate(item);

	if ( !flat_list ) {
		int id = cat_item->categoryId();

		// Now show the recipes
		ElementList recipeList;
		database->loadRecipeList( &recipeList, id );

		ElementList::const_iterator recipe_it;
		for ( recipe_it = recipeList.begin(); recipe_it != recipeList.end(); ++recipe_it ) {
			Recipe recipe;
			recipe.recipeID = ( *recipe_it ).id;
			recipe.title = ( *recipe_it ).name;
			createRecipe( recipe, id );
		}
	}
}

void RecipeListView::populateAll( QListViewItem *parent )
{
	bool first = false;
	if ( !parent ) {
		first = true;
		m_progress_dlg = new KProgressDialog(this,"populate_all_prog_dlg",QString::null,i18n("Loading recipes"),true);
		m_progress_dlg->setAllowCancel(false);
		m_progress_dlg->progressBar()->setTotalSteps(0);
		m_progress_dlg->progressBar()->setPercentageVisible(false);

		m_progress_dlg->grabKeyboard(); //don't let the user keep hitting keys

		parent = firstChild();
	}
	else {
		populate( parent );
		parent = parent->firstChild();
	}

	for ( QListViewItem *item = parent; item; item = item->nextSibling() ) {
		if ( m_progress_dlg && m_progress_dlg->wasCancelled() )
			break;

		populateAll( item );
	}

	if ( first ) {
		delete m_progress_dlg;
		m_progress_dlg = 0;
	}
}

void RecipeListView::createRecipe( const Recipe &recipe, int parent_id )
{
	if ( parent_id == -1 ) {
		if ( !m_uncat_item && curr_offset == 0 ) {
			m_uncat_item = new UncategorizedItem(this);
			if ( childCount() == 1 ) 		//only call createElement if this is the only item in the list
				createElement(m_uncat_item);	//otherwise, this item won't stay at the top
		}

		if ( m_uncat_item )
			new RecipeListItem( m_uncat_item, recipe );
	}
	else {
		CategoryListItem *parent = (CategoryListItem*)items_map[ parent_id ];
		if ( parent && parent->isPopulated() )
			createElement(new RecipeListItem( parent, recipe ));
	}
}

void RecipeListView::createRecipe( const Element &recipe_el, const ElementList &categories )
{
	Recipe recipe;
	recipe.recipeID = recipe_el.id;
	recipe.title = recipe_el.name;

	if ( categories.count() == 0 ) {
		createRecipe( recipe, -1 );
	}
	else {
		for ( ElementList::const_iterator cat_it = categories.begin(); cat_it != categories.end(); ++cat_it ) {
			int cur_cat_id = ( *cat_it ).id;

			QListViewItemIterator iterator( this );
			while ( iterator.current() ) {
				if ( iterator.current() ->rtti() == 1001 ) {
					CategoryListItem * cat_item = ( CategoryListItem* ) iterator.current();
					if ( cat_item->categoryId() == cur_cat_id ) {
						createRecipe( recipe, cur_cat_id );
					}
				}
				++iterator;
			}
		}
	}
}

void RecipeListView::createElement( QListViewItem *item )
{
	CategoryItemInfo *cat_item = dynamic_cast<CategoryItemInfo*>(item);

	#if 0
	ElementList list;
	database->loadRecipeList( &list, cat_item->categoryId() );
	if ( list.count() > 0 )
	#endif
	if ( cat_item )
		new PseudoListItem( item );

	CategoryListView::createElement(item);
}

void RecipeListView::modifyRecipe( const Element &recipe, const ElementList &categories )
{
	removeRecipe( recipe.id );
	createRecipe( recipe, categories );
}

void RecipeListView::removeRecipe( int id )
{
	QListViewItemIterator iterator( this );
	while ( iterator.current() ) {
		if ( iterator.current() ->rtti() == 1000 ) {
			RecipeListItem * recipe_it = ( RecipeListItem* ) iterator.current();
			if ( recipe_it->recipeID() == id ) {
				removeElement(recipe_it);

				//delete the "Uncategorized" item if we removed the last recipe that was under it
				if ( m_uncat_item->childCount() == 0 ) {
					delete m_uncat_item;
					m_uncat_item = 0;
				}
			}
		}
		++iterator;
	}
}

void RecipeListView::removeRecipe( int recipe_id, int cat_id )
{
	QListViewItem * item = items_map[ cat_id ];

	//find out if this is the only category the recipe belongs to
	int finds = 0;
	QListViewItemIterator iterator( this );
	while ( iterator.current() ) {
		if ( iterator.current() ->rtti() == 1000 ) {
			RecipeListItem * recipe_it = ( RecipeListItem* ) iterator.current();

			if ( recipe_it->recipeID() == recipe_id ) {
				if ( finds > 1 )
					break;
				finds++;
			}
		}
		++iterator;
	}

	//do this to only iterate over children of 'item'
	QListViewItem *pEndItem = NULL;
	QListViewItem *pStartItem = item;
	do {
		if ( pStartItem->nextSibling() )
			pEndItem = pStartItem->nextSibling();
		else
			pStartItem = pStartItem->parent();
	}
	while ( pStartItem && !pEndItem );

	iterator = QListViewItemIterator( item );
	while ( iterator.current() != pEndItem ) {
		if ( iterator.current() ->rtti() == 1000 ) {
			RecipeListItem * recipe_it = ( RecipeListItem* ) iterator.current();

			if ( recipe_it->recipeID() == recipe_id ) {

				if ( finds == 1 ) {
					//the item is now uncategorized
					if ( !m_uncat_item && curr_offset == 0 )
						m_uncat_item = new UncategorizedItem(this);
					if ( m_uncat_item ) {
						Recipe r;
						r.title = recipe_it->title(); r.recipeID = recipe_id;
						new RecipeListItem(m_uncat_item,r);
					}
				}
				removeElement(recipe_it);
				break;
			}
		}
		++iterator;
	}
}

void RecipeListView::removeCategory( int id )
{
	QListViewItem * item = items_map[ id ];
	if ( !item )
		return ; //this may have been deleted already by its parent being deleted

	moveChildrenToRoot( item );

	StdCategoryListView::removeCategory( id );
}

void RecipeListView::moveChildrenToRoot( QListViewItem *item )
{
	QListViewItem * next_sibling;
	for ( QListViewItem * it = item->firstChild(); it; it = next_sibling ) {
		next_sibling = it->nextSibling();
		if ( it->rtti() == 1000 ) {
			RecipeListItem *recipe_it = (RecipeListItem*) it;
			Recipe r;
			r.title = recipe_it->title(); r.recipeID = recipe_it->recipeID();

			//the item is now uncategorized
			removeElement(it,false);
			it->parent() ->takeItem( it );
			if ( !m_uncat_item && curr_offset == 0 )
				m_uncat_item = new UncategorizedItem(this);
			if ( m_uncat_item )
				new RecipeListItem(m_uncat_item,r);
		}
		moveChildrenToRoot( it );
		delete it;
	}
}

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


<commit_before>/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/*
 * Copyright 2015 Cloudius Systems
 *
 * Modified by Cloudius Systems
 */

#pragma once

#include "types.hh"
#include <algorithm>

namespace sstables {

static constexpr int TOMBSTONE_HISTOGRAM_BIN_SIZE = 100;

/**
 * ColumnStats holds information about the columns for one row inside sstable
 */
struct column_stats {
    /** how many columns are there in the row */
    uint64_t column_count;

    uint64_t start_offset;
    uint64_t row_size;

    /** the largest (client-supplied) timestamp in the row */
    uint64_t min_timestamp;
    uint64_t max_timestamp;
    int max_local_deletion_time;
    /** histogram of tombstone drop time */
    streaming_histogram tombstone_histogram;

    /** max and min column names according to comparator */
    std::vector<bytes> min_column_names;
    std::vector<bytes> max_column_names;

    bool has_legacy_counter_shards;

    column_stats() {
        column_count = 0;
        start_offset = 0;
        row_size = 0;
        min_timestamp = std::numeric_limits<uint64_t>::max();
        max_timestamp = std::numeric_limits<uint64_t>::min();
        max_local_deletion_time = std::numeric_limits<int>::min();
        tombstone_histogram = streaming_histogram(TOMBSTONE_HISTOGRAM_BIN_SIZE);
        has_legacy_counter_shards = false;
    }

    void reset() {
        *this = column_stats();
    }

    void update_min_timestamp(uint64_t potential_min) {
        min_timestamp = std::min(min_timestamp, potential_min);
    }
    void update_max_timestamp(uint64_t potential_max) {
        max_timestamp = std::max(max_timestamp, potential_max);
    }
    void update_max_local_deletion_time(int potential_value) {
        max_local_deletion_time = std::max(max_local_deletion_time, potential_value);
    }

};

class metadata_collector {
public:
    static constexpr double NO_COMPRESSION_RATIO = -1.0;

    static estimated_histogram default_column_count_histogram() {
        // EH of 114 can track a max value of 2395318855, i.e., > 2B columns
        return estimated_histogram(114);
    }

    static estimated_histogram default_row_size_histogram() {
        // EH of 150 can track a max value of 1697806495183, i.e., > 1.5PB
        return estimated_histogram(150);
    }

    static streaming_histogram default_tombstone_drop_time_histogram() {
        return streaming_histogram(TOMBSTONE_HISTOGRAM_BIN_SIZE);
    }

    static replay_position replay_position_none() {
        // Cassandra says the following about replay position none:
        // NONE is used for SSTables that are streamed from other nodes and thus have no relationship
        // with our local commitlog. The values satisfy the critera that
        //  - no real commitlog segment will have the given id
        //  - it will sort before any real replayposition, so it will be effectively ignored by getReplayPosition
        return replay_position(-1UL, 0U);
    }
private:
    estimated_histogram _estimated_row_size = default_row_size_histogram();
    estimated_histogram _estimated_column_count = default_column_count_histogram();
    replay_position _replay_position = replay_position_none();
    uint64_t _min_timestamp = std::numeric_limits<uint64_t>::max();
    uint64_t _max_timestamp = std::numeric_limits<uint64_t>::min();
    uint64_t _repaired_at = 0;
    int _max_local_deletion_time = std::numeric_limits<int>::min();
    double _compression_ratio = NO_COMPRESSION_RATIO;
    // FIXME: add C++ version of protected Set<Integer> ancestors = new HashSet<>();
    streaming_histogram _estimated_tombstone_drop_time = default_tombstone_drop_time_histogram();
    int _sstable_level = 0;
    std::vector<bytes> _min_column_names;
    std::vector<bytes> _max_column_names;
    bool _has_legacy_counter_shards = false;
private:
    /*
     * Convert a vector of bytes into a disk array of disk_string<uint16_t>.
     */
    static void convert(disk_array<uint32_t, disk_string<uint16_t>>&to, std::vector<bytes>&& from) {
        to.elements.resize(from.size());
        for (auto i = 0U; i < from.size(); i++) {
            to.elements[i].value = std::move(from[i]);
        }
    }
public:
    void add_row_size(uint64_t row_size) {
        _estimated_row_size.add(row_size);
    }

    void add_column_count(uint64_t column_count) {
        _estimated_column_count.add(column_count);
    }

    void merge_tombstone_histogram(streaming_histogram& histogram) {
        _estimated_tombstone_drop_time.merge(histogram);
    }

    /**
     * Ratio is compressed/uncompressed and it is
     * if you have 1.x then compression isn't helping
     */
    void add_compression_ratio(uint64_t compressed, uint64_t uncompressed) {
        _compression_ratio = (double) compressed/uncompressed;
    }

    void update_min_timestamp(uint64_t potential_min) {
        _min_timestamp = std::min(_min_timestamp, potential_min);
    }

    void update_max_timestamp(uint64_t potential_max) {
        _max_timestamp = std::max(_max_timestamp, potential_max);
    }

    void update_max_local_deletion_time(int max_local_deletion_time) {
        _max_local_deletion_time = std::max(_max_local_deletion_time, max_local_deletion_time);
    }

    void set_replay_position(replay_position rp) {
        _replay_position = rp;
    }

    void set_repaired_at(uint64_t repaired_at) {
        _repaired_at = repaired_at;
    }

    void sstable_level(int sstable_level) {
        _sstable_level = sstable_level;
    }

    void update_min_column_names(std::vector<bytes>& min_column_names) {
        if (min_column_names.size() > 0) {
            column_name_helper::merge_min_components(_min_column_names, std::move(min_column_names));
        }
    }

    void update_max_column_names(std::vector<bytes>& max_column_names) {
        if (max_column_names.size() > 0) {
            column_name_helper::merge_max_components(_max_column_names, std::move(max_column_names));
        }
    }

    void update_has_legacy_counter_shards(bool has_legacy_counter_shards) {
        _has_legacy_counter_shards = _has_legacy_counter_shards || has_legacy_counter_shards;
    }

    void update(column_stats& stats) {
        update_min_timestamp(stats.min_timestamp);
        update_max_timestamp(stats.max_timestamp);
        update_max_local_deletion_time(stats.max_local_deletion_time);
        add_row_size(stats.row_size);
        add_column_count(stats.column_count);
        merge_tombstone_histogram(stats.tombstone_histogram);
        update_min_column_names(stats.min_column_names);
        update_max_column_names(stats.max_column_names);
        update_has_legacy_counter_shards(stats.has_legacy_counter_shards);
    }

    void construct_stats(stats_metadata& m) {
        m.estimated_row_size = std::move(_estimated_row_size);
        m.estimated_column_count = std::move(_estimated_column_count);
        m.position = _replay_position;
        m.min_timestamp = _min_timestamp;
        m.max_timestamp = _max_timestamp;
        m.max_local_deletion_time = _max_local_deletion_time;
        m.compression_ratio = _compression_ratio;
        m.estimated_tombstone_drop_time = std::move(_estimated_tombstone_drop_time);
        m.sstable_level = _sstable_level;
        m.repaired_at = _repaired_at;
        convert(m.min_column_names, std::move(_min_column_names));
        convert(m.max_column_names, std::move(_max_column_names));
        m.has_legacy_counter_shards = _has_legacy_counter_shards;
    }
};

}

<commit_msg>sstables: extend metadata collector to add ancestors<commit_after>/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/*
 * Copyright 2015 Cloudius Systems
 *
 * Modified by Cloudius Systems
 */

#pragma once

#include "types.hh"
#include <algorithm>

namespace sstables {

static constexpr int TOMBSTONE_HISTOGRAM_BIN_SIZE = 100;

/**
 * ColumnStats holds information about the columns for one row inside sstable
 */
struct column_stats {
    /** how many columns are there in the row */
    uint64_t column_count;

    uint64_t start_offset;
    uint64_t row_size;

    /** the largest (client-supplied) timestamp in the row */
    uint64_t min_timestamp;
    uint64_t max_timestamp;
    int max_local_deletion_time;
    /** histogram of tombstone drop time */
    streaming_histogram tombstone_histogram;

    /** max and min column names according to comparator */
    std::vector<bytes> min_column_names;
    std::vector<bytes> max_column_names;

    bool has_legacy_counter_shards;

    column_stats() {
        column_count = 0;
        start_offset = 0;
        row_size = 0;
        min_timestamp = std::numeric_limits<uint64_t>::max();
        max_timestamp = std::numeric_limits<uint64_t>::min();
        max_local_deletion_time = std::numeric_limits<int>::min();
        tombstone_histogram = streaming_histogram(TOMBSTONE_HISTOGRAM_BIN_SIZE);
        has_legacy_counter_shards = false;
    }

    void reset() {
        *this = column_stats();
    }

    void update_min_timestamp(uint64_t potential_min) {
        min_timestamp = std::min(min_timestamp, potential_min);
    }
    void update_max_timestamp(uint64_t potential_max) {
        max_timestamp = std::max(max_timestamp, potential_max);
    }
    void update_max_local_deletion_time(int potential_value) {
        max_local_deletion_time = std::max(max_local_deletion_time, potential_value);
    }

};

class metadata_collector {
public:
    static constexpr double NO_COMPRESSION_RATIO = -1.0;

    static estimated_histogram default_column_count_histogram() {
        // EH of 114 can track a max value of 2395318855, i.e., > 2B columns
        return estimated_histogram(114);
    }

    static estimated_histogram default_row_size_histogram() {
        // EH of 150 can track a max value of 1697806495183, i.e., > 1.5PB
        return estimated_histogram(150);
    }

    static streaming_histogram default_tombstone_drop_time_histogram() {
        return streaming_histogram(TOMBSTONE_HISTOGRAM_BIN_SIZE);
    }

    static replay_position replay_position_none() {
        // Cassandra says the following about replay position none:
        // NONE is used for SSTables that are streamed from other nodes and thus have no relationship
        // with our local commitlog. The values satisfy the critera that
        //  - no real commitlog segment will have the given id
        //  - it will sort before any real replayposition, so it will be effectively ignored by getReplayPosition
        return replay_position(-1UL, 0U);
    }
private:
    estimated_histogram _estimated_row_size = default_row_size_histogram();
    estimated_histogram _estimated_column_count = default_column_count_histogram();
    replay_position _replay_position = replay_position_none();
    uint64_t _min_timestamp = std::numeric_limits<uint64_t>::max();
    uint64_t _max_timestamp = std::numeric_limits<uint64_t>::min();
    uint64_t _repaired_at = 0;
    int _max_local_deletion_time = std::numeric_limits<int>::min();
    double _compression_ratio = NO_COMPRESSION_RATIO;
    std::set<int> _ancestors;
    streaming_histogram _estimated_tombstone_drop_time = default_tombstone_drop_time_histogram();
    int _sstable_level = 0;
    std::vector<bytes> _min_column_names;
    std::vector<bytes> _max_column_names;
    bool _has_legacy_counter_shards = false;
private:
    /*
     * Convert a vector of bytes into a disk array of disk_string<uint16_t>.
     */
    static void convert(disk_array<uint32_t, disk_string<uint16_t>>&to, std::vector<bytes>&& from) {
        to.elements.resize(from.size());
        for (auto i = 0U; i < from.size(); i++) {
            to.elements[i].value = std::move(from[i]);
        }
    }
public:
    void add_row_size(uint64_t row_size) {
        _estimated_row_size.add(row_size);
    }

    void add_column_count(uint64_t column_count) {
        _estimated_column_count.add(column_count);
    }

    void merge_tombstone_histogram(streaming_histogram& histogram) {
        _estimated_tombstone_drop_time.merge(histogram);
    }

    /**
     * Ratio is compressed/uncompressed and it is
     * if you have 1.x then compression isn't helping
     */
    void add_compression_ratio(uint64_t compressed, uint64_t uncompressed) {
        _compression_ratio = (double) compressed/uncompressed;
    }

    void update_min_timestamp(uint64_t potential_min) {
        _min_timestamp = std::min(_min_timestamp, potential_min);
    }

    void update_max_timestamp(uint64_t potential_max) {
        _max_timestamp = std::max(_max_timestamp, potential_max);
    }

    void update_max_local_deletion_time(int max_local_deletion_time) {
        _max_local_deletion_time = std::max(_max_local_deletion_time, max_local_deletion_time);
    }

    void set_replay_position(replay_position rp) {
        _replay_position = rp;
    }

    void set_repaired_at(uint64_t repaired_at) {
        _repaired_at = repaired_at;
    }

    void add_ancestor(int generation) {
        _ancestors.insert(generation);
    }

    void sstable_level(int sstable_level) {
        _sstable_level = sstable_level;
    }

    void update_min_column_names(std::vector<bytes>& min_column_names) {
        if (min_column_names.size() > 0) {
            column_name_helper::merge_min_components(_min_column_names, std::move(min_column_names));
        }
    }

    void update_max_column_names(std::vector<bytes>& max_column_names) {
        if (max_column_names.size() > 0) {
            column_name_helper::merge_max_components(_max_column_names, std::move(max_column_names));
        }
    }

    void update_has_legacy_counter_shards(bool has_legacy_counter_shards) {
        _has_legacy_counter_shards = _has_legacy_counter_shards || has_legacy_counter_shards;
    }

    void update(column_stats& stats) {
        update_min_timestamp(stats.min_timestamp);
        update_max_timestamp(stats.max_timestamp);
        update_max_local_deletion_time(stats.max_local_deletion_time);
        add_row_size(stats.row_size);
        add_column_count(stats.column_count);
        merge_tombstone_histogram(stats.tombstone_histogram);
        update_min_column_names(stats.min_column_names);
        update_max_column_names(stats.max_column_names);
        update_has_legacy_counter_shards(stats.has_legacy_counter_shards);
    }

    void construct_stats(stats_metadata& m) {
        m.estimated_row_size = std::move(_estimated_row_size);
        m.estimated_column_count = std::move(_estimated_column_count);
        m.position = _replay_position;
        m.min_timestamp = _min_timestamp;
        m.max_timestamp = _max_timestamp;
        m.max_local_deletion_time = _max_local_deletion_time;
        m.compression_ratio = _compression_ratio;
        m.estimated_tombstone_drop_time = std::move(_estimated_tombstone_drop_time);
        m.sstable_level = _sstable_level;
        m.repaired_at = _repaired_at;
        convert(m.min_column_names, std::move(_min_column_names));
        convert(m.max_column_names, std::move(_max_column_names));
        m.has_legacy_counter_shards = _has_legacy_counter_shards;
    }
};

}

<|endoftext|>


<commit_before>#ifndef STAN_MATH_GPU_KERNELS_COPY_HPP
#define STAN_MATH_GPU_KERNELS_COPY_HPP
#ifdef STAN_OPENCL

#include <stan/math/gpu/kernel_cl.hpp>

namespace stan {
namespace math {
namespace opencl_kernels {
// \cond
const char *copy_kernel_code = STRINGIFY(
    // \endcond
    /**
     * Copy one matrix to another
     * @param[in] A The matrix to copy.
     * @param[out] B The matrix to copy A to.
     * @param rows The number of rows in A.
     * @param cols The number of cols in A.
     * @note Code is a const char* held in
     * copy_kernel_code.
     * Kernel used in math/gpu/matrix_gpu.hpp.
     *  This kernel uses the helper macros available in helpers.cl.
     */
    __kernel void copy(__global double *A, __global double *B,
                       unsigned int rows, unsigned int cols) {
      int i = get_global_id(0);
      int j = get_global_id(1);
      if (i < rows && j < cols) {
        B(i, j) = A(i, j);
      }
    }
    // \cond
);
// \endcond

/**
 * See the docs for \link kernels/copy.hpp copy() \endlink
 */
const global_range_kernel<cl::Buffer, cl::Buffer, int, int> copy(
    "copy", copy_kernel_code);

}  // namespace opencl_kernels
}  // namespace math
}  // namespace stan
#endif
#endif
<commit_msg>cpplint fix<commit_after>#ifndef STAN_MATH_GPU_KERNELS_COPY_HPP
#define STAN_MATH_GPU_KERNELS_COPY_HPP
#ifdef STAN_OPENCL

#include <stan/math/gpu/kernel_cl.hpp>
#include <algorithm>

namespace stan {
namespace math {
namespace opencl_kernels {
// \cond
const char *copy_kernel_code = STRINGIFY(
    // \endcond
    /**
     * Copy one matrix to another
     * @param[in] A The matrix to copy.
     * @param[out] B The matrix to copy A to.
     * @param rows The number of rows in A.
     * @param cols The number of cols in A.
     * @note Code is a const char* held in
     * copy_kernel_code.
     * Kernel used in math/gpu/matrix_gpu.hpp.
     *  This kernel uses the helper macros available in helpers.cl.
     */
    __kernel void copy(__global double *A, __global double *B,
                       unsigned int rows, unsigned int cols) {
      int i = get_global_id(0);
      int j = get_global_id(1);
      if (i < rows && j < cols) {
        B(i, j) = A(i, j);
      }
    }
    // \cond
);
// \endcond

/**
 * See the docs for \link kernels/copy.hpp copy() \endlink
 */
const global_range_kernel<cl::Buffer, cl::Buffer, int, int> copy(
    "copy", copy_kernel_code);

}  // namespace opencl_kernels
}  // namespace math
}  // namespace stan
#endif
#endif
<|endoftext|>


<commit_before><commit_msg>migrate ImpNumberFill implementation to OUStringBuffer<commit_after><|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: connctrl.cxx,v $
 *
 *  $Revision: 1.13 $
 *
 *  last change: $Author: hr $ $Date: 2007-06-27 16:54:09 $
 *
 *  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
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_svx.hxx"

// include ---------------------------------------------------------------

#include <svx/xoutx.hxx>

#include <svx/svdoedge.hxx>
#include <svx/svdattrx.hxx>

#ifndef _SVDMARK_HXX //autogen
#include <svx/svdmark.hxx>
#endif
#ifndef _SVDVIEW_HXX //autogen
#include <svx/svdview.hxx>
#endif

#include <svx/svdpage.hxx> // SdrObjList

#include "connctrl.hxx"
#include <svx/dialmgr.hxx>
#include "dlgutil.hxx"

// #110094#
#ifndef _SDR_CONTACT_OBJECTCONTACTOFOBJLISTPAINTER_HXX
#include <svx/sdr/contact/objectcontactofobjlistpainter.hxx>
#endif

// #110094#
#ifndef _SDR_CONTACT_DISPLAYINFO_HXX
#include <svx/sdr/contact/displayinfo.hxx>
#endif

#ifndef _SV_SVAPP_HXX
#include <vcl/svapp.hxx>
#endif

/*************************************************************************
|*
|* Ctor SvxXConnectionPreview
|*
*************************************************************************/

SvxXConnectionPreview::SvxXConnectionPreview( Window* pParent, const ResId& rResId,
                            const SfxItemSet& rInAttrs ) :
                            Control ( pParent, rResId ),
                            rAttrs  ( rInAttrs ),
                            pEdgeObj( NULL ),
                            pObjList( NULL ),
                            pView   ( NULL )
{
    pExtOutDev = new XOutputDevice( this );

    SetMapMode( MAP_100TH_MM );

    SetStyles();
}

/*************************************************************************
|*
|* Dtor SvxXConnectionPreview
|*
*************************************************************************/

SvxXConnectionPreview::~SvxXConnectionPreview()
{
    delete pObjList;
    delete pExtOutDev;
}

/*************************************************************************
|*
|* Dtor SvxXConnectionPreview
|*
*************************************************************************/

void SvxXConnectionPreview::Construct()
{
    DBG_ASSERT( pView, "Keine gueltige View Uebergeben!" );

    const SdrMarkList& rMarkList = pView->GetMarkedObjectList();
    ULONG nMarkCount = rMarkList.GetMarkCount();

    if( nMarkCount >= 1 )
    {
        BOOL bFound = FALSE;
        const SdrObject* pObj = rMarkList.GetMark(0)->GetMarkedSdrObj();

        for( USHORT i = 0; i < nMarkCount && !bFound; i++ )
        {
            pObj = rMarkList.GetMark( i )->GetMarkedSdrObj();
            UINT32 nInv = pObj->GetObjInventor();
            UINT16 nId = pObj->GetObjIdentifier();
            if( nInv == SdrInventor && nId == OBJ_EDGE )
            {
                bFound = TRUE;
                SdrEdgeObj* pTmpEdgeObj = (SdrEdgeObj*) pObj;
                pEdgeObj = (SdrEdgeObj*) pTmpEdgeObj->Clone();

                SdrObjConnection& rConn1 = (SdrObjConnection&)pEdgeObj->GetConnection( TRUE );
                SdrObjConnection& rConn2 = (SdrObjConnection&)pEdgeObj->GetConnection( FALSE );

                rConn1 = pTmpEdgeObj->GetConnection( TRUE );
                rConn2 = pTmpEdgeObj->GetConnection( FALSE );

                SdrObject* pTmpObj1 = pTmpEdgeObj->GetConnectedNode( TRUE );
                SdrObject* pTmpObj2 = pTmpEdgeObj->GetConnectedNode( FALSE );

                // #110094#
                // potential memory leak here (!). Create SdrObjList only when there is
                // not yet one.
                if(!pObjList)
                {
                    pObjList = new SdrObjList( pView->GetModel(), NULL );
                }

                if( pTmpObj1 )
                {
                    SdrObject* pObj1 = pTmpObj1->Clone();
                    pObjList->InsertObject( pObj1 );
                    pEdgeObj->ConnectToNode( TRUE, pObj1 );
                }
                if( pTmpObj2 )
                {
                    SdrObject* pObj2 = pTmpObj2->Clone();
                    pObjList->InsertObject( pObj2 );
                    pEdgeObj->ConnectToNode( FALSE, pObj2 );
                }
                pObjList->InsertObject( pEdgeObj );
            }
        }
    }

    if( !pEdgeObj )
        pEdgeObj = new SdrEdgeObj();

    // Groesse anpassen
    if( pObjList )
    {
        OutputDevice* pOD = pView->GetFirstOutputDevice(); // GetWin( 0 );
        Rectangle aRect = pObjList->GetAllObjBoundRect();

        MapMode aMapMode = GetMapMode();
        aMapMode.SetMapUnit( pOD->GetMapMode().GetMapUnit() );
        SetMapMode( aMapMode );

        MapMode         aDisplayMap( aMapMode );
        Point           aNewPos;
        Size            aNewSize;
        const Size      aWinSize = PixelToLogic( GetOutputSizePixel(), aDisplayMap );
        const long      nWidth = aWinSize.Width();
        const long      nHeight = aWinSize.Height();
        double          fRectWH = (double) aRect.GetWidth() / aRect.GetHeight();
        double          fWinWH = (double) nWidth / nHeight;

        // Bitmap an Thumbgroesse anpassen (hier nicht!)
        if ( fRectWH < fWinWH)
        {
            aNewSize.Width() = (long) ( (double) nHeight * fRectWH );
            aNewSize.Height()= nHeight;
        }
        else
        {
            aNewSize.Width() = nWidth;
            aNewSize.Height()= (long) ( (double) nWidth / fRectWH );
        }

        Fraction aFrac1( aWinSize.Width(), aRect.GetWidth() );
        Fraction aFrac2( aWinSize.Height(), aRect.GetHeight() );
        Fraction aMinFrac( aFrac1 <= aFrac2 ? aFrac1 : aFrac2 );

        // MapMode umsetzen
        aDisplayMap.SetScaleX( aMinFrac );
        aDisplayMap.SetScaleY( aMinFrac );

        // Zentrierung
        aNewPos.X() = ( nWidth - aNewSize.Width() )  >> 1;
        aNewPos.Y() = ( nHeight - aNewSize.Height() ) >> 1;

        aDisplayMap.SetOrigin( LogicToLogic( aNewPos, aMapMode, aDisplayMap ) );
        SetMapMode( aDisplayMap );

        // Ursprung
        aNewPos = aDisplayMap.GetOrigin();
        aNewPos -= Point( aRect.TopLeft().X(), aRect.TopLeft().Y() );
        aDisplayMap.SetOrigin( aNewPos );
        SetMapMode( aDisplayMap );

        Point aPos;
        MouseEvent aMEvt( aPos, 1, 0, MOUSE_RIGHT );
        MouseButtonDown( aMEvt );
        /*
        Point aPt( -aRect.TopLeft().X(), -aRect.TopLeft().Y() );
        aMapMode.SetOrigin( aPt );

        // Skalierung
        Size aSize = GetOutputSize();
        Fraction aFrac1( aSize.Width(), aRect.GetWidth() );
        Fraction aFrac2( aSize.Height(), aRect.GetHeight() );
        Fraction aMaxFrac( aFrac1 > aFrac2 ? aFrac1 : aFrac2 );
        Fraction aMinFrac( aFrac1 <= aFrac2 ? aFrac1 : aFrac2 );
        BOOL bChange = (BOOL) ( (double)aMinFrac > 1.0 );
        aMapMode.SetScaleX( aMinFrac );
        aMapMode.SetScaleY( aMinFrac );

        // zentrieren
        long nXXL = aSize.Width() > aRect.GetWidth() ? aSize.Width() : aRect.GetWidth();
        long nXS = aSize.Width() <= aRect.GetWidth() ? aSize.Width() : aRect.GetWidth();
        if( bChange )
        {
            long nTmp = nXXL; nXXL = nXS; nXS = nTmp;
        }
        long nX = (long) ( (double)aMinFrac * (double)nXXL );
        nX = (long) ( (double)labs( nXS - nX ) / (double)aMinFrac / 2.0 );

        long nYXL = aSize.Height() > aRect.GetHeight() ? aSize.Height() : aRect.GetHeight();
        long nYS = aSize.Height() <= aRect.GetHeight() ? aSize.Height() : aRect.GetHeight();
        if( bChange )
        {
            long nTmp = nXXL; nXXL = nXS; nXS = nTmp;
        }
        long nY = (long) ( (double)aMinFrac * (double)nYXL );
        nY = (long) ( (double)labs( nYS - nY ) / (double)aMinFrac / 2.0 );

        aPt += Point( nX, nY );
        aMapMode.SetOrigin( aPt );

        SetMapMode( aMapMode );
        */
    }
}

/*************************************************************************
|*
|* SvxXConnectionPreview: Paint()
|*
*************************************************************************/

void SvxXConnectionPreview::Paint( const Rectangle& )
{
    SdrPaintInfoRec aInfoRec;

    //pEdgeObj->Paint( *pExtOutDev, aInfoRec );
    if( pObjList )
    {
        // #110094#
        // This will not work anymore. To not start at Adam and Eve, i will
        // ATM not try to change all this stuff to really using an own model
        // and a view. I will just try to provide a mechanism to paint such
        // objects without own model and without a page/view with the new
        // mechanism.
        //
        //pObjList->Paint( *pExtOutDev, aInfoRec );

        // New stuff: Use a ObjectContactOfObjListPainter.
        sdr::contact::SdrObjectVector aObjectVector;

        for(sal_uInt32 a(0L); a < pObjList->GetObjCount(); a++)
        {
            SdrObject* pObject = pObjList->GetObj(a);
            DBG_ASSERT(pObject,
                "SvxXConnectionPreview::Paint: Corrupt ObjectList (!)");
            aObjectVector.push_back(pObject);
        }

        sdr::contact::ObjectContactOfObjListPainter aPainter(aObjectVector);
        sdr::contact::DisplayInfo aDisplayInfo;

        aDisplayInfo.SetExtendedOutputDevice(pExtOutDev);
        aDisplayInfo.SetPaintInfoRec(&aInfoRec);
        aDisplayInfo.SetOutputDevice(pExtOutDev->GetOutDev());

        // do processing
        aPainter.ProcessDisplay(aDisplayInfo);

        // prepare delete
        aPainter.PrepareDelete();
    }
}

/*************************************************************************
|*
|* SvxXConnectionPreview: SetAttributes()
|*
*************************************************************************/

void SvxXConnectionPreview::SetAttributes( const SfxItemSet& rInAttrs )
{
    //pEdgeObj->SetItemSetAndBroadcast(rInAttrs);
    pEdgeObj->SetMergedItemSetAndBroadcast(rInAttrs);

    Invalidate();
}

/*************************************************************************
|*
|* Ermittelt die Anzahl der Linienversaetze anhand des Preview-Objektes
|*
*************************************************************************/

USHORT SvxXConnectionPreview::GetLineDeltaAnz()
{
    const SfxItemSet& rSet = pEdgeObj->GetMergedItemSet();
    sal_uInt16 nCount(0);

    if(SFX_ITEM_DONTCARE != rSet.GetItemState(SDRATTR_EDGELINEDELTAANZ))
        nCount = ((const SdrEdgeLineDeltaAnzItem&)rSet.Get(SDRATTR_EDGELINEDELTAANZ)).GetValue();

    return nCount;
}

/*************************************************************************
|*
|* SvxXConnectionPreview: MouseButtonDown()
|*
*************************************************************************/

void SvxXConnectionPreview::MouseButtonDown( const MouseEvent& rMEvt )
{
    BOOL bZoomIn  = rMEvt.IsLeft() && !rMEvt.IsShift();
    BOOL bZoomOut = rMEvt.IsRight() || rMEvt.IsShift();
    BOOL bCtrl    = rMEvt.IsMod1();

    if( bZoomIn || bZoomOut )
    {
        MapMode aMapMode = GetMapMode();
        Fraction aXFrac = aMapMode.GetScaleX();
        Fraction aYFrac = aMapMode.GetScaleY();
        Fraction* pMultFrac;

        if( bZoomIn )
        {
            if( bCtrl )
                pMultFrac = new Fraction( 3, 2 );
            else
                pMultFrac = new Fraction( 11, 10 );
        }
        else
        {
            if( bCtrl )
                pMultFrac = new Fraction( 2, 3 );
            else
                pMultFrac = new Fraction( 10, 11 );
        }

        aXFrac *= *pMultFrac;
        aYFrac *= *pMultFrac;
        if( (double)aXFrac > 0.001 && (double)aXFrac < 1000.0 &&
            (double)aYFrac > 0.001 && (double)aYFrac < 1000.0 )
        {
            aMapMode.SetScaleX( aXFrac );
            aMapMode.SetScaleY( aYFrac );
            SetMapMode( aMapMode );

            Size aOutSize( GetOutputSize() );

            Point aPt( aMapMode.GetOrigin() );
            long nX = (long)( ( (double)aOutSize.Width() - ( (double)aOutSize.Width() * (double)*pMultFrac  ) ) / 2.0 + 0.5 );
            long nY = (long)( ( (double)aOutSize.Height() - ( (double)aOutSize.Height() * (double)*pMultFrac  ) ) / 2.0 + 0.5 );
            aPt.X() +=  nX;
            aPt.Y() +=  nY;

            aMapMode.SetOrigin( aPt );
            SetMapMode( aMapMode );

            Invalidate();
        }
        delete pMultFrac;
    }
}

void SvxXConnectionPreview::SetStyles()
{
    const StyleSettings& rStyles = Application::GetSettings().GetStyleSettings();
    SetDrawMode( GetDisplayBackground().GetColor().IsDark() ? OUTPUT_DRAWMODE_CONTRAST : OUTPUT_DRAWMODE_COLOR );
    SetBackground( Wallpaper( Color( rStyles.GetFieldColor() ) ) );
}

void SvxXConnectionPreview::DataChanged( const DataChangedEvent& rDCEvt )
{
    Control::DataChanged( rDCEvt );

    if ( (rDCEvt.GetType() == DATACHANGED_SETTINGS) && (rDCEvt.GetFlags() & SETTINGS_STYLE) )
    {
        SetStyles();
    }
}

<commit_msg>INTEGRATION: CWS changefileheader (1.13.368); FILE MERGED 2008/04/01 15:50:14 thb 1.13.368.3: #i85898# Stripping all external header guards 2008/04/01 12:48:07 thb 1.13.368.2: #i85898# Stripping all external header guards 2008/03/31 14:19:20 rt 1.13.368.1: #i87441# Change license header to LPGL v3.<commit_after>/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2008 by Sun Microsystems, Inc.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * $RCSfile: connctrl.cxx,v $
 * $Revision: 1.14 $
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org 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 version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_svx.hxx"

// include ---------------------------------------------------------------

#include <svx/xoutx.hxx>

#include <svx/svdoedge.hxx>
#include <svx/svdattrx.hxx>
#include <svx/svdmark.hxx>
#include <svx/svdview.hxx>

#include <svx/svdpage.hxx> // SdrObjList

#include "connctrl.hxx"
#include <svx/dialmgr.hxx>
#include "dlgutil.hxx"

// #110094#
#include <svx/sdr/contact/objectcontactofobjlistpainter.hxx>

// #110094#
#include <svx/sdr/contact/displayinfo.hxx>
#include <vcl/svapp.hxx>

/*************************************************************************
|*
|* Ctor SvxXConnectionPreview
|*
*************************************************************************/

SvxXConnectionPreview::SvxXConnectionPreview( Window* pParent, const ResId& rResId,
                            const SfxItemSet& rInAttrs ) :
                            Control ( pParent, rResId ),
                            rAttrs  ( rInAttrs ),
                            pEdgeObj( NULL ),
                            pObjList( NULL ),
                            pView   ( NULL )
{
    pExtOutDev = new XOutputDevice( this );

    SetMapMode( MAP_100TH_MM );

    SetStyles();
}

/*************************************************************************
|*
|* Dtor SvxXConnectionPreview
|*
*************************************************************************/

SvxXConnectionPreview::~SvxXConnectionPreview()
{
    delete pObjList;
    delete pExtOutDev;
}

/*************************************************************************
|*
|* Dtor SvxXConnectionPreview
|*
*************************************************************************/

void SvxXConnectionPreview::Construct()
{
    DBG_ASSERT( pView, "Keine gueltige View Uebergeben!" );

    const SdrMarkList& rMarkList = pView->GetMarkedObjectList();
    ULONG nMarkCount = rMarkList.GetMarkCount();

    if( nMarkCount >= 1 )
    {
        BOOL bFound = FALSE;
        const SdrObject* pObj = rMarkList.GetMark(0)->GetMarkedSdrObj();

        for( USHORT i = 0; i < nMarkCount && !bFound; i++ )
        {
            pObj = rMarkList.GetMark( i )->GetMarkedSdrObj();
            UINT32 nInv = pObj->GetObjInventor();
            UINT16 nId = pObj->GetObjIdentifier();
            if( nInv == SdrInventor && nId == OBJ_EDGE )
            {
                bFound = TRUE;
                SdrEdgeObj* pTmpEdgeObj = (SdrEdgeObj*) pObj;
                pEdgeObj = (SdrEdgeObj*) pTmpEdgeObj->Clone();

                SdrObjConnection& rConn1 = (SdrObjConnection&)pEdgeObj->GetConnection( TRUE );
                SdrObjConnection& rConn2 = (SdrObjConnection&)pEdgeObj->GetConnection( FALSE );

                rConn1 = pTmpEdgeObj->GetConnection( TRUE );
                rConn2 = pTmpEdgeObj->GetConnection( FALSE );

                SdrObject* pTmpObj1 = pTmpEdgeObj->GetConnectedNode( TRUE );
                SdrObject* pTmpObj2 = pTmpEdgeObj->GetConnectedNode( FALSE );

                // #110094#
                // potential memory leak here (!). Create SdrObjList only when there is
                // not yet one.
                if(!pObjList)
                {
                    pObjList = new SdrObjList( pView->GetModel(), NULL );
                }

                if( pTmpObj1 )
                {
                    SdrObject* pObj1 = pTmpObj1->Clone();
                    pObjList->InsertObject( pObj1 );
                    pEdgeObj->ConnectToNode( TRUE, pObj1 );
                }
                if( pTmpObj2 )
                {
                    SdrObject* pObj2 = pTmpObj2->Clone();
                    pObjList->InsertObject( pObj2 );
                    pEdgeObj->ConnectToNode( FALSE, pObj2 );
                }
                pObjList->InsertObject( pEdgeObj );
            }
        }
    }

    if( !pEdgeObj )
        pEdgeObj = new SdrEdgeObj();

    // Groesse anpassen
    if( pObjList )
    {
        OutputDevice* pOD = pView->GetFirstOutputDevice(); // GetWin( 0 );
        Rectangle aRect = pObjList->GetAllObjBoundRect();

        MapMode aMapMode = GetMapMode();
        aMapMode.SetMapUnit( pOD->GetMapMode().GetMapUnit() );
        SetMapMode( aMapMode );

        MapMode         aDisplayMap( aMapMode );
        Point           aNewPos;
        Size            aNewSize;
        const Size      aWinSize = PixelToLogic( GetOutputSizePixel(), aDisplayMap );
        const long      nWidth = aWinSize.Width();
        const long      nHeight = aWinSize.Height();
        double          fRectWH = (double) aRect.GetWidth() / aRect.GetHeight();
        double          fWinWH = (double) nWidth / nHeight;

        // Bitmap an Thumbgroesse anpassen (hier nicht!)
        if ( fRectWH < fWinWH)
        {
            aNewSize.Width() = (long) ( (double) nHeight * fRectWH );
            aNewSize.Height()= nHeight;
        }
        else
        {
            aNewSize.Width() = nWidth;
            aNewSize.Height()= (long) ( (double) nWidth / fRectWH );
        }

        Fraction aFrac1( aWinSize.Width(), aRect.GetWidth() );
        Fraction aFrac2( aWinSize.Height(), aRect.GetHeight() );
        Fraction aMinFrac( aFrac1 <= aFrac2 ? aFrac1 : aFrac2 );

        // MapMode umsetzen
        aDisplayMap.SetScaleX( aMinFrac );
        aDisplayMap.SetScaleY( aMinFrac );

        // Zentrierung
        aNewPos.X() = ( nWidth - aNewSize.Width() )  >> 1;
        aNewPos.Y() = ( nHeight - aNewSize.Height() ) >> 1;

        aDisplayMap.SetOrigin( LogicToLogic( aNewPos, aMapMode, aDisplayMap ) );
        SetMapMode( aDisplayMap );

        // Ursprung
        aNewPos = aDisplayMap.GetOrigin();
        aNewPos -= Point( aRect.TopLeft().X(), aRect.TopLeft().Y() );
        aDisplayMap.SetOrigin( aNewPos );
        SetMapMode( aDisplayMap );

        Point aPos;
        MouseEvent aMEvt( aPos, 1, 0, MOUSE_RIGHT );
        MouseButtonDown( aMEvt );
        /*
        Point aPt( -aRect.TopLeft().X(), -aRect.TopLeft().Y() );
        aMapMode.SetOrigin( aPt );

        // Skalierung
        Size aSize = GetOutputSize();
        Fraction aFrac1( aSize.Width(), aRect.GetWidth() );
        Fraction aFrac2( aSize.Height(), aRect.GetHeight() );
        Fraction aMaxFrac( aFrac1 > aFrac2 ? aFrac1 : aFrac2 );
        Fraction aMinFrac( aFrac1 <= aFrac2 ? aFrac1 : aFrac2 );
        BOOL bChange = (BOOL) ( (double)aMinFrac > 1.0 );
        aMapMode.SetScaleX( aMinFrac );
        aMapMode.SetScaleY( aMinFrac );

        // zentrieren
        long nXXL = aSize.Width() > aRect.GetWidth() ? aSize.Width() : aRect.GetWidth();
        long nXS = aSize.Width() <= aRect.GetWidth() ? aSize.Width() : aRect.GetWidth();
        if( bChange )
        {
            long nTmp = nXXL; nXXL = nXS; nXS = nTmp;
        }
        long nX = (long) ( (double)aMinFrac * (double)nXXL );
        nX = (long) ( (double)labs( nXS - nX ) / (double)aMinFrac / 2.0 );

        long nYXL = aSize.Height() > aRect.GetHeight() ? aSize.Height() : aRect.GetHeight();
        long nYS = aSize.Height() <= aRect.GetHeight() ? aSize.Height() : aRect.GetHeight();
        if( bChange )
        {
            long nTmp = nXXL; nXXL = nXS; nXS = nTmp;
        }
        long nY = (long) ( (double)aMinFrac * (double)nYXL );
        nY = (long) ( (double)labs( nYS - nY ) / (double)aMinFrac / 2.0 );

        aPt += Point( nX, nY );
        aMapMode.SetOrigin( aPt );

        SetMapMode( aMapMode );
        */
    }
}

/*************************************************************************
|*
|* SvxXConnectionPreview: Paint()
|*
*************************************************************************/

void SvxXConnectionPreview::Paint( const Rectangle& )
{
    SdrPaintInfoRec aInfoRec;

    //pEdgeObj->Paint( *pExtOutDev, aInfoRec );
    if( pObjList )
    {
        // #110094#
        // This will not work anymore. To not start at Adam and Eve, i will
        // ATM not try to change all this stuff to really using an own model
        // and a view. I will just try to provide a mechanism to paint such
        // objects without own model and without a page/view with the new
        // mechanism.
        //
        //pObjList->Paint( *pExtOutDev, aInfoRec );

        // New stuff: Use a ObjectContactOfObjListPainter.
        sdr::contact::SdrObjectVector aObjectVector;

        for(sal_uInt32 a(0L); a < pObjList->GetObjCount(); a++)
        {
            SdrObject* pObject = pObjList->GetObj(a);
            DBG_ASSERT(pObject,
                "SvxXConnectionPreview::Paint: Corrupt ObjectList (!)");
            aObjectVector.push_back(pObject);
        }

        sdr::contact::ObjectContactOfObjListPainter aPainter(aObjectVector);
        sdr::contact::DisplayInfo aDisplayInfo;

        aDisplayInfo.SetExtendedOutputDevice(pExtOutDev);
        aDisplayInfo.SetPaintInfoRec(&aInfoRec);
        aDisplayInfo.SetOutputDevice(pExtOutDev->GetOutDev());

        // do processing
        aPainter.ProcessDisplay(aDisplayInfo);

        // prepare delete
        aPainter.PrepareDelete();
    }
}

/*************************************************************************
|*
|* SvxXConnectionPreview: SetAttributes()
|*
*************************************************************************/

void SvxXConnectionPreview::SetAttributes( const SfxItemSet& rInAttrs )
{
    //pEdgeObj->SetItemSetAndBroadcast(rInAttrs);
    pEdgeObj->SetMergedItemSetAndBroadcast(rInAttrs);

    Invalidate();
}

/*************************************************************************
|*
|* Ermittelt die Anzahl der Linienversaetze anhand des Preview-Objektes
|*
*************************************************************************/

USHORT SvxXConnectionPreview::GetLineDeltaAnz()
{
    const SfxItemSet& rSet = pEdgeObj->GetMergedItemSet();
    sal_uInt16 nCount(0);

    if(SFX_ITEM_DONTCARE != rSet.GetItemState(SDRATTR_EDGELINEDELTAANZ))
        nCount = ((const SdrEdgeLineDeltaAnzItem&)rSet.Get(SDRATTR_EDGELINEDELTAANZ)).GetValue();

    return nCount;
}

/*************************************************************************
|*
|* SvxXConnectionPreview: MouseButtonDown()
|*
*************************************************************************/

void SvxXConnectionPreview::MouseButtonDown( const MouseEvent& rMEvt )
{
    BOOL bZoomIn  = rMEvt.IsLeft() && !rMEvt.IsShift();
    BOOL bZoomOut = rMEvt.IsRight() || rMEvt.IsShift();
    BOOL bCtrl    = rMEvt.IsMod1();

    if( bZoomIn || bZoomOut )
    {
        MapMode aMapMode = GetMapMode();
        Fraction aXFrac = aMapMode.GetScaleX();
        Fraction aYFrac = aMapMode.GetScaleY();
        Fraction* pMultFrac;

        if( bZoomIn )
        {
            if( bCtrl )
                pMultFrac = new Fraction( 3, 2 );
            else
                pMultFrac = new Fraction( 11, 10 );
        }
        else
        {
            if( bCtrl )
                pMultFrac = new Fraction( 2, 3 );
            else
                pMultFrac = new Fraction( 10, 11 );
        }

        aXFrac *= *pMultFrac;
        aYFrac *= *pMultFrac;
        if( (double)aXFrac > 0.001 && (double)aXFrac < 1000.0 &&
            (double)aYFrac > 0.001 && (double)aYFrac < 1000.0 )
        {
            aMapMode.SetScaleX( aXFrac );
            aMapMode.SetScaleY( aYFrac );
            SetMapMode( aMapMode );

            Size aOutSize( GetOutputSize() );

            Point aPt( aMapMode.GetOrigin() );
            long nX = (long)( ( (double)aOutSize.Width() - ( (double)aOutSize.Width() * (double)*pMultFrac  ) ) / 2.0 + 0.5 );
            long nY = (long)( ( (double)aOutSize.Height() - ( (double)aOutSize.Height() * (double)*pMultFrac  ) ) / 2.0 + 0.5 );
            aPt.X() +=  nX;
            aPt.Y() +=  nY;

            aMapMode.SetOrigin( aPt );
            SetMapMode( aMapMode );

            Invalidate();
        }
        delete pMultFrac;
    }
}

void SvxXConnectionPreview::SetStyles()
{
    const StyleSettings& rStyles = Application::GetSettings().GetStyleSettings();
    SetDrawMode( GetDisplayBackground().GetColor().IsDark() ? OUTPUT_DRAWMODE_CONTRAST : OUTPUT_DRAWMODE_COLOR );
    SetBackground( Wallpaper( Color( rStyles.GetFieldColor() ) ) );
}

void SvxXConnectionPreview::DataChanged( const DataChangedEvent& rDCEvt )
{
    Control::DataChanged( rDCEvt );

    if ( (rDCEvt.GetType() == DATACHANGED_SETTINGS) && (rDCEvt.GetFlags() & SETTINGS_STYLE) )
    {
        SetStyles();
    }
}

<|endoftext|>