<commit_before>#include <regex>
#include "foo_musicbrainz.h"
#include "ReleaseList.h"
#include "RequestURL.h"
#include "TOC.h"
#include "Track.h"
#include "CCustomQueryMBID.h"
#include "CCustomQueryTags.h"
#include "CTaggerDialog.h"

using namespace std::tr1;

extern cfg_bool cfg_write_ids;
class foo_mb_menu : public contextmenu_item_simple
{
public:
	unsigned get_num_items()
	{
		return 4;
	}

	void get_item_name(unsigned p_index,pfc::string_base & p_out)
	{
		static const char *item_name[] = {
			"Get Tags From MusicBrainz (by TOC)",
			"Get Tags From MusicBrainz (by Artist & Album)",
			"Get Tags From MusicBrainz (by MusicBrainz Album ID)",
			"Add TOC to MusicBrainz"
		};
		p_out = item_name[p_index];
	}

	void get_item_default_path(unsigned p_index,pfc::string_base & p_out)
	{
		p_out = "Tagging";
	}

	void context_command(unsigned p_index,metadb_handle_list_cref p_data,const GUID& p_caller)
	{
		unsigned int count = p_data.get_count();
		if (p_index <= 2 && count > 99)
		{
			popup_message::g_show("Please select no more than 99 tracks.", COMPONENT_TITLE, popup_message::icon_error);
			return;
		}
		switch (p_index)
		{
		case 0:
			{
				TOC toc(p_data);
				RequestURL url;
				url.AddParam("discid", toc.getDiscID());
				url.AddParam("count", count);
				url.AddParam("cdstubs", "no");

				ReleaseList *mbc = new ReleaseList(p_data);
				mbc->setDiscId(toc.getDiscID());

				// new CTaggerDialog(url.GetURL(), mbc);
				break;
			}
		case 1:
			{
				pfc::string8 artist, album;
				for (t_size i = 0; i < count; i++) {
					auto item = p_data.get_item(i);
					item->metadb_lock();
					const file_info *info;
					if (!item->get_info_locked(info)) {
						item->metadb_unlock();
						return;
					}

					auto current_artist = info->meta_get("ALBUM ARTIST", 0);
					if (current_artist == nullptr) current_artist = info->meta_get("ARTIST", 0);
					auto current_album = info->meta_get("ALBUM", 0);

					if (current_artist == nullptr || current_album == nullptr) {
						item->metadb_unlock();
						break;
					}

					// Save album and artist of the first item
					if (i == 0) {
						artist = current_artist;
						album = current_album;
						if (artist.is_empty() || album.is_empty()) {
							artist.reset();
							album.reset();
							item->metadb_unlock();
							break;
						}
					// Break if artist or album of current item are different from the first one
					} else if (strcmp(artist, current_artist) != 0 || strcmp(album, current_album) != 0) {
						artist.reset();
						album.reset();
						item->metadb_unlock();
							break;
					}
					item->metadb_unlock();
				}
				// new CCustomQueryTags(new ReleaseList(p_data), count, artist, album);
				break;
			}
		case 2:
			{
				// Stop if MBIDs are disabled
				if (!cfg_write_ids.get_value()) return;

				pfc::string8 album_id;
				for (t_size i = 0; i < count; i++) {
					auto item = p_data.get_item(i);
					item->metadb_lock();
					const file_info *info;
					if (!item->get_info_locked(info)) {
						item->metadb_unlock();
						return;
					}

					auto current_album_id = info->meta_get("MUSICBRAINZ_ALBUMID", 0);

					if (current_album_id == nullptr) {
						item->metadb_unlock();
						break;
					}

					// Save album ID of the first item
					if (i == 0) {
						album_id = current_album_id;
						regex rx("^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$");
						if (!regex_search(album_id.get_ptr(), rx)) {
							album_id.reset();
							item->metadb_unlock();
							break;
						}
					// Break if album ID of current item is different from the first one
					} else if (strcmp(album_id, current_album_id) != 0) {
						album_id.reset();
						item->metadb_unlock();
						break;
					}
					item->metadb_unlock();
				}
				new CCustomQueryMBID(new ReleaseList(p_data), count, album_id);
				break;
			}
		case 3:
			{
				TOC toc(p_data);

				pfc::string8 url = "http:\/\/musicbrainz.org\/cdtoc\/attach?toc=";
				url << toc.getTOC();
				pfc::stringcvt::string_os_from_utf8 url_converter(url);
				ShellExecute(nullptr, _T("open"), url_converter, nullptr, nullptr, SW_SHOW);
				break;
			}
		}
	}

	GUID get_item_guid(unsigned p_index)
	{
		static const GUID guid_foo_mb_menu[] = {
			{ 0x3ca8395b, 0x694e, 0x4845, { 0xb5, 0xea, 0x56, 0x30, 0x5e, 0x7c, 0x24, 0x48 } },
			{ 0x77f1f5cd, 0xf295, 0x4ef4, { 0xba, 0x7b, 0xc7, 0x70, 0xaa, 0xc6, 0xd0, 0x1e } },
			{ 0xf453e537, 0x01e9, 0x4f2d, { 0x89, 0xdc, 0x42, 0x4d, 0x0e, 0xe5, 0x72, 0xfb } },
			{ 0x4d5e632c, 0x34f3, 0x4fda, { 0x8f, 0x71, 0x35, 0xa4, 0xb2, 0x5b, 0xea, 0x94 } }
		};
		return guid_foo_mb_menu[p_index];
	}

	bool get_item_description(unsigned p_index,pfc::string_base & p_out)
	{
		static const char *item_description[] = {
			"Queries MusicBrainz server for tags for a complete CD using TOC.",
			"Queries MusicBrainz server for tags for a complete CD using Artist/Album.",
			"Queries MusicBrainz server for tags for a complete CD using MusicBrainz Album ID.",
			"Opens MusicBrainz TOC lookup page."
		};
		p_out = item_description[p_index];
		return true;
	}

	bool context_get_display(unsigned p_index,metadb_handle_list_cref p_data,pfc::string_base & p_out,unsigned & p_displayflags,const GUID & p_caller)
	{
		PFC_ASSERT(p_index>=0 && p_index<get_num_items());
		unsigned int count = p_data.get_count();
		if (count <= 99)
		{
			if (p_index == 0 || p_index == 3)
			{
				const file_info *info;
				for (t_size i = 0; i < count; i++)
				{
					p_data.get_item(i)->metadb_lock();
					if (!p_data.get_item(i)->get_info_locked(info) || info->info_get_length_samples() % 588 != 0)
					{
						p_data.get_item(i)->metadb_unlock();
						return false;
					}
					p_data.get_item(i)->metadb_unlock();
				}
			}
			if (p_index == 2 && !cfg_write_ids.get_value())
			{
				return false;
			}
			get_item_name(p_index, p_out);
			return true;
		}
		else
		{
			return false;
		}
	}
};

static contextmenu_item_factory_t<foo_mb_menu> g_foo_mb_menu_factory;
<commit_msg>Removed unneeded escape symbols<commit_after>#include <regex>
#include "foo_musicbrainz.h"
#include "ReleaseList.h"
#include "RequestURL.h"
#include "TOC.h"
#include "Track.h"
#include "CCustomQueryMBID.h"
#include "CCustomQueryTags.h"
#include "CTaggerDialog.h"

using namespace std::tr1;

extern cfg_bool cfg_write_ids;
class foo_mb_menu : public contextmenu_item_simple
{
public:
	unsigned get_num_items()
	{
		return 4;
	}

	void get_item_name(unsigned p_index,pfc::string_base & p_out)
	{
		static const char *item_name[] = {
			"Get Tags From MusicBrainz (by TOC)",
			"Get Tags From MusicBrainz (by Artist & Album)",
			"Get Tags From MusicBrainz (by MusicBrainz Album ID)",
			"Add TOC to MusicBrainz"
		};
		p_out = item_name[p_index];
	}

	void get_item_default_path(unsigned p_index,pfc::string_base & p_out)
	{
		p_out = "Tagging";
	}

	void context_command(unsigned p_index,metadb_handle_list_cref p_data,const GUID& p_caller)
	{
		unsigned int count = p_data.get_count();
		if (p_index <= 2 && count > 99)
		{
			popup_message::g_show("Please select no more than 99 tracks.", COMPONENT_TITLE, popup_message::icon_error);
			return;
		}
		switch (p_index)
		{
		case 0:
			{
				TOC toc(p_data);
				RequestURL url;
				url.AddParam("discid", toc.getDiscID());
				url.AddParam("count", count);
				url.AddParam("cdstubs", "no");

				ReleaseList *mbc = new ReleaseList(p_data);
				mbc->setDiscId(toc.getDiscID());

				// new CTaggerDialog(url.GetURL(), mbc);
				break;
			}
		case 1:
			{
				pfc::string8 artist, album;
				for (t_size i = 0; i < count; i++) {
					auto item = p_data.get_item(i);
					item->metadb_lock();
					const file_info *info;
					if (!item->get_info_locked(info)) {
						item->metadb_unlock();
						return;
					}

					auto current_artist = info->meta_get("ALBUM ARTIST", 0);
					if (current_artist == nullptr) current_artist = info->meta_get("ARTIST", 0);
					auto current_album = info->meta_get("ALBUM", 0);

					if (current_artist == nullptr || current_album == nullptr) {
						item->metadb_unlock();
						break;
					}

					// Save album and artist of the first item
					if (i == 0) {
						artist = current_artist;
						album = current_album;
						if (artist.is_empty() || album.is_empty()) {
							artist.reset();
							album.reset();
							item->metadb_unlock();
							break;
						}
					// Break if artist or album of current item are different from the first one
					} else if (strcmp(artist, current_artist) != 0 || strcmp(album, current_album) != 0) {
						artist.reset();
						album.reset();
						item->metadb_unlock();
							break;
					}
					item->metadb_unlock();
				}
				// new CCustomQueryTags(new ReleaseList(p_data), count, artist, album);
				break;
			}
		case 2:
			{
				// Stop if MBIDs are disabled
				if (!cfg_write_ids.get_value()) return;

				pfc::string8 album_id;
				for (t_size i = 0; i < count; i++) {
					auto item = p_data.get_item(i);
					item->metadb_lock();
					const file_info *info;
					if (!item->get_info_locked(info)) {
						item->metadb_unlock();
						return;
					}

					auto current_album_id = info->meta_get("MUSICBRAINZ_ALBUMID", 0);

					if (current_album_id == nullptr) {
						item->metadb_unlock();
						break;
					}

					// Save album ID of the first item
					if (i == 0) {
						album_id = current_album_id;
						regex rx("^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$");
						if (!regex_search(album_id.get_ptr(), rx)) {
							album_id.reset();
							item->metadb_unlock();
							break;
						}
					// Break if album ID of current item is different from the first one
					} else if (strcmp(album_id, current_album_id) != 0) {
						album_id.reset();
						item->metadb_unlock();
						break;
					}
					item->metadb_unlock();
				}
				new CCustomQueryMBID(new ReleaseList(p_data), count, album_id);
				break;
			}
		case 3:
			{
				TOC toc(p_data);

				pfc::string8 url = "http://musicbrainz.org/cdtoc/attach?toc=";
				url << toc.getTOC();
				pfc::stringcvt::string_os_from_utf8 url_converter(url);
				ShellExecute(nullptr, _T("open"), url_converter, nullptr, nullptr, SW_SHOW);
				break;
			}
		}
	}

	GUID get_item_guid(unsigned p_index)
	{
		static const GUID guid_foo_mb_menu[] = {
			{ 0x3ca8395b, 0x694e, 0x4845, { 0xb5, 0xea, 0x56, 0x30, 0x5e, 0x7c, 0x24, 0x48 } },
			{ 0x77f1f5cd, 0xf295, 0x4ef4, { 0xba, 0x7b, 0xc7, 0x70, 0xaa, 0xc6, 0xd0, 0x1e } },
			{ 0xf453e537, 0x01e9, 0x4f2d, { 0x89, 0xdc, 0x42, 0x4d, 0x0e, 0xe5, 0x72, 0xfb } },
			{ 0x4d5e632c, 0x34f3, 0x4fda, { 0x8f, 0x71, 0x35, 0xa4, 0xb2, 0x5b, 0xea, 0x94 } }
		};
		return guid_foo_mb_menu[p_index];
	}

	bool get_item_description(unsigned p_index,pfc::string_base & p_out)
	{
		static const char *item_description[] = {
			"Queries MusicBrainz server for tags for a complete CD using TOC.",
			"Queries MusicBrainz server for tags for a complete CD using Artist/Album.",
			"Queries MusicBrainz server for tags for a complete CD using MusicBrainz Album ID.",
			"Opens MusicBrainz TOC lookup page."
		};
		p_out = item_description[p_index];
		return true;
	}

	bool context_get_display(unsigned p_index,metadb_handle_list_cref p_data,pfc::string_base & p_out,unsigned & p_displayflags,const GUID & p_caller)
	{
		PFC_ASSERT(p_index>=0 && p_index<get_num_items());
		unsigned int count = p_data.get_count();
		if (count <= 99)
		{
			if (p_index == 0 || p_index == 3)
			{
				const file_info *info;
				for (t_size i = 0; i < count; i++)
				{
					p_data.get_item(i)->metadb_lock();
					if (!p_data.get_item(i)->get_info_locked(info) || info->info_get_length_samples() % 588 != 0)
					{
						p_data.get_item(i)->metadb_unlock();
						return false;
					}
					p_data.get_item(i)->metadb_unlock();
				}
			}
			if (p_index == 2 && !cfg_write_ids.get_value())
			{
				return false;
			}
			get_item_name(p_index, p_out);
			return true;
		}
		else
		{
			return false;
		}
	}
};

static contextmenu_item_factory_t<foo_mb_menu> g_foo_mb_menu_factory;
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: scrwin.hxx,v $
 *
 *  $Revision: 1.3 $
 *
 *  last change: $Author: rt $ $Date: 2005-09-08 10:14:00 $
 *
 *  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 _SCRWIN_HXX
#define _SCRWIN_HXX

#ifndef INCLUDED_SVTDLLAPI_H
#include "svtools/svtdllapi.h"
#endif

#ifndef _SCRBAR_HXX //autogen
#include <vcl/scrbar.hxx>
#endif

class DataChangedEvent;

// -------------------------
// - ScrollableWindow-Type -
// -------------------------

typedef USHORT ScrollableWindowFlags;

#define SCRWIN_THUMBDRAGGING 1
#define SCRWIN_VCENTER       2
#define SCRWIN_HCENTER       4
#define SCRWIN_DEFAULT       (SCRWIN_THUMBDRAGGING | SCRWIN_VCENTER | SCRWIN_HCENTER)

// --------------------
// - ScrollableWindow -
// --------------------

class SVT_DLLPUBLIC ScrollableWindow: public Window
{
private:
    Point           aPixOffset;         // offset to virtual window (pixel)
    Size            aTotPixSz;          // total size of virtual window (pixel)
    long            nLinePixH;          // size of a line/column (pixel)
    long            nColumnPixW;

    ScrollBar       aVScroll;           // the scrollbars
    ScrollBar       aHScroll;
    ScrollBarBox    aCornerWin;         // window in the bottom right corner
    BOOL            bScrolling:1,       // user controlled scrolling
                    bHandleDragging:1,  // scroll window while dragging
                    bHCenter:1,
                    bVCenter:1;

#ifdef _SVT_SCRWIN_CXX
    SVT_DLLPRIVATE void         ImpInitialize( ScrollableWindowFlags nFlags );
    DECL_DLLPRIVATE_LINK( ScrollHdl, ScrollBar * );
    DECL_DLLPRIVATE_LINK( EndScrollHdl, ScrollBar * );
#endif

public:
                    ScrollableWindow( Window* pParent, WinBits nBits = 0,
                                      ScrollableWindowFlags = SCRWIN_DEFAULT );
                    ScrollableWindow( Window* pParent, const ResId& rId,
                                      ScrollableWindowFlags = SCRWIN_DEFAULT );

    virtual void    Resize();
    virtual void    Command( const CommandEvent& rCEvt );
    virtual void    DataChanged( const DataChangedEvent& rDEvt );

    virtual void    StartScroll();
    virtual void    EndScroll( long nDeltaX, long nDeltaY );

    void            SetMapMode( const MapMode& rNewMapMode );
    MapMode         GetMapMode() const;

    void            SetTotalSize( const Size& rNewSize );
    Size            GetTotalSize() { return PixelToLogic( aTotPixSz ); }

    void            SetVisibleSize( const Size& rNewSize );
    BOOL            MakeVisible( const Rectangle& rTarget, BOOL bSloppy = FALSE );
    Rectangle       GetVisibleArea() const;

    void            SetLineSize( ULONG nHorz, ULONG nVert );
    void            Scroll( long nDeltaX, long nDeltaY );
    void            Scroll( long nDeltaX, long nDeltaY,
                            const Rectangle& rRect );
    void            ScrollLines( long nLinesX, long nLinesY );
    void            ScrollPages( long nPagesX, ULONG nOverlapX,
                                 long nPagesY, ULONG nOverlapY );

private:
    SVT_DLLPRIVATE void         SetOutputSizePixel( const Size& rSize );
    SVT_DLLPRIVATE Size         GetOutputSizePixel() const;
    SVT_DLLPRIVATE Size         GetOutputSize() const;
};

#endif
<commit_msg>INTEGRATION: CWS warnings01 (1.3.62); FILE MERGED 2005/11/16 09:57:59 pl 1.3.62.2: #i55991# removed warnings 2005/11/15 15:13:07 pl 1.3.62.1: #i55991# removed warnings<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: scrwin.hxx,v $
 *
 *  $Revision: 1.4 $
 *
 *  last change: $Author: hr $ $Date: 2006-06-19 20:26:55 $
 *
 *  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 _SCRWIN_HXX
#define _SCRWIN_HXX

#ifndef INCLUDED_SVTDLLAPI_H
#include "svtools/svtdllapi.h"
#endif

#ifndef _SCRBAR_HXX //autogen
#include <vcl/scrbar.hxx>
#endif

class DataChangedEvent;

// -------------------------
// - ScrollableWindow-Type -
// -------------------------

typedef USHORT ScrollableWindowFlags;

#define SCRWIN_THUMBDRAGGING 1
#define SCRWIN_VCENTER       2
#define SCRWIN_HCENTER       4
#define SCRWIN_DEFAULT       (SCRWIN_THUMBDRAGGING | SCRWIN_VCENTER | SCRWIN_HCENTER)

// --------------------
// - ScrollableWindow -
// --------------------

class SVT_DLLPUBLIC ScrollableWindow: public Window
{
private:
    Point           aPixOffset;         // offset to virtual window (pixel)
    Size            aTotPixSz;          // total size of virtual window (pixel)
    long            nLinePixH;          // size of a line/column (pixel)
    long            nColumnPixW;

    ScrollBar       aVScroll;           // the scrollbars
    ScrollBar       aHScroll;
    ScrollBarBox    aCornerWin;         // window in the bottom right corner
    BOOL            bScrolling:1,       // user controlled scrolling
                    bHandleDragging:1,  // scroll window while dragging
                    bHCenter:1,
                    bVCenter:1;

#ifdef _SVT_SCRWIN_CXX
    SVT_DLLPRIVATE void         ImpInitialize( ScrollableWindowFlags nFlags );
    DECL_DLLPRIVATE_LINK( ScrollHdl, ScrollBar * );
    DECL_DLLPRIVATE_LINK( EndScrollHdl, ScrollBar * );
#endif

public:
                    ScrollableWindow( Window* pParent, WinBits nBits = 0,
                                      ScrollableWindowFlags = SCRWIN_DEFAULT );
                    ScrollableWindow( Window* pParent, const ResId& rId,
                                      ScrollableWindowFlags = SCRWIN_DEFAULT );

    virtual void    Resize();
    virtual void    Command( const CommandEvent& rCEvt );
    virtual void    DataChanged( const DataChangedEvent& rDEvt );

    virtual void    StartScroll();
    virtual void    EndScroll( long nDeltaX, long nDeltaY );

    using OutputDevice::SetMapMode;
    virtual void    SetMapMode( const MapMode& rNewMapMode );
    virtual MapMode GetMapMode() const;

    void            SetTotalSize( const Size& rNewSize );
    Size            GetTotalSize() { return PixelToLogic( aTotPixSz ); }

    void            SetVisibleSize( const Size& rNewSize );
    BOOL            MakeVisible( const Rectangle& rTarget, BOOL bSloppy = FALSE );
    Rectangle       GetVisibleArea() const;

    void            SetLineSize( ULONG nHorz, ULONG nVert );
    using Window::Scroll;
    virtual void    Scroll( long nDeltaX, long nDeltaY, USHORT nFlags = 0 );
    void            ScrollLines( long nLinesX, long nLinesY );
    void            ScrollPages( long nPagesX, ULONG nOverlapX,
                                 long nPagesY, ULONG nOverlapY );

private:
    SVT_DLLPRIVATE Size         GetOutputSizePixel() const;
    SVT_DLLPRIVATE Size         GetOutputSize() const;
};

#endif
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: XMLChartPropertyContext.hxx,v $
 *
 *  $Revision: 1.4 $
 *
 *  last change: $Author: hr $ $Date: 2006-06-19 18:02:31 $
 *
 *  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 _XMLOFF_CHARTPROPERTYCONTEXT_HXX_
#define _XMLOFF_CHARTPROPERTYCONTEXT_HXX_

#ifndef _XMLOFF_XMLPROPERTYSETCONTEXT_HXX
#include "xmlprcon.hxx"
#endif

class XMLChartPropertyContext : public SvXMLPropertySetContext
{
public:
    TYPEINFO();

    XMLChartPropertyContext( SvXMLImport& rImport, sal_uInt16 nPrfx,
                             const ::rtl::OUString& rLName,
                             const ::com::sun::star::uno::Reference<
                                 ::com::sun::star::xml::sax::XAttributeList > & xAttrList,
                             sal_uInt32 nFamily,
                             ::std::vector< XMLPropertyState >& rProps,
                             const UniReference< SvXMLImportPropertyMapper >& rMapper );
    virtual ~XMLChartPropertyContext();

    using SvXMLPropertySetContext::CreateChildContext;
    virtual SvXMLImportContext* CreateChildContext(
        sal_uInt16 nPrefix,
        const ::rtl::OUString& rLocalName,
        const ::com::sun::star::uno::Reference<
            ::com::sun::star::xml::sax::XAttributeList > & xAttrList,
        ::std::vector< XMLPropertyState > &rProperties,
        const XMLPropertyState& rProp );

private:
};

#endif  // _XMLOFF_CHARTPROPERTYCONTEXT_HXX_
<commit_msg>INTEGRATION: CWS vgbugs07 (1.4.156); FILE MERGED 2007/06/04 13:23:20 vg 1.4.156.1: #i76605# Remove -I .../inc/module hack introduced by hedaburemove01<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: XMLChartPropertyContext.hxx,v $
 *
 *  $Revision: 1.5 $
 *
 *  last change: $Author: hr $ $Date: 2007-06-27 14:50:56 $
 *
 *  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 _XMLOFF_CHARTPROPERTYCONTEXT_HXX_
#define _XMLOFF_CHARTPROPERTYCONTEXT_HXX_

#ifndef _XMLOFF_XMLPROPERTYSETCONTEXT_HXX
#include <xmloff/xmlprcon.hxx>
#endif

class XMLChartPropertyContext : public SvXMLPropertySetContext
{
public:
    TYPEINFO();

    XMLChartPropertyContext( SvXMLImport& rImport, sal_uInt16 nPrfx,
                             const ::rtl::OUString& rLName,
                             const ::com::sun::star::uno::Reference<
                                 ::com::sun::star::xml::sax::XAttributeList > & xAttrList,
                             sal_uInt32 nFamily,
                             ::std::vector< XMLPropertyState >& rProps,
                             const UniReference< SvXMLImportPropertyMapper >& rMapper );
    virtual ~XMLChartPropertyContext();

    using SvXMLPropertySetContext::CreateChildContext;
    virtual SvXMLImportContext* CreateChildContext(
        sal_uInt16 nPrefix,
        const ::rtl::OUString& rLocalName,
        const ::com::sun::star::uno::Reference<
            ::com::sun::star::xml::sax::XAttributeList > & xAttrList,
        ::std::vector< XMLPropertyState > &rProperties,
        const XMLPropertyState& rProp );

private:
};

#endif  // _XMLOFF_CHARTPROPERTYCONTEXT_HXX_
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: XMLIndexSpanEntryContext.cxx,v $
 *
 *  $Revision: 1.3 $
 *
 *  last change: $Author: hr $ $Date: 2006-06-19 18:41:00 $
 *
 *  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 _XMLOFF_XMLINDEXSPANENTRYCONTEXT_HXX_
#include "XMLIndexSpanEntryContext.hxx"
#endif

#ifndef _RTL_USTRING_
#include <rtl/ustring.hxx>
#endif

#ifndef _XMLOFF_XMLINDEXTEMPLATECONTEXT_HXX_
#include "XMLIndexTemplateContext.hxx"
#endif

#ifndef _XMLOFF_XMLICTXT_HXX
#include "xmlictxt.hxx"
#endif

using ::rtl::OUString;
using ::com::sun::star::uno::Sequence;
using ::com::sun::star::uno::Any;
using ::com::sun::star::beans::PropertyValue;

TYPEINIT1( XMLIndexSpanEntryContext, XMLIndexSimpleEntryContext);

XMLIndexSpanEntryContext::XMLIndexSpanEntryContext(
    SvXMLImport& rImport,
    XMLIndexTemplateContext& rTemplate,
    sal_uInt16 nPrfx,
    const OUString& rLocalName ) :
        XMLIndexSimpleEntryContext(rImport, rTemplate.sTokenText,
                                   rTemplate, nPrfx, rLocalName)
{
    nValues++;  // one more for the text string
}

XMLIndexSpanEntryContext::~XMLIndexSpanEntryContext()
{
}

void XMLIndexSpanEntryContext::Characters(const OUString& sString)
{
    sContent.append(sString);
}

void XMLIndexSpanEntryContext::FillPropertyValues(
    Sequence<PropertyValue> & rValues)
{
    // call superclass for token type, stylename,
    XMLIndexSimpleEntryContext::FillPropertyValues(rValues);

    // content
    Any aAny;
    aAny <<= sContent.makeStringAndClear();
    rValues[nValues-1].Name = rTemplateContext.sText;
    rValues[nValues-1].Value = aAny;
}

<commit_msg>INTEGRATION: CWS pchfix02 (1.3.34); FILE MERGED 2006/09/01 18:00:03 kaib 1.3.34.1: #i68856# Added header markers and pch files<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: XMLIndexSpanEntryContext.cxx,v $
 *
 *  $Revision: 1.4 $
 *
 *  last change: $Author: obo $ $Date: 2006-09-17 11:07:21 $
 *
 *  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_xmloff.hxx"

#ifndef _XMLOFF_XMLINDEXSPANENTRYCONTEXT_HXX_
#include "XMLIndexSpanEntryContext.hxx"
#endif

#ifndef _RTL_USTRING_
#include <rtl/ustring.hxx>
#endif

#ifndef _XMLOFF_XMLINDEXTEMPLATECONTEXT_HXX_
#include "XMLIndexTemplateContext.hxx"
#endif

#ifndef _XMLOFF_XMLICTXT_HXX
#include "xmlictxt.hxx"
#endif

using ::rtl::OUString;
using ::com::sun::star::uno::Sequence;
using ::com::sun::star::uno::Any;
using ::com::sun::star::beans::PropertyValue;

TYPEINIT1( XMLIndexSpanEntryContext, XMLIndexSimpleEntryContext);

XMLIndexSpanEntryContext::XMLIndexSpanEntryContext(
    SvXMLImport& rImport,
    XMLIndexTemplateContext& rTemplate,
    sal_uInt16 nPrfx,
    const OUString& rLocalName ) :
        XMLIndexSimpleEntryContext(rImport, rTemplate.sTokenText,
                                   rTemplate, nPrfx, rLocalName)
{
    nValues++;  // one more for the text string
}

XMLIndexSpanEntryContext::~XMLIndexSpanEntryContext()
{
}

void XMLIndexSpanEntryContext::Characters(const OUString& sString)
{
    sContent.append(sString);
}

void XMLIndexSpanEntryContext::FillPropertyValues(
    Sequence<PropertyValue> & rValues)
{
    // call superclass for token type, stylename,
    XMLIndexSimpleEntryContext::FillPropertyValues(rValues);

    // content
    Any aAny;
    aAny <<= sContent.makeStringAndClear();
    rValues[nValues-1].Name = rTemplateContext.sText;
    rValues[nValues-1].Value = aAny;
}

<|endoftext|>


<commit_before>/* Begin CVS Header
   $Source: /Volumes/Home/Users/shoops/cvs/copasi_dev/copasi/CopasiSE/CopasiSE.cpp,v $
   $Revision: 1.6 $
   $Name:  $
   $Author: shoops $
   $Date: 2003/11/26 18:39:29 $
   End CVS Header */

// Main
//
// (C) Stefan Hoops 2002
//

#ifdef XXXX
#ifdef WIN32
# include <windows.h>
# include <winbase.h>
# include <direct.h>
# define getcwd _getcwd
# ifdef ERROR
#  undef ERROR
# endif
#else
# include <unistd.h>
#endif
#endif

#include <stdlib.h>
#include <sstream>
#include <string>
#include <iostream>

#define COPASI_MAIN
#define COPASI_TRACE_CONSTRUCTION

#include "copasi.h"
#include "utilities/CGlobals.h"
#include "utilities/CCopasiMessage.h"
#include "utilities/CCopasiException.h"
#include "commandline/COptionParser.h"
#include "commandline/COptions.h"
#include "function/CFunctionDB.h"
#include "model/CModel.h"
#include "output/COutputList.h"
#include "output/COutput.h"
#include "trajectory/CTrajectoryTask.h"
#include "trajectory/CTrajectoryProblem.h"
#include "steadystate/CSteadyStateTask.h"
#include "steadystate/CSteadyStateProblem.h"

void processTrajectory(CModel & model, CReadConfig & copasiFile);
void processSteadyState(CModel & model, CReadConfig & copasiFile);

int main(int argc, char *argv[])
{
  try
    {
      CCopasiContainer::init();
      Copasi = new CGlobals;

      // Parse the commandline options
      COptions::init(argc, argv);

      // Get the name of the SystemFunctionDB
      std::string tmp;
      COptions::getValue("SystemFunctionDB", tmp);
      Copasi->pFunctionDB->setFilename(tmp);

      // Get the name of the CopasiFile
      COptions::getValue("CopasiFile", tmp);
      CReadConfig CopasiFile(tmp);

      // Load the model
      CModel Model;
      Model.load(CopasiFile);

      // Load the output specifications
      Copasi->pOutputList->load(CopasiFile);

      bool runTrajectory;
      CopasiFile.getVariable("Dynamics", "bool", &runTrajectory,
                             CReadConfig::LOOP);
      bool runSteadyState;
      CopasiFile.getVariable("SteadyState", "bool", & runSteadyState);

      if (runTrajectory) processTrajectory(Model, CopasiFile);
      if (runSteadyState) processSteadyState(Model, CopasiFile);
    }

  catch (copasi::autoexcept &e)
    {
      switch (e.get_autothrow_id())
        {
        case copasi::autothrow_help:
          std::cout << "Usage: " << argv[0] << " [options]\n";
          std::cout << e.what();
        }
    }

  catch (copasi::option_error &e)
    {
      std::cerr << argv[0] << ": " << e.what() << "\n";
      std::cerr << e.get_help_comment() << std::endl;
    }

  catch (CCopasiException Exception)
    {
      std::cout << Exception.getMessage().getText() << std::endl;
    }

  pdelete(Copasi);
  pdelete(CCopasiContainer::Root);

  std::cout << "Leaving main program." << std::endl;
  return 0;
}

void processTrajectory(CModel & model, CReadConfig & copasiFile)
{
  CTrajectoryTask task;

  task.load(copasiFile);

  task.getProblem()->setModel(&model);

  std::ofstream TrajectoryFile(Copasi->pOutputList->getTrajectoryFile().c_str());
  task.initialize(&TrajectoryFile);

  task.process();
}

void processSteadyState(CModel & model, CReadConfig & copasiFile)
{
  CSteadyStateTask task;

  task.load(copasiFile);

  task.getProblem()->setModel(&model);

  std::ofstream SteadyStateFile(Copasi->pOutputList->getSteadyStateFile().c_str());
  task.initialize(&SteadyStateFile);

  task.process();
}
<commit_msg>fixes to make it compile again.<commit_after>/* Begin CVS Header
   $Source: /Volumes/Home/Users/shoops/cvs/copasi_dev/copasi/CopasiSE/CopasiSE.cpp,v $
   $Revision: 1.7 $
   $Name:  $
   $Author: ssahle $
   $Date: 2004/05/11 09:52:34 $
   End CVS Header */

// Main
//
// (C) Stefan Hoops 2002
//

#ifdef XXXX
#ifdef WIN32
# include <windows.h>
# include <winbase.h>
# include <direct.h>
# define getcwd _getcwd
# ifdef ERROR
#  undef ERROR
# endif
#else
# include <unistd.h>
#endif
#endif

#include <stdlib.h>
#include <sstream>
#include <string>
#include <iostream>

#define COPASI_MAIN
#define COPASI_TRACE_CONSTRUCTION

#include "copasi.h"
#include "utilities/CGlobals.h"
#include "utilities/CCopasiMessage.h"
#include "utilities/CCopasiException.h"
#include "commandline/COptionParser.h"
#include "commandline/COptions.h"
#include "function/CFunctionDB.h"
#include "model/CModel.h"
#include "output/COutputList.h"
#include "output/COutput.h"
#include "trajectory/CTrajectoryTask.h"
#include "trajectory/CTrajectoryProblem.h"
#include "steadystate/CSteadyStateTask.h"
#include "steadystate/CSteadyStateProblem.h"

void processTrajectory(CModel & model, CReadConfig & copasiFile);
void processSteadyState(CModel & model, CReadConfig & copasiFile);

int main(int argc, char *argv[])
{
  try
    {
      CCopasiContainer::init();
      Copasi = new CGlobals;

      // Parse the commandline options
      COptions::init(argc, argv);

      // Get the name of the SystemFunctionDB
      std::string tmp;
      COptions::getValue("SystemFunctionDB", tmp);
      Copasi->pFunctionDB->setFilename(tmp);

      // Get the name of the CopasiFile
      COptions::getValue("CopasiFile", tmp);
      CReadConfig CopasiFile(tmp);

      // Load the model
      CModel Model;
      Model.load(CopasiFile);

      // Load the output specifications
      //Copasi->pOutputList->load(CopasiFile);//TODO

      bool runTrajectory;
      CopasiFile.getVariable("Dynamics", "bool", &runTrajectory,
                             CReadConfig::LOOP);
      bool runSteadyState;
      CopasiFile.getVariable("SteadyState", "bool", & runSteadyState);

      if (runTrajectory) processTrajectory(Model, CopasiFile);
      if (runSteadyState) processSteadyState(Model, CopasiFile);
    }

  catch (copasi::autoexcept &e)
    {
      switch (e.get_autothrow_id())
        {
        case copasi::autothrow_help:
          std::cout << "Usage: " << argv[0] << " [options]\n";
          std::cout << e.what();
        }
    }

  catch (copasi::option_error &e)
    {
      std::cerr << argv[0] << ": " << e.what() << "\n";
      std::cerr << e.get_help_comment() << std::endl;
    }

  catch (CCopasiException Exception)
    {
      std::cout << Exception.getMessage().getText() << std::endl;
    }

  pdelete(Copasi);
  pdelete(CCopasiContainer::Root);

  std::cout << "Leaving main program." << std::endl;
  return 0;
}

void processTrajectory(CModel & model, CReadConfig & copasiFile)
{
  CTrajectoryTask task;

  task.load(copasiFile);

  task.getProblem()->setModel(&model);

  std::ofstream TrajectoryFile("TEST.DAT" /*Copasi->pOutputList->getTrajectoryFile().c_str()*/);
  task.initialize(&TrajectoryFile);

  task.process();
}

void processSteadyState(CModel & model, CReadConfig & copasiFile)
{
  CSteadyStateTask task;

  task.load(copasiFile);

  task.getProblem()->setModel(&model);

  std::ofstream SteadyStateFile("TEST.DAT" /*Copasi->pOutputList->getSteadyStateFile().c_str()*/);
  task.initialize(&SteadyStateFile);

  task.process();
}
<|endoftext|>


<commit_before>//* This file is part of the MOOSE framework
//* https://www.mooseframework.org
//*
//* All rights reserved, see COPYRIGHT for full restrictions
//* https://github.com/idaholab/moose/blob/master/COPYRIGHT
//*
//* Licensed under LGPL 2.1, please see LICENSE for details
//* https://www.gnu.org/licenses/lgpl-2.1.html

#include "libmesh/petsc_macro.h"
#include "FieldSplitPreconditioner.h"

// MOOSE includes
#include "FEProblem.h"
#include "MooseEnum.h"
#include "MooseVariableFE.h"
#include "NonlinearSystem.h"
#include "PetscSupport.h"

#include "libmesh/libmesh_common.h"
#include "libmesh/petsc_nonlinear_solver.h"
#include "libmesh/coupling_matrix.h"

registerMooseObjectAliased("MooseApp", FieldSplitPreconditioner, "FSP");

defineLegacyParams(FieldSplitPreconditioner);

InputParameters
FieldSplitPreconditioner::validParams()
{
  InputParameters params = MoosePreconditioner::validParams();
  params.addClassDescription("Preconditioner designed to map onto PETSc's PCFieldSplit.");
  params.addParam<std::vector<std::string>>(
      "off_diag_row",
      "The off diagonal row you want to add into the matrix, it will be associated "
      "with an off diagonal column from the same position in off_diag_colum.");
  params.addParam<std::vector<std::string>>("off_diag_column",
                                            "The off diagonal column you want to add into the "
                                            "matrix, it will be associated with an off diagonal "
                                            "row from the same position in off_diag_row.");
  // We should use full coupling Jacobian matrix by default
  params.addParam<bool>("full",
                        true,
                        "Set to true if you want the full set of couplings.  Simply "
                        "for convenience so you don't have to set every off_diag_row "
                        "and off_diag_column combination.");
  params.addRequiredParam<std::vector<std::string>>(
      "topsplit", "entrance to splits, the top split will specify how splits will go.");
  return params;
}

FieldSplitPreconditioner::FieldSplitPreconditioner(const InputParameters & parameters)
  : MoosePreconditioner(parameters),
    _top_split(getParam<std::vector<std::string>>("topsplit")),
    _nl(_fe_problem.getNonlinearSystemBase())
{
  // number of variables
  unsigned int n_vars = _nl.nVariables();
  // if we want to construct a full Jacobian?
  // it is recommended to have a full Jacobian for using
  // the fieldSplit preconditioner
  bool full = getParam<bool>("full");
  // how variables couple
  std::unique_ptr<CouplingMatrix> cm = std::make_unique<CouplingMatrix>(n_vars);
  if (!full)
  {
    // put 1s on diagonal
    for (unsigned int i = 0; i < n_vars; i++)
      (*cm)(i, i) = 1;

    // off-diagonal entries
    std::vector<std::vector<unsigned int>> off_diag(n_vars);
    for (unsigned int i = 0; i < getParam<std::vector<std::string>>("off_diag_row").size(); i++)
    {
      unsigned int row =
          _nl.getVariable(0, getParam<std::vector<std::string>>("off_diag_row")[i]).number();
      unsigned int column =
          _nl.getVariable(0, getParam<std::vector<std::string>>("off_diag_column")[i]).number();
      (*cm)(row, column) = 1;
    }
  }
  else
  {
    for (unsigned int i = 0; i < n_vars; i++)
      for (unsigned int j = 0; j < n_vars; j++)
        (*cm)(i, j) = 1; // full coupling
  }
  _fe_problem.setCouplingMatrix(std::move(cm));

  // turn on a flag
  _nl.useFieldSplitPreconditioner(true);

  // set a top splitting
  _fe_problem.getNonlinearSystemBase().setDecomposition(_top_split);

  // apply prefix and store PETSc options
  _fe_problem.getNonlinearSystemBase().setupFieldDecomposition();
}
<commit_msg>Add parameter checks on setting off-diagonal couplings<commit_after>//* This file is part of the MOOSE framework
//* https://www.mooseframework.org
//*
//* All rights reserved, see COPYRIGHT for full restrictions
//* https://github.com/idaholab/moose/blob/master/COPYRIGHT
//*
//* Licensed under LGPL 2.1, please see LICENSE for details
//* https://www.gnu.org/licenses/lgpl-2.1.html

#include "libmesh/petsc_macro.h"
#include "FieldSplitPreconditioner.h"

// MOOSE includes
#include "FEProblem.h"
#include "MooseEnum.h"
#include "MooseVariableFE.h"
#include "NonlinearSystem.h"
#include "PetscSupport.h"

#include "libmesh/libmesh_common.h"
#include "libmesh/petsc_nonlinear_solver.h"
#include "libmesh/coupling_matrix.h"

registerMooseObjectAliased("MooseApp", FieldSplitPreconditioner, "FSP");

defineLegacyParams(FieldSplitPreconditioner);

InputParameters
FieldSplitPreconditioner::validParams()
{
  InputParameters params = MoosePreconditioner::validParams();
  params.addClassDescription("Preconditioner designed to map onto PETSc's PCFieldSplit.");
  params.addParam<std::vector<std::string>>(
      "off_diag_row",
      "The off diagonal row you want to add into the matrix, it will be associated "
      "with an off diagonal column from the same position in off_diag_column.");
  params.addParam<std::vector<std::string>>("off_diag_column",
                                            "The off diagonal column you want to add into the "
                                            "matrix, it will be associated with an off diagonal "
                                            "row from the same position in off_diag_row.");
  // We should use full coupling Jacobian matrix by default
  params.addParam<bool>("full",
                        true,
                        "Set to true if you want the full set of couplings.  Simply "
                        "for convenience so you don't have to set every off_diag_row "
                        "and off_diag_column combination.");
  params.addRequiredParam<std::vector<std::string>>(
      "topsplit", "entrance to splits, the top split will specify how splits will go.");
  return params;
}

FieldSplitPreconditioner::FieldSplitPreconditioner(const InputParameters & parameters)
  : MoosePreconditioner(parameters),
    _top_split(getParam<std::vector<std::string>>("topsplit")),
    _nl(_fe_problem.getNonlinearSystemBase())
{
  // number of variables
  unsigned int n_vars = _nl.nVariables();
  // if we want to construct a full Jacobian?
  // it is recommended to have a full Jacobian for using
  // the fieldSplit preconditioner
  bool full = getParam<bool>("full");

  // We either have a full coupling or a custom coupling
  if (full && isParamValid("off_diag_row"))
    paramError("off_diag_row", "Set full=false to specify the off-diagonal rows manually");
  if (full && isParamValid("off_diag_column"))
    paramError("off_diag_column", "Set full=false to specify the off-diagonal columns manually");

  // Off-diagonal rows and colums must match
  const auto off_diag_rows = getParam<std::vector<std::string>>("off_diag_row");
  const auto off_diag_columns = getParam<std::vector<std::string>>("off_diag_column");
  if (isParamValid("off_diag_row"))
  {
    if (isParamValid("off_diag_column"))
    {
      if (off_diag_rows.size() != off_diag_columns.size())
        paramError("off_diag_row", "Off-diagonal rows should be paired one to one with "
                                   "off-diagonal columns");
    }
    else
      paramError("off_diag_row", "If off-diagonal rows are specified, matching off-diagonal "
                                 "columns must be specified as well");
  }
  else if (isParamValid("off_diag_column"))
    paramError("off_diag_column", "If off-diagonal columns are specified, matching off-diagonal "
                                  "rows must be specified as well");

  // how variables couple
  std::unique_ptr<CouplingMatrix> cm = std::make_unique<CouplingMatrix>(n_vars);
  if (!full)
  {
    // put 1s on diagonal
    for (unsigned int i = 0; i < n_vars; i++)
      (*cm)(i, i) = 1;

    // off-diagonal entries
    std::vector<std::vector<unsigned int>> off_diag(n_vars);
    for (unsigned int i = 0; i < off_diag_rows.size(); i++)
    {
      unsigned int row =
          _nl.getVariable(0, off_diag_rows[i]).number();
      unsigned int column =
          _nl.getVariable(0, off_diag_columns[i]).number();
      (*cm)(row, column) = 1;
    }
  }
  else
  {
    for (unsigned int i = 0; i < n_vars; i++)
      for (unsigned int j = 0; j < n_vars; j++)
        (*cm)(i, j) = 1; // full coupling
  }
  _fe_problem.setCouplingMatrix(std::move(cm));

  // turn on a flag
  _nl.useFieldSplitPreconditioner(true);

  // set a top splitting
  _fe_problem.getNonlinearSystemBase().setDecomposition(_top_split);

  // apply prefix and store PETSc options
  _fe_problem.getNonlinearSystemBase().setupFieldDecomposition();
}
<|endoftext|>


<commit_before>// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "ash/wm/workspace/workspace_event_handler.h"

#include "ash/screen_ash.h"
#include "ash/shell.h"
#include "ash/wm/property_util.h"
#include "ash/wm/window_util.h"
#include "ash/wm/workspace/workspace_window_resizer.h"
#include "ui/aura/client/aura_constants.h"
#include "ui/aura/window.h"
#include "ui/aura/window_delegate.h"
#include "ui/base/events/event.h"
#include "ui/base/events/event_functions.h"
#include "ui/base/hit_test.h"
#include "ui/compositor/scoped_layer_animation_settings.h"
#include "ui/gfx/screen.h"

namespace ash {
namespace {

void SingleAxisMaximize(aura::Window* window, const gfx::Rect& maximize_rect) {
  gfx::Rect bounds_in_screen =
      ScreenAsh::ConvertRectToScreen(window->parent(), window->bounds());

  window->ClearProperty(aura::client::kRestoreBoundsKey);
  window->SetProperty(aura::client::kRestoreBoundsKey,
                      new gfx::Rect(bounds_in_screen));
  window->SetBounds(maximize_rect);
}

void SingleAxisUnmaximize(aura::Window* window,
                          const gfx::Rect& restore_bounds_in_screen) {
  gfx::Rect restore_bounds = ScreenAsh::ConvertRectFromScreen(
      window->parent(), restore_bounds_in_screen);
  window->SetBounds(restore_bounds);
  window->ClearProperty(aura::client::kRestoreBoundsKey);
}

void ToggleMaximizedState(aura::Window* window) {
  if (GetRestoreBoundsInScreen(window)) {
    if (window->GetProperty(aura::client::kShowStateKey) ==
        ui::SHOW_STATE_NORMAL) {
      window->SetBounds(GetRestoreBoundsInParent(window));
      ClearRestoreBounds(window);
    } else {
      window->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_NORMAL);
    }
  } else if (wm::CanMaximizeWindow(window)) {
    window->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_MAXIMIZED);
  }
}

}  // namespace

namespace internal {

WorkspaceEventHandler::WorkspaceEventHandler(aura::Window* owner)
    : ToplevelWindowEventHandler(owner),
      destroyed_(NULL) {
}

WorkspaceEventHandler::~WorkspaceEventHandler() {
  if (destroyed_)
    *destroyed_ = true;
}

ui::EventResult WorkspaceEventHandler::OnMouseEvent(ui::MouseEvent* event) {
  aura::Window* target = static_cast<aura::Window*>(event->target());
  switch (event->type()) {
    case ui::ET_MOUSE_MOVED: {
      int component =
          target->delegate()->GetNonClientComponent(event->location());
      multi_window_resize_controller_.Show(target, component,
                                           event->location());
      break;
    }
    case ui::ET_MOUSE_ENTERED:
      break;
    case ui::ET_MOUSE_CAPTURE_CHANGED:
    case ui::ET_MOUSE_EXITED:
      break;
    case ui::ET_MOUSE_PRESSED: {
      // Maximize behavior is implemented as post-target handling so the target
      // can cancel it.
      if (ui::EventCanceledDefaultHandling(*event))
        return ToplevelWindowEventHandler::OnMouseEvent(event);

      if (event->flags() & ui::EF_IS_DOUBLE_CLICK &&
          target->delegate()->GetNonClientComponent(event->location()) ==
          HTCAPTION) {
        bool destroyed = false;
        destroyed_ = &destroyed;
        ToggleMaximizedState(target);
        if (destroyed)
          return ui::ER_UNHANDLED;
        destroyed_ = NULL;
      }
      multi_window_resize_controller_.Hide();
      HandleVerticalResizeDoubleClick(target, event);
      break;
    }
    default:
      break;
  }
  return ToplevelWindowEventHandler::OnMouseEvent(event);
}

ui::EventResult WorkspaceEventHandler::OnGestureEvent(ui::GestureEvent* event) {
  aura::Window* target = static_cast<aura::Window*>(event->target());
  if (event->type() == ui::ET_GESTURE_DOUBLE_TAP &&
      target->delegate()->GetNonClientComponent(event->location()) ==
      HTCAPTION) {
    ToggleMaximizedState(target);  // |this| may be destroyed from here.
    return ui::ER_CONSUMED;
  }
  return ToplevelWindowEventHandler::OnGestureEvent(event);
}

WindowResizer* WorkspaceEventHandler::CreateWindowResizer(
    aura::Window* window,
    const gfx::Point& point_in_parent,
    int window_component) {
  // Allow dragging maximized windows if it's not tracked by workspace. This is
  // set by tab dragging code.
  if (!wm::IsWindowNormal(window) &&
      (window_component != HTCAPTION || GetTrackedByWorkspace(window))) {
    return NULL;
  }
  return WorkspaceWindowResizer::Create(
      window, point_in_parent, window_component,
      std::vector<aura::Window*>());
}

void WorkspaceEventHandler::HandleVerticalResizeDoubleClick(
    aura::Window* target,
    ui::MouseEvent* event) {
  if (event->flags() & ui::EF_IS_DOUBLE_CLICK &&
      !wm::IsWindowMaximized(target)) {
    int component =
        target->delegate()->GetNonClientComponent(event->location());
    gfx::Rect work_area =
        Shell::GetScreen()->GetDisplayNearestWindow(target).work_area();
    const gfx::Rect* restore_bounds =
        target->GetProperty(aura::client::kRestoreBoundsKey);
    if (component == HTBOTTOM || component == HTTOP) {
      if (restore_bounds &&
          (target->bounds().height() == work_area.height() &&
           target->bounds().y() == work_area.y())) {
        SingleAxisUnmaximize(target, *restore_bounds);
      } else {
        SingleAxisMaximize(target,
                           gfx::Rect(target->bounds().x(),
                                     work_area.y(),
                                     target->bounds().width(),
                                     work_area.height()));
      }
    } else if (component == HTLEFT || component == HTRIGHT) {
      if (restore_bounds &&
          (target->bounds().width() == work_area.width() &&
           target->bounds().x() == work_area.x())) {
        SingleAxisUnmaximize(target, *restore_bounds);
      } else {
        SingleAxisMaximize(target,
                           gfx::Rect(work_area.x(),
                                     target->bounds().y(),
                                     work_area.width(),
                                     target->bounds().height()));
      }
    }
  }
}

}  // namespace internal
}  // namespace ash
<commit_msg>Revert 162913 - Don't maximize on double-click if CanMaximize is false.<commit_after>// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "ash/wm/workspace/workspace_event_handler.h"

#include "ash/screen_ash.h"
#include "ash/shell.h"
#include "ash/wm/property_util.h"
#include "ash/wm/window_util.h"
#include "ash/wm/workspace/workspace_window_resizer.h"
#include "ui/aura/client/aura_constants.h"
#include "ui/aura/window.h"
#include "ui/aura/window_delegate.h"
#include "ui/base/events/event.h"
#include "ui/base/events/event_functions.h"
#include "ui/base/hit_test.h"
#include "ui/compositor/scoped_layer_animation_settings.h"
#include "ui/gfx/screen.h"

namespace ash {
namespace {

void SingleAxisMaximize(aura::Window* window, const gfx::Rect& maximize_rect) {
  gfx::Rect bounds_in_screen =
      ScreenAsh::ConvertRectToScreen(window->parent(), window->bounds());

  window->ClearProperty(aura::client::kRestoreBoundsKey);
  window->SetProperty(aura::client::kRestoreBoundsKey,
                      new gfx::Rect(bounds_in_screen));
  window->SetBounds(maximize_rect);
}

void SingleAxisUnmaximize(aura::Window* window,
                          const gfx::Rect& restore_bounds_in_screen) {
  gfx::Rect restore_bounds = ScreenAsh::ConvertRectFromScreen(
      window->parent(), restore_bounds_in_screen);
  window->SetBounds(restore_bounds);
  window->ClearProperty(aura::client::kRestoreBoundsKey);
}

void ToggleMaximizedState(aura::Window* window) {
  if (GetRestoreBoundsInScreen(window)) {
    if (window->GetProperty(aura::client::kShowStateKey) ==
        ui::SHOW_STATE_NORMAL) {
      window->SetBounds(GetRestoreBoundsInParent(window));
      ClearRestoreBounds(window);
    } else {
      window->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_NORMAL);
    }
  } else {
    window->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_MAXIMIZED);
  }
}

}  // namespace

namespace internal {

WorkspaceEventHandler::WorkspaceEventHandler(aura::Window* owner)
    : ToplevelWindowEventHandler(owner),
      destroyed_(NULL) {
}

WorkspaceEventHandler::~WorkspaceEventHandler() {
  if (destroyed_)
    *destroyed_ = true;
}

ui::EventResult WorkspaceEventHandler::OnMouseEvent(ui::MouseEvent* event) {
  aura::Window* target = static_cast<aura::Window*>(event->target());
  switch (event->type()) {
    case ui::ET_MOUSE_MOVED: {
      int component =
          target->delegate()->GetNonClientComponent(event->location());
      multi_window_resize_controller_.Show(target, component,
                                           event->location());
      break;
    }
    case ui::ET_MOUSE_ENTERED:
      break;
    case ui::ET_MOUSE_CAPTURE_CHANGED:
    case ui::ET_MOUSE_EXITED:
      break;
    case ui::ET_MOUSE_PRESSED: {
      // Maximize behavior is implemented as post-target handling so the target
      // can cancel it.
      if (ui::EventCanceledDefaultHandling(*event))
        return ToplevelWindowEventHandler::OnMouseEvent(event);

      if (event->flags() & ui::EF_IS_DOUBLE_CLICK &&
          target->delegate()->GetNonClientComponent(event->location()) ==
          HTCAPTION) {
        bool destroyed = false;
        destroyed_ = &destroyed;
        ToggleMaximizedState(target);
        if (destroyed)
          return ui::ER_UNHANDLED;
        destroyed_ = NULL;
      }
      multi_window_resize_controller_.Hide();
      HandleVerticalResizeDoubleClick(target, event);
      break;
    }
    default:
      break;
  }
  return ToplevelWindowEventHandler::OnMouseEvent(event);
}

ui::EventResult WorkspaceEventHandler::OnGestureEvent(ui::GestureEvent* event) {
  aura::Window* target = static_cast<aura::Window*>(event->target());
  if (event->type() == ui::ET_GESTURE_DOUBLE_TAP &&
      target->delegate()->GetNonClientComponent(event->location()) ==
      HTCAPTION) {
    ToggleMaximizedState(target);  // |this| may be destroyed from here.
    return ui::ER_CONSUMED;
  }
  return ToplevelWindowEventHandler::OnGestureEvent(event);
}

WindowResizer* WorkspaceEventHandler::CreateWindowResizer(
    aura::Window* window,
    const gfx::Point& point_in_parent,
    int window_component) {
  // Allow dragging maximized windows if it's not tracked by workspace. This is
  // set by tab dragging code.
  if (!wm::IsWindowNormal(window) &&
      (window_component != HTCAPTION || GetTrackedByWorkspace(window))) {
    return NULL;
  }
  return WorkspaceWindowResizer::Create(
      window, point_in_parent, window_component,
      std::vector<aura::Window*>());
}

void WorkspaceEventHandler::HandleVerticalResizeDoubleClick(
    aura::Window* target,
    ui::MouseEvent* event) {
  if (event->flags() & ui::EF_IS_DOUBLE_CLICK &&
      !wm::IsWindowMaximized(target)) {
    int component =
        target->delegate()->GetNonClientComponent(event->location());
    gfx::Rect work_area =
        Shell::GetScreen()->GetDisplayNearestWindow(target).work_area();
    const gfx::Rect* restore_bounds =
        target->GetProperty(aura::client::kRestoreBoundsKey);
    if (component == HTBOTTOM || component == HTTOP) {
      if (restore_bounds &&
          (target->bounds().height() == work_area.height() &&
           target->bounds().y() == work_area.y())) {
        SingleAxisUnmaximize(target, *restore_bounds);
      } else {
        SingleAxisMaximize(target,
                           gfx::Rect(target->bounds().x(),
                                     work_area.y(),
                                     target->bounds().width(),
                                     work_area.height()));
      }
    } else if (component == HTLEFT || component == HTRIGHT) {
      if (restore_bounds &&
          (target->bounds().width() == work_area.width() &&
           target->bounds().x() == work_area.x())) {
        SingleAxisUnmaximize(target, *restore_bounds);
      } else {
        SingleAxisMaximize(target,
                           gfx::Rect(work_area.x(),
                                     target->bounds().y(),
                                     work_area.width(),
                                     target->bounds().height()));
      }
    }
  }
}

}  // namespace internal
}  // namespace ash
<|endoftext|>


<commit_before>/* bzflag
 * Copyright (c) 1993 - 2003 Tim Riker
 *
 * This package is free software;  you can redistribute it and/or
 * modify it under the terms of the license found in the file
 * named COPYING that should have accompanied this file.
 *
 * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 */

#include "CursesUI.h"

using namespace std;

// add this UI to the map
UIAdder CursesUI::uiAdder("curses", &CursesUI::creator);

CursesUI::CursesUI(const map<PlayerId, string>& p, PlayerId m) :
  players(p), me(m), maxHistory(20), currentHistory(0) {

  // initialize ncurses
  initscr();
  nonl();
  cbreak();
  noecho();

  // create main output window
  mainWin = newwin(LINES - 5, 0, 0, 0);
  wsetscrreg(mainWin, 0, LINES - 2);
  scrollok(mainWin, TRUE);
  wrefresh(mainWin);

  // create target window
  targetWin = newwin(1, 0, LINES - 2, 0);
  wattron(targetWin, A_UNDERLINE);
  targetIter = players.begin();
  updateTargetWin();

  // create command window
  cmdWin = newwin(0, 0, LINES - 1, 0);
  keypad(cmdWin, TRUE);
  nodelay(cmdWin, TRUE);
  updateCmdWin();

  // register commands for tab completion
  comp.registerWord("/lagstats");
  comp.registerWord("/idlestats");
  comp.registerWord("/flaghistory");
  comp.registerWord("/password ");
  comp.registerWord("/report ");
  comp.registerWord("/shutdownserver");
  comp.registerWord("/superkill");
  comp.registerWord("/gameover");
  comp.registerWord("/flag ");
  comp.registerWord("reset");
  comp.registerWord("up");
  comp.registerWord("show");
  comp.registerWord("/kick ");
  comp.registerWord("/playerlist");
  comp.registerWord("/ban ");
  comp.registerWord("/banlist");
  comp.registerWord("/countdown");
  comp.registerWord("/lagwarn ");
  comp.registerWord("/quit");
}

CursesUI::~CursesUI() {
  endwin();
}

void CursesUI::outputMessage(const string& msg) {
  waddstr(mainWin, (msg + "\n").c_str());
  wrefresh(mainWin);
}

bool CursesUI::checkCommand(string& str) {
  wrefresh(cmdWin);
  str = "";
  int i;
  int c = wgetch(cmdWin);
  switch (c) {
  case ERR:
    return false;

    // clear command (21 is Ctrl-U)
  case 21:
    cmd = "";
    updateCmdWin();

    // delete last character
  case KEY_BACKSPACE:
  case KEY_DC:
  case 127:
    cmd = cmd.substr(0, cmd.size() - 1);
    updateCmdWin();
    return false;

    // send command
  case 13:
    if (history.size() == maxHistory)
      history.erase(history.begin());
    history.push_back(cmd);
    str = cmd;
    cmd = "";
    currentHistory = history.size();
    updateCmdWin();
    return true;

    // scroll main window - doesn't work
  case KEY_NPAGE:
    wscrl(mainWin, 1);
    return false;
  case KEY_PPAGE:
    wscrl(mainWin, -1);
    return false;

    // change target
  case KEY_LEFT:
    if (targetIter == players.begin())
      for (unsigned int i = 0; i < players.size() - 1; i++)
	++targetIter;
    else
      targetIter--;
    updateTargetWin();
    return false;
  case KEY_RIGHT:
    targetIter++;
    if (targetIter == players.end())
      targetIter = players.begin();
    updateTargetWin();
    return false;

    // command history
  case KEY_UP:
    if (currentHistory != 0)
      --currentHistory;
    cmd = history[currentHistory];
    updateCmdWin();
    return false;
  case KEY_DOWN:
    if (currentHistory < history.size())
      ++currentHistory;
    if (currentHistory == history.size())
      cmd = "";
    else
      cmd = history[currentHistory];
    updateCmdWin();
    return false;

    // kick target
  case KEY_F(5):
    if (targetIter != players.end() && targetIter->first != me) {
      cmd = "/kick ";
      cmd += targetIter->second;
      targetIter = players.find(me);
      updateCmdWin();
      updateTargetWin();
    }
    return false;

    // tab - autocomplete
  case '\t':
    i = cmd.find_last_of(" \t");
    cmd = cmd.substr(0, i+1) + comp.complete(cmd.substr(i+1));
    updateCmdWin();
    return false;

  default:
    if (c < 32 || c > 127 || cmd.size() >= CMDLENGTH)
      return false;
    cmd += char(c);
    updateCmdWin();
    return false;
  }
}

void CursesUI::addedPlayer(PlayerId p) {
  comp.registerWord(players.find(p)->second);
}

void CursesUI::removingPlayer(PlayerId p) {
  if (targetIter->first == p) {
    targetIter = players.find(me);
    updateTargetWin();
  }
  comp.unregisterWord(players.find(p)->second);
}

PlayerId CursesUI::getTarget() const {
  if (targetIter->first == me)
    return AllPlayers;
  return targetIter->first;
}

void CursesUI::updateTargetWin() {
  wclear(targetWin);
  wmove(targetWin, 0, 0);
  wmove(targetWin, 1, 1);
  string tmp = "Send to ";
  tmp = tmp + (targetIter == players.end() || targetIter->first == me ?
	       "all" : targetIter->second) + ":";
  waddstr(targetWin, tmp.c_str());
  wrefresh(targetWin);
}

void CursesUI::updateCmdWin() {
  wclear(cmdWin);
  wmove(cmdWin, 1, 1);
  waddstr(cmdWin, cmd.c_str());
  wmove(cmdWin, 1, 1 + cmd.size());
  wrefresh(cmdWin);
}

BZAdminUI* CursesUI::creator(const map<PlayerId, string>& players,
			     PlayerId me) {
  return new CursesUI(players, me);
}
<commit_msg>Register more commands for tab completion in bzadmin<commit_after>/* bzflag
 * Copyright (c) 1993 - 2003 Tim Riker
 *
 * This package is free software;  you can redistribute it and/or
 * modify it under the terms of the license found in the file
 * named COPYING that should have accompanied this file.
 *
 * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 */

#include "CursesUI.h"

using namespace std;

// add this UI to the map
UIAdder CursesUI::uiAdder("curses", &CursesUI::creator);

CursesUI::CursesUI(const map<PlayerId, string>& p, PlayerId m) :
  players(p), me(m), maxHistory(20), currentHistory(0) {

  // initialize ncurses
  initscr();
  nonl();
  cbreak();
  noecho();

  // create main output window
  mainWin = newwin(LINES - 5, 0, 0, 0);
  wsetscrreg(mainWin, 0, LINES - 2);
  scrollok(mainWin, TRUE);
  wrefresh(mainWin);

  // create target window
  targetWin = newwin(1, 0, LINES - 2, 0);
  wattron(targetWin, A_UNDERLINE);
  targetIter = players.begin();
  updateTargetWin();

  // create command window
  cmdWin = newwin(0, 0, LINES - 1, 0);
  keypad(cmdWin, TRUE);
  nodelay(cmdWin, TRUE);
  updateCmdWin();

  // register commands for tab completion
  comp.registerWord("/lagstats");
  comp.registerWord("/idlestats");
  comp.registerWord("/flaghistory");
  comp.registerWord("/password ");
  comp.registerWord("/report ");
  comp.registerWord("/shutdownserver");
  comp.registerWord("/superkill");
  comp.registerWord("/gameover");
  comp.registerWord("/flag ");
  comp.registerWord("reset");
  comp.registerWord("up");
  comp.registerWord("show");
  comp.registerWord("/kick ");
  comp.registerWord("/playerlist");
  comp.registerWord("/ban ");
  comp.registerWord("/banlist");
  comp.registerWord("/countdown");
  comp.registerWord("/lagwarn ");
  comp.registerWord("/quit");
  comp.registerWord("/unban ");
  comp.registerWord("/lagwarn ");
  comp.registerWord("/help");
  comp.registerWord("/identify ");
  comp.registerWord("/register ");
  comp.registerWord("/ghost ");
  comp.registerWord("/deregister");
  comp.registerWord("/setpass ");
  comp.registerWord("/groupperms");
  comp.registerWord("/setgroup ");
  comp.registerWord("/removegroup ");
  comp.registerWord("/reload");
  comp.registerWord("/poll ");
  comp.registerWord("ban");
  comp.registerWord("kick");
  comp.registerWord("vote");
  comp.registerWord("veto");
  comp.registerWord("/");
}

CursesUI::~CursesUI() {
  endwin();
}

void CursesUI::outputMessage(const string& msg) {
  waddstr(mainWin, (msg + "\n").c_str());
  wrefresh(mainWin);
}

bool CursesUI::checkCommand(string& str) {
  wrefresh(cmdWin);
  str = "";
  int i;
  int c = wgetch(cmdWin);
  switch (c) {
  case ERR:
    return false;

    // clear command (21 is Ctrl-U)
  case 21:
    cmd = "";
    updateCmdWin();

    // delete last character
  case KEY_BACKSPACE:
  case KEY_DC:
  case 127:
    cmd = cmd.substr(0, cmd.size() - 1);
    updateCmdWin();
    return false;

    // send command
  case 13:
    if (history.size() == maxHistory)
      history.erase(history.begin());
    history.push_back(cmd);
    str = cmd;
    cmd = "";
    currentHistory = history.size();
    updateCmdWin();
    return true;

    // scroll main window - doesn't work
  case KEY_NPAGE:
    wscrl(mainWin, 1);
    return false;
  case KEY_PPAGE:
    wscrl(mainWin, -1);
    return false;

    // change target
  case KEY_LEFT:
    if (targetIter == players.begin())
      for (unsigned int i = 0; i < players.size() - 1; i++)
	++targetIter;
    else
      targetIter--;
    updateTargetWin();
    return false;
  case KEY_RIGHT:
    targetIter++;
    if (targetIter == players.end())
      targetIter = players.begin();
    updateTargetWin();
    return false;

    // command history
  case KEY_UP:
    if (currentHistory != 0)
      --currentHistory;
    cmd = history[currentHistory];
    updateCmdWin();
    return false;
  case KEY_DOWN:
    if (currentHistory < history.size())
      ++currentHistory;
    if (currentHistory == history.size())
      cmd = "";
    else
      cmd = history[currentHistory];
    updateCmdWin();
    return false;

    // kick target
  case KEY_F(5):
    if (targetIter != players.end() && targetIter->first != me) {
      cmd = "/kick ";
      cmd += targetIter->second;
      targetIter = players.find(me);
      updateCmdWin();
      updateTargetWin();
    }
    return false;

    // tab - autocomplete
  case '\t':
    i = cmd.find_last_of(" \t");
    cmd = cmd.substr(0, i+1) + comp.complete(cmd.substr(i+1));
    updateCmdWin();
    return false;

  default:
    if (c < 32 || c > 127 || cmd.size() >= CMDLENGTH)
      return false;
    cmd += char(c);
    updateCmdWin();
    return false;
  }
}

void CursesUI::addedPlayer(PlayerId p) {
  comp.registerWord(players.find(p)->second);
}

void CursesUI::removingPlayer(PlayerId p) {
  if (targetIter->first == p) {
    targetIter = players.find(me);
    updateTargetWin();
  }
  comp.unregisterWord(players.find(p)->second);
}

PlayerId CursesUI::getTarget() const {
  if (targetIter->first == me)
    return AllPlayers;
  return targetIter->first;
}

void CursesUI::updateTargetWin() {
  wclear(targetWin);
  wmove(targetWin, 0, 0);
  wmove(targetWin, 1, 1);
  string tmp = "Send to ";
  tmp = tmp + (targetIter == players.end() || targetIter->first == me ?
	       "all" : targetIter->second) + ":";
  waddstr(targetWin, tmp.c_str());
  wrefresh(targetWin);
}

void CursesUI::updateCmdWin() {
  wclear(cmdWin);
  wmove(cmdWin, 1, 1);
  waddstr(cmdWin, cmd.c_str());
  wmove(cmdWin, 1, 1 + cmd.size());
  wrefresh(cmdWin);
}

BZAdminUI* CursesUI::creator(const map<PlayerId, string>& players,
			     PlayerId me) {
  return new CursesUI(players, me);
}
<|endoftext|>


<commit_before>/* bzflag
 * Copyright (c) 1993 - 2004 Tim Riker
 *
 * This package is free software;  you can redistribute it and/or
 * modify it under the terms of the license found in the file
 * named COPYING that should have accompanied this file.
 *
 * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 */

#ifdef _MSC_VER
#pragma warning( 4: 4786)
#endif

#include "CursesUI.h"

// add this UI to the map
UIAdder CursesUI::uiAdder("curses", &CursesUI::creator);

CursesUI::CursesUI(BZAdminClient& c) :
  BZAdminUI(c),
  menuState(0), menu(c.getPlayers()), client(c), players(c.getPlayers()),
  me(c.getMyId()), maxHistory(20), currentHistory(0),
  maxBufferSize(300), scrollOffset(0) {

  // initialize ncurses
  initscr();
  start_color();
  use_default_colors();
  init_pair(Default, COLOR_FGDEFAULT, COLOR_BGDEFAULT);
  init_pair(White, COLOR_WHITE, COLOR_BGDEFAULT);
  init_pair(Red, COLOR_RED, COLOR_BGDEFAULT);
  init_pair(Green, COLOR_GREEN, COLOR_BGDEFAULT);
  init_pair(Blue, COLOR_BLUE, COLOR_BGDEFAULT);
  init_pair(Purple, COLOR_MAGENTA, COLOR_BGDEFAULT);
  init_pair(Yellow, COLOR_YELLOW, COLOR_BGDEFAULT);
  init_pair(Cyan, COLOR_CYAN, COLOR_BGDEFAULT);
  nonl();
  cbreak();
  noecho();

  // create main output window
  mainWin = newwin(LINES - 5, 0, 0, 0);
  wsetscrreg(mainWin, 0, LINES - 2);
  scrollok(mainWin, TRUE);
  wrefresh(mainWin);

  // create target window
  targetWin = newwin(1, 0, LINES - 2, 0);
  wattron(targetWin, A_UNDERLINE);
  targetIter = players.begin();
  updateTargetWin();

  // create command window
  cmdWin = newwin(0, 0, LINES - 1, 0);
  keypad(cmdWin, TRUE);
  nodelay(cmdWin, TRUE);
  updateCmdWin();

  // initialize the menu
  menu.setUpdateCallback(initMainMenu);

  // register commands for tab completion
  comp.registerWord("/ban ");
  comp.registerWord("/banlist");
  comp.registerWord("/countdown");
  comp.registerWord("/deregister");
  comp.registerWord("/flag ");
  comp.registerWord("reset");
  comp.registerWord("up");
  comp.registerWord("show");
  comp.registerWord("/flaghistory");
  comp.registerWord("/gameover");
  comp.registerWord("/ghost ");
  comp.registerWord("/groupperms");
  comp.registerWord("/help");
  comp.registerWord("/identify ");
  comp.registerWord("/idlestats");
  comp.registerWord("/kick ");
  comp.registerWord("/lagstats");
  comp.registerWord("/lagwarn ");
  comp.registerWord("/password ");
  comp.registerWord("/playerlist");
  comp.registerWord("/poll ");
  comp.registerWord("ban");
  comp.registerWord("kick");
  comp.registerWord("/quit");
  comp.registerWord("/register ");
  comp.registerWord("/reload");
  comp.registerWord("/removegroup ");
  comp.registerWord("/report ");
  comp.registerWord("/reset");
  comp.registerWord("/set");
  comp.registerWord("/setgroup ");
  comp.registerWord("/setpass ");
  comp.registerWord("/shutdownserver");
  comp.registerWord("/superkill");
  comp.registerWord("/unban ");
  comp.registerWord("/veto");
  comp.registerWord("/vote");
}

CursesUI::~CursesUI() {
  endwin();
}

void CursesUI::outputMessage(const std::string& msg, ColorCode color) {
  // add message to the message buffer, remove the oldest message if it's full
  if (msgBuffer.size() == maxBufferSize)
    msgBuffer.erase(msgBuffer.begin());
  std::pair<std::string, ColorCode> p(msg, color);
  msgBuffer.push_back(p);

  // if we have scrolled away from the bottom, don't show the new message
  if (scrollOffset == 0) {
    wattron(mainWin, COLOR_PAIR(color));
    waddstr(mainWin, (msg + "\n").c_str());
    wattroff(mainWin, COLOR_PAIR(color));
    wrefresh(mainWin);
  }
}

void CursesUI::handleNewPacket(uint16_t code) {
  BZAdminUI::handleNewPacket(code);
}

bool CursesUI::checkCommand(std::string& str) {
  wrefresh(cmdWin);
  str = "";
  int i;

  // get a character and do checks that are always needed
  int c = wgetch(cmdWin);
  switch (c) {
   case KEY_RESIZE:
     handleResize(LINES, COLS);
     return false;
  case KEY_F(2):
    toggleMenu();
    return false;
  case ERR:
    return false;
  }

  // if the menu is active, use the keystrokes for that
  if (menuState == 1)
    return menu.handleKey(c, str);

  // if not, go ahead and parse commands
  switch (c) {

    // clear command (21 is Ctrl-U)
  case 21:
    cmd = "";
    updateCmdWin();
    currentHistory = history.size();

    // delete last character
  case KEY_BACKSPACE:
  case KEY_DC:
  case 127:
    cmd = cmd.substr(0, cmd.size() - 1);
    updateCmdWin();
    return false;

    // redraw command (12 is ctrl-l)
  case 12:
    wclear(cmdWin);
    wclear(targetWin);
    updateCmdWin();
    updateTargetWin();
    return false;

    // send command
  case '\n': // works with PDCurses
  case 13:   // works with ncurses
    if (history.size() == maxHistory)
      history.erase(history.begin());
    history.push_back(cmd);
    str = cmd;
    cmd = "";
    currentHistory = history.size();
    updateCmdWin();
    return true;

    // scroll main window
  case KEY_NPAGE:
    scrollOffset = (scrollOffset < unsigned(LINES - 2) / 2 ?
		    0 : scrollOffset - (LINES - 2) / 2);
    updateMainWinFromBuffer(LINES - 2);
    return false;
  case KEY_PPAGE:
    if (msgBuffer.size() < unsigned(LINES - 2))
      scrollOffset = 0;
    else if (scrollOffset > msgBuffer.size() - (LINES - 2) - (LINES - 2) / 2)
      scrollOffset = msgBuffer.size() - (LINES - 2);
    else
      scrollOffset += (LINES - 2) / 2;
    updateMainWinFromBuffer(LINES - 2);
    return false;

    // change target
  case KEY_LEFT:
    if (targetIter == players.begin())
      for (unsigned int i = 0; i < players.size() - 1; i++)
	++targetIter;
    else
      targetIter--;
    updateTargetWin();
    return false;
  case KEY_RIGHT:
    targetIter++;
    if (targetIter == players.end())
      targetIter = players.begin();
    updateTargetWin();
    return false;

    // command history
  case KEY_UP:
    if (currentHistory == 0 || history.size() == 0)
      return false;
    --currentHistory;
    cmd = history[currentHistory];
    updateCmdWin();
    return false;
  case KEY_DOWN:
    if (currentHistory < history.size())
      ++currentHistory;
    if (currentHistory == history.size())
      cmd = "";
    else
      cmd = history[currentHistory];
    updateCmdWin();
    return false;

    // kick target
  case KEY_F(5):
    if (targetIter != players.end() && targetIter->first != me) {
      cmd = "/kick ";
      cmd += targetIter->second.name;
      targetIter = players.find(me);
      updateCmdWin();
      updateTargetWin();
    }
    return false;

    // ban target (only works if we have done /playerlist earlier)
  case KEY_F(6):
    if (targetIter != players.end() && targetIter->first != me) {
      if (targetIter->second.ip != "") {
	cmd = "/ban ";
	cmd += targetIter->second.ip;
	targetIter = players.find(me);
	updateCmdWin();
	updateTargetWin();
      }
      else {
	std::string msg = "--- Can't ban ";
	msg += targetIter->second.name + ", you don't have the IP address";
	outputMessage(msg, Red);
	outputMessage("--- Trying to fetch IP addresses...", Red);
	str = "/playerlist";
	return true;
      }
    }
    return false;

    // tab - autocomplete
  case '\t':
    i = cmd.find_last_of(" \t");
    cmd = cmd.substr(0, i+1) + comp.complete(cmd.substr(i+1));
    updateCmdWin();
    return false;

  default:
    if (c < 32 || c > 127 || cmd.size() >= CMDLENGTH)
      return false;
    cmd += char(c);
    updateCmdWin();
    return false;
  }
}

void CursesUI::addedPlayer(PlayerId p) {
  PlayerIdMap::const_iterator iter = players.find(p);
  comp.registerWord(iter->second.name);
  if (p == me)
    targetIter = iter;
}

void CursesUI::removingPlayer(PlayerId p) {
  if (targetIter->first == p) {
    targetIter = players.find(me);
    updateTargetWin();
  }
  comp.unregisterWord(players.find(p)->second.name);
}

PlayerId CursesUI::getTarget() const {
  if (targetIter->first == me)
    return AllPlayers;
  return targetIter->first;
}

void CursesUI::handleResize(int lines, int cols) {
  resizeterm(lines, cols);
  wresize(mainWin, lines - 2, cols);
  updateMainWinFromBuffer(lines - 2);
  mvwin(targetWin, lines - 2, 0);
  wresize(targetWin, 1, cols);
  mvwin(cmdWin, lines - 1, 0);
  wresize(cmdWin, 1, cols);
  updateTargetWin();
  updateCmdWin();
  wrefresh(mainWin);
}

void CursesUI::updateMainWinFromBuffer(unsigned int numberOfMessages) {
  wclear(mainWin);
  int start = msgBuffer.size() - numberOfMessages - scrollOffset;
  start = (start < 0 ? 0 : start);
  unsigned int end = start + numberOfMessages;
  end = (end >= msgBuffer.size() ? msgBuffer.size() : end);
  for (unsigned int i = start ; i < end; ++i) {
    wattron(mainWin, COLOR_PAIR(msgBuffer[i].second));
    waddstr(mainWin, (msgBuffer[i].first + "\n").c_str());
    wattroff(mainWin, COLOR_PAIR(msgBuffer[i].second));
  }
  wrefresh(mainWin);
}

void CursesUI::updateTargetWin() {
  werase(targetWin);
  wmove(targetWin, 0, 0);
  wmove(targetWin, 1, 1);
  std::string tmp = "Send to ";
  tmp = tmp + (targetIter == players.end() || targetIter->first == me ?
	       "all" : targetIter->second.name) + ":";
  waddstr(targetWin, tmp.c_str());
  wrefresh(targetWin);
}

void CursesUI::updateCmdWin() {
  werase(cmdWin);
  wmove(cmdWin, 1, 1);
  waddstr(cmdWin, cmd.c_str());
  wmove(cmdWin, 1, 1 + cmd.size());
  wrefresh(cmdWin);
}

void CursesUI::toggleMenu() {
  if (menuState == 0) {
    menuState = 1;
    curs_set(0);
    const int menuWinSize = (LINES - 2) / 2;
    wresize(mainWin, LINES - 2 - menuWinSize, COLS);
    mvwin(mainWin, menuWinSize, 0);
    updateMainWinFromBuffer(LINES - 2 - menuWinSize);
    menuWin = newwin(menuWinSize, 0, 0, 0);
    menu.setWindow(menuWin);
    menu.showMenu();
  }
  else if (menuState == 1) {
    menuState = 2;
    curs_set(1);
  }
  else {
    menuState = 0;
    menu.setWindow(NULL);
    delwin(menuWin);
    wresize(mainWin, LINES - 2, COLS);
    mvwin(mainWin, 0, 0);
    updateMainWinFromBuffer(LINES - 2);
  }
  wrefresh(targetWin);
  wrefresh(cmdWin);
}

void CursesUI::initMainMenu(CursesMenu& menu) {
  menu.setHeader("MAIN MENU");
  menu.clear();
  menu.addItem(new SubmenuCMItem("Show players",
				  &CursesUI::initPlayerMenu));
  //menu.addItem(new SubmenuCMItem("Edit banlist",
  //				  &CursesUI::initBanMenu));
  menu.addItem(new SubmenuCMItem("Edit server variables",
				  &CursesUI::initServerVarMenu));
  //menu.addItem(new SubmenuCMItem("Edit message filter",
  //				  &CursesUI::initFilterMenu));
}

void CursesUI::initPlayerMenu(CursesMenu& menu) {
  menu.setHeader("PLAYERLIST");
  menu.clear();
  PlayerIdMap::const_iterator it;
  for (it = menu.players.begin(); it != menu.players.end(); ++it)
    menu.addItem(new PlayerCMItem(menu.players, it->first));
  menu.addItem(new CommandCMItem("Reload playerlist", "/playerlist", true));
  menu.addItem(new SubmenuCMItem("Back to main menu",
				  &CursesUI::initMainMenu));
}

void CursesUI::initBanMenu(CursesMenu& menu) {
  menu.setHeader("BANLIST");
  menu.clear();
  menu.addItem(new SubmenuCMItem("Not implemented - go back",
				  &CursesUI::initMainMenu));
}

void CursesUI::initServerVarMenu(CursesMenu& menu) {
  menu.setHeader("SERVER VARIABLE EDITOR");
  menu.clear();
  BZDB.iterate(&CursesUI::addBZDBCMItem, &menu);
  menu.addItem(new SubmenuCMItem("Back to main menu",
				 &CursesUI::initMainMenu));
}

void CursesUI::addBZDBCMItem(const std::string& name, void* menu) {
  ((CursesMenu*)menu)->addItem(new BZDBCMItem(name));
}

void CursesUI::initFilterMenu(CursesMenu& menu) {
  menu.setHeader("MESSAGE FILTER EDITOR");
  menu.clear();
  menu.addItem(new SubmenuCMItem("Not implemented - go back",
				  &CursesUI::initMainMenu));
}

BZAdminUI* CursesUI::creator(BZAdminClient& client) {
  return new CursesUI(client);
}

// Local Variables: ***
// mode:C++ ***
// tab-width: 8 ***
// c-basic-offset: 2 ***
// indent-tabs-mode: t ***
// End: ***
// ex: shiftwidth=2 tabstop=8
<commit_msg>put " " around callsigns with the f5 kick thing.<commit_after>/* bzflag
 * Copyright (c) 1993 - 2004 Tim Riker
 *
 * This package is free software;  you can redistribute it and/or
 * modify it under the terms of the license found in the file
 * named COPYING that should have accompanied this file.
 *
 * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 */

#ifdef _MSC_VER
#pragma warning( 4: 4786)
#endif

#include "CursesUI.h"

// add this UI to the map
UIAdder CursesUI::uiAdder("curses", &CursesUI::creator);

CursesUI::CursesUI(BZAdminClient& c) :
  BZAdminUI(c),
  menuState(0), menu(c.getPlayers()), client(c), players(c.getPlayers()),
  me(c.getMyId()), maxHistory(20), currentHistory(0),
  maxBufferSize(300), scrollOffset(0) {

  // initialize ncurses
  initscr();
  start_color();
  use_default_colors();
  init_pair(Default, COLOR_FGDEFAULT, COLOR_BGDEFAULT);
  init_pair(White, COLOR_WHITE, COLOR_BGDEFAULT);
  init_pair(Red, COLOR_RED, COLOR_BGDEFAULT);
  init_pair(Green, COLOR_GREEN, COLOR_BGDEFAULT);
  init_pair(Blue, COLOR_BLUE, COLOR_BGDEFAULT);
  init_pair(Purple, COLOR_MAGENTA, COLOR_BGDEFAULT);
  init_pair(Yellow, COLOR_YELLOW, COLOR_BGDEFAULT);
  init_pair(Cyan, COLOR_CYAN, COLOR_BGDEFAULT);
  nonl();
  cbreak();
  noecho();

  // create main output window
  mainWin = newwin(LINES - 5, 0, 0, 0);
  wsetscrreg(mainWin, 0, LINES - 2);
  scrollok(mainWin, TRUE);
  wrefresh(mainWin);

  // create target window
  targetWin = newwin(1, 0, LINES - 2, 0);
  wattron(targetWin, A_UNDERLINE);
  targetIter = players.begin();
  updateTargetWin();

  // create command window
  cmdWin = newwin(0, 0, LINES - 1, 0);
  keypad(cmdWin, TRUE);
  nodelay(cmdWin, TRUE);
  updateCmdWin();

  // initialize the menu
  menu.setUpdateCallback(initMainMenu);

  // register commands for tab completion
  comp.registerWord("/ban ");
  comp.registerWord("/banlist");
  comp.registerWord("/countdown");
  comp.registerWord("/deregister");
  comp.registerWord("/flag ");
  comp.registerWord("reset");
  comp.registerWord("up");
  comp.registerWord("show");
  comp.registerWord("/flaghistory");
  comp.registerWord("/gameover");
  comp.registerWord("/ghost ");
  comp.registerWord("/groupperms");
  comp.registerWord("/help");
  comp.registerWord("/identify ");
  comp.registerWord("/idlestats");
  comp.registerWord("/kick ");
  comp.registerWord("/lagstats");
  comp.registerWord("/lagwarn ");
  comp.registerWord("/password ");
  comp.registerWord("/playerlist");
  comp.registerWord("/poll ");
  comp.registerWord("ban");
  comp.registerWord("kick");
  comp.registerWord("/quit");
  comp.registerWord("/register ");
  comp.registerWord("/reload");
  comp.registerWord("/removegroup ");
  comp.registerWord("/report ");
  comp.registerWord("/reset");
  comp.registerWord("/set");
  comp.registerWord("/setgroup ");
  comp.registerWord("/setpass ");
  comp.registerWord("/shutdownserver");
  comp.registerWord("/superkill");
  comp.registerWord("/unban ");
  comp.registerWord("/veto");
  comp.registerWord("/vote");
}

CursesUI::~CursesUI() {
  endwin();
}

void CursesUI::outputMessage(const std::string& msg, ColorCode color) {
  // add message to the message buffer, remove the oldest message if it's full
  if (msgBuffer.size() == maxBufferSize)
    msgBuffer.erase(msgBuffer.begin());
  std::pair<std::string, ColorCode> p(msg, color);
  msgBuffer.push_back(p);

  // if we have scrolled away from the bottom, don't show the new message
  if (scrollOffset == 0) {
    wattron(mainWin, COLOR_PAIR(color));
    waddstr(mainWin, (msg + "\n").c_str());
    wattroff(mainWin, COLOR_PAIR(color));
    wrefresh(mainWin);
  }
}

void CursesUI::handleNewPacket(uint16_t code) {
  BZAdminUI::handleNewPacket(code);
}

bool CursesUI::checkCommand(std::string& str) {
  wrefresh(cmdWin);
  str = "";
  int i;

  // get a character and do checks that are always needed
  int c = wgetch(cmdWin);
  switch (c) {
   case KEY_RESIZE:
     handleResize(LINES, COLS);
     return false;
  case KEY_F(2):
    toggleMenu();
    return false;
  case ERR:
    return false;
  }

  // if the menu is active, use the keystrokes for that
  if (menuState == 1)
    return menu.handleKey(c, str);

  // if not, go ahead and parse commands
  switch (c) {

    // clear command (21 is Ctrl-U)
  case 21:
    cmd = "";
    updateCmdWin();
    currentHistory = history.size();

    // delete last character
  case KEY_BACKSPACE:
  case KEY_DC:
  case 127:
    cmd = cmd.substr(0, cmd.size() - 1);
    updateCmdWin();
    return false;

    // redraw command (12 is ctrl-l)
  case 12:
    wclear(cmdWin);
    wclear(targetWin);
    updateCmdWin();
    updateTargetWin();
    return false;

    // send command
  case '\n': // works with PDCurses
  case 13:   // works with ncurses
    if (history.size() == maxHistory)
      history.erase(history.begin());
    history.push_back(cmd);
    str = cmd;
    cmd = "";
    currentHistory = history.size();
    updateCmdWin();
    return true;

    // scroll main window
  case KEY_NPAGE:
    scrollOffset = (scrollOffset < unsigned(LINES - 2) / 2 ?
		    0 : scrollOffset - (LINES - 2) / 2);
    updateMainWinFromBuffer(LINES - 2);
    return false;
  case KEY_PPAGE:
    if (msgBuffer.size() < unsigned(LINES - 2))
      scrollOffset = 0;
    else if (scrollOffset > msgBuffer.size() - (LINES - 2) - (LINES - 2) / 2)
      scrollOffset = msgBuffer.size() - (LINES - 2);
    else
      scrollOffset += (LINES - 2) / 2;
    updateMainWinFromBuffer(LINES - 2);
    return false;

    // change target
  case KEY_LEFT:
    if (targetIter == players.begin())
      for (unsigned int i = 0; i < players.size() - 1; i++)
	++targetIter;
    else
      targetIter--;
    updateTargetWin();
    return false;
  case KEY_RIGHT:
    targetIter++;
    if (targetIter == players.end())
      targetIter = players.begin();
    updateTargetWin();
    return false;

    // command history
  case KEY_UP:
    if (currentHistory == 0 || history.size() == 0)
      return false;
    --currentHistory;
    cmd = history[currentHistory];
    updateCmdWin();
    return false;
  case KEY_DOWN:
    if (currentHistory < history.size())
      ++currentHistory;
    if (currentHistory == history.size())
      cmd = "";
    else
      cmd = history[currentHistory];
    updateCmdWin();
    return false;

    // kick target
  case KEY_F(5):
    if (targetIter != players.end() && targetIter->first != me) {
      cmd = "/kick \"";
      cmd += targetIter->second.name;
      cmd += "\"";
      targetIter = players.find(me);
      updateCmdWin();
      updateTargetWin();
    }
    return false;

    // ban target (only works if we have done /playerlist earlier)
  case KEY_F(6):
    if (targetIter != players.end() && targetIter->first != me) {
      if (targetIter->second.ip != "") {
	cmd = "/ban ";
	cmd += targetIter->second.ip;
	targetIter = players.find(me);
	updateCmdWin();
	updateTargetWin();
      }
      else {
	std::string msg = "--- Can't ban ";
	msg += targetIter->second.name + ", you don't have the IP address";
	outputMessage(msg, Red);
	outputMessage("--- Trying to fetch IP addresses...", Red);
	str = "/playerlist";
	return true;
      }
    }
    return false;

    // tab - autocomplete
  case '\t':
    i = cmd.find_last_of(" \t");
    cmd = cmd.substr(0, i+1) + comp.complete(cmd.substr(i+1));
    updateCmdWin();
    return false;

  default:
    if (c < 32 || c > 127 || cmd.size() >= CMDLENGTH)
      return false;
    cmd += char(c);
    updateCmdWin();
    return false;
  }
}

void CursesUI::addedPlayer(PlayerId p) {
  PlayerIdMap::const_iterator iter = players.find(p);
  comp.registerWord(iter->second.name);
  if (p == me)
    targetIter = iter;
}

void CursesUI::removingPlayer(PlayerId p) {
  if (targetIter->first == p) {
    targetIter = players.find(me);
    updateTargetWin();
  }
  comp.unregisterWord(players.find(p)->second.name);
}

PlayerId CursesUI::getTarget() const {
  if (targetIter->first == me)
    return AllPlayers;
  return targetIter->first;
}

void CursesUI::handleResize(int lines, int cols) {
  resizeterm(lines, cols);
  wresize(mainWin, lines - 2, cols);
  updateMainWinFromBuffer(lines - 2);
  mvwin(targetWin, lines - 2, 0);
  wresize(targetWin, 1, cols);
  mvwin(cmdWin, lines - 1, 0);
  wresize(cmdWin, 1, cols);
  updateTargetWin();
  updateCmdWin();
  wrefresh(mainWin);
}

void CursesUI::updateMainWinFromBuffer(unsigned int numberOfMessages) {
  wclear(mainWin);
  int start = msgBuffer.size() - numberOfMessages - scrollOffset;
  start = (start < 0 ? 0 : start);
  unsigned int end = start + numberOfMessages;
  end = (end >= msgBuffer.size() ? msgBuffer.size() : end);
  for (unsigned int i = start ; i < end; ++i) {
    wattron(mainWin, COLOR_PAIR(msgBuffer[i].second));
    waddstr(mainWin, (msgBuffer[i].first + "\n").c_str());
    wattroff(mainWin, COLOR_PAIR(msgBuffer[i].second));
  }
  wrefresh(mainWin);
}

void CursesUI::updateTargetWin() {
  werase(targetWin);
  wmove(targetWin, 0, 0);
  wmove(targetWin, 1, 1);
  std::string tmp = "Send to ";
  tmp = tmp + (targetIter == players.end() || targetIter->first == me ?
	       "all" : targetIter->second.name) + ":";
  waddstr(targetWin, tmp.c_str());
  wrefresh(targetWin);
}

void CursesUI::updateCmdWin() {
  werase(cmdWin);
  wmove(cmdWin, 1, 1);
  waddstr(cmdWin, cmd.c_str());
  wmove(cmdWin, 1, 1 + cmd.size());
  wrefresh(cmdWin);
}

void CursesUI::toggleMenu() {
  if (menuState == 0) {
    menuState = 1;
    curs_set(0);
    const int menuWinSize = (LINES - 2) / 2;
    wresize(mainWin, LINES - 2 - menuWinSize, COLS);
    mvwin(mainWin, menuWinSize, 0);
    updateMainWinFromBuffer(LINES - 2 - menuWinSize);
    menuWin = newwin(menuWinSize, 0, 0, 0);
    menu.setWindow(menuWin);
    menu.showMenu();
  }
  else if (menuState == 1) {
    menuState = 2;
    curs_set(1);
  }
  else {
    menuState = 0;
    menu.setWindow(NULL);
    delwin(menuWin);
    wresize(mainWin, LINES - 2, COLS);
    mvwin(mainWin, 0, 0);
    updateMainWinFromBuffer(LINES - 2);
  }
  wrefresh(targetWin);
  wrefresh(cmdWin);
}

void CursesUI::initMainMenu(CursesMenu& menu) {
  menu.setHeader("MAIN MENU");
  menu.clear();
  menu.addItem(new SubmenuCMItem("Show players",
				  &CursesUI::initPlayerMenu));
  //menu.addItem(new SubmenuCMItem("Edit banlist",
  //				  &CursesUI::initBanMenu));
  menu.addItem(new SubmenuCMItem("Edit server variables",
				  &CursesUI::initServerVarMenu));
  //menu.addItem(new SubmenuCMItem("Edit message filter",
  //				  &CursesUI::initFilterMenu));
}

void CursesUI::initPlayerMenu(CursesMenu& menu) {
  menu.setHeader("PLAYERLIST");
  menu.clear();
  PlayerIdMap::const_iterator it;
  for (it = menu.players.begin(); it != menu.players.end(); ++it)
    menu.addItem(new PlayerCMItem(menu.players, it->first));
  menu.addItem(new CommandCMItem("Reload playerlist", "/playerlist", true));
  menu.addItem(new SubmenuCMItem("Back to main menu",
				  &CursesUI::initMainMenu));
}

void CursesUI::initBanMenu(CursesMenu& menu) {
  menu.setHeader("BANLIST");
  menu.clear();
  menu.addItem(new SubmenuCMItem("Not implemented - go back",
				  &CursesUI::initMainMenu));
}

void CursesUI::initServerVarMenu(CursesMenu& menu) {
  menu.setHeader("SERVER VARIABLE EDITOR");
  menu.clear();
  BZDB.iterate(&CursesUI::addBZDBCMItem, &menu);
  menu.addItem(new SubmenuCMItem("Back to main menu",
				 &CursesUI::initMainMenu));
}

void CursesUI::addBZDBCMItem(const std::string& name, void* menu) {
  ((CursesMenu*)menu)->addItem(new BZDBCMItem(name));
}

void CursesUI::initFilterMenu(CursesMenu& menu) {
  menu.setHeader("MESSAGE FILTER EDITOR");
  menu.clear();
  menu.addItem(new SubmenuCMItem("Not implemented - go back",
				  &CursesUI::initMainMenu));
}

BZAdminUI* CursesUI::creator(BZAdminClient& client) {
  return new CursesUI(client);
}

// Local Variables: ***
// mode:C++ ***
// tab-width: 8 ***
// c-basic-offset: 2 ***
// indent-tabs-mode: t ***
// End: ***
// ex: shiftwidth=2 tabstop=8
<|endoftext|>