/***************************************************************************
* Copyright (C) 2004 by Gerhard W. Gruber *
* sparhawk@gmx.at *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program 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 General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/
/******************************************************************************
*
* PROJECT: FILOU
* $Source: /cvsroot/desktoptools/filou/src/Plugin.h,v $
* $Revision: 1.4 $
* $Date: 2004/09/09 16:20:35 $
* $Author: lightweave $
* $Name: $
*
* $Log: Plugin.h,v $
* Revision 1.4 2004/09/09 16:20:35 lightweave
* Functionality added to get the new list into the viewer frame
*
* Revision 1.3 2004/08/31 21:39:14 lightweave
* Added support for AssignPlugin dialog.
*
* Revision 1.2 2004/08/22 19:11:38 lightweave
* Added binary plugin
*
* Revision 1.1.1.1 2004/08/21 17:00:08 lightweave
* Initial release
*
*
*****************************************************************************/
/******************************************************************************
*
* This file contains the base class for a plugin and is not directly usable.
* This class defines the entire interface which must be exported. The functions
* are described where they appear and serve as the documentation. All plugins
* must be derived from this base class otherwise they can not be used in the
* framework.
* An instance of a plugin is created for a specific part of the file and each
* instance is only responsible for that particular part of the file. This means
* that one plugin can handle different parts of a file and will be instantiated
* each time a chunk is assigned to that plugin.
*
*****************************************************************************/
// Some GUIDS available for use (have to be removed if they are used):
// {91ED56A3-2A3B-4DD6-9B5D-96EC01D94736}
// {61745811-B3F8-484F-8976-FC5C96548115}
//
#ifndef PLUGIN_H
#define PLUGIN_H
#include <wx/file.h>
#include <wx/dynarray.h>
#ifdef __WXMSW__
#define FILE_LENGTH_TYPE __int64
#endif
int FILOU_MessageBox(wxWindow *parent, wxString const &Title, wxString const &Message);
/**
* SEventInfo is a structure that is filled by the plugin whenever it
* registers a new event handler, in order for the framework to disconnect
* it when required. If it is a range handler, both IDs have to be
* filled. If it is a single event, then m_LastId must contain wxID_ANY.
*/
typedef struct {
int m_FirstId;
int m_LastId;
wxEventType m_Type;
} SEventInfo;
WX_DEFINE_ARRAY(SEventInfo *, AEventInfo);
class CReturnCode;
WX_DECLARE_OBJARRAY(CReturnCode, AReturnCode);
class CPlugin {
public:
/**
* SRectangle is used to calculate the size the plugin requires to display
* it's data. m_Start/m_End is filled by the framework and specifies the
* range in the file, the plugin should display. The plugin must then
* calculate the width and height it will require.
*/
struct SRectangle {
FILE_LENGTH_TYPE m_Start;
FILE_LENGTH_TYPE m_End;
int m_X;
int m_Y;
int m_Width;
int m_Height;
int m_Left;
int m_Top;
};
typedef enum {
ERC_OK,
ERC_INVALID,
ERC_REFRESH,
ERC_LEAVE_EDITMODE,
ERC_DIRTY,
ERC_SCROLL_TO_POSITION,
ERC_SCROLL_HORIZ,
ERC_SCROLL_VERT,
ERC_PROCEED,
ERC_COUNT
} EReturnCode;
typedef enum {
ECV_LINE_UP, // or RIGHT
ECV_LINE_DOWN, // or LEFT
ECV_PAGE_UP, // or RIGHT
ECV_PAGE_DOWN, // or LEFT
ECV_COUNT
} ERC_Codevalue;
typedef enum {
KMT_SINGLE,
KMT_DOUBLE,
KMT_RANGE,
KMT_LIST, // Use the include list
KMT_END,
KMT_COUNT
} EKeyMapType;
typedef CPlugin::EReturnCode (CPlugin::*KeyHandler)(wxWindow *, wxFile &, CPlugin::SRectangle &, wxKeyEvent &event, AReturnCode &);
struct SKeyMap {
EKeyMapType m_KeyType;
int m_KeyCodeFirst;
int m_KeyCodeLast;
KeyHandler m_KeyHandler;
char *m_Include;
char *m_Exclude;
};
/**
* SPluginId will gather information about the plugin. When GetPluginId
* is called the function must fill out Id, Name and Description. All
* other fields should not be touched by the function as they will be
* filled by the framework.
*/
struct SPluginInfo {
wxString m_Id;
wxString m_Name;
wxString m_Description;
CPlugin *m_DefaultObject;
};
public:
CPlugin(void);
virtual ~CPlugin(void);
/**
* CreateInstance should return an instance of the derived object. The
* framework will never use 'new' to create a new object, instead it will
* always use this function, as it never knows what objects it is using
* at runtime.
*/
virtual CPlugin *CreateInstance(void) = 0;
/**
* Connect is used to initialize the object when it is instantiated.
* Usually this would be done in the constructor of course but this
* is the chance to do it again. :) The advantage of this function is
* that, if it fails, the framework will not use this class and know
* about it. This function is called immediatly after a new object is
* created. The default behaviour is to return true.
*/
virtual bool Connect(wxWindow *, wxFile &);
/**
* Disconnect will be called before the class is destroyed. The same
* can be done in the destructor and is only there for completness of
* the interface.
*/
virtual void Disconnect(wxWindow *, wxFile &);
/**
* GetPluginName must return the name of the plugin and a description.
* This is presented to the user when he wants to apply a viewer and
* must be human readable.
* The id should be a unique id (ideally a GUID) which identifies the
* plugin.
*/
virtual void GetPluginId(SPluginInfo *) = 0;
/**
* HasConfigDlg returns true if the plugin has a configuration
* dialog which can be used to configure options.
*/
virtual bool HasConfigDlg(void);
/**
* OnConfigDlg displays the configuration dialog for a given plugin
* instance. Return true if the view has to be refreshed.
*/
virtual bool OnConfigDlg(wxWindow *Parent);
/**
* HasEditor returns true if the plugin supports editing. In this case
* the plugin must provide functions which are called when editing
* is to be done. The default return value is false.
*/
virtual bool HasEditor(void);
/**
* UpdateToolbar allows the plugin to add buttons to the toolbar.
* The plugin must allways assume that other plugins can be called
* before it, therefore the BaseId is given to tell the
* plugin what ids it can use for the controls it will add. The plugin
* may not remove controls from the toolbar as it can not make
* any assumptions what's already there.
* The toolbar contains buttons which are always there (like
* configuration options) because they are created by the framework.
* Thus it is not neccessary to create such buttons itself.
* For each button the plugin must also specify the event handeler
* information. The plugin can register as many event handlers as it likes
* and combine it into range or single events, though a range is prefered.
* The function may not connect the event handler directly as this is done
* by the framework after it has collected all the event handler informations.
*
* The function must return the number of buttons/controls it has added.
* The control id for a given control is BaseId+Index while Index is
* the number of the control.
*/
virtual int UpdateToolbar(wxWindow *Parent, wxToolBar *Toolbar, int BaseId, AEventInfo &);
/**
* OnToolbarItem is called when the user pressed a button in the toolbar.
* The Id is the actual Id of the button. Each plugion stores it's BaseId
* so it can easily determine the number of the button by subtracting
* the base from the passed in id.
* Return true if the display has to be updated, otherwise false.
*/
virtual void OnToolbarItem(wxWindow *Parent, int Id, AReturnCode &);
/**
* CalcSize calculates the rectangle in pixels the plugin needs to display it's
* data. The input data specifies the range.
*/
virtual void CalcSize(wxFile &, wxClientDC &, CPlugin::SRectangle &) = 0;
/**
* ShowData prints the content of the file to the window. The Offset
* members m_Start/m_End defines the range in the file which the plugin
* shold display. Note that his can differ from the range the plugin received
* by CalcSize because a smaller part of the display may be visible than
* the plugin is responsible for.
*
* i.E. If the plugin is responsible for the entire file (like the hexdump as
* default) the CalcSize must calculate how much pixelspace it would take to
* display that data, but the window may be much smaller to show the entire
* file.
*/
virtual FILE_LENGTH_TYPE RenderView(wxFile &, wxClientDC &, CPlugin::SRectangle &Offset) = 0;
/**
* GetScrollStepping returns the number of bytes in vertical/horizontal
* direction which are required to scroll one line/character (or whatever
* units makes sense for a particular viewer).
*/
virtual void GetScrollStepping(long &width, long &heigth) = 0;
/**
* SnapToUnit calculates the x, y coordinates and width/height when the
* user starts to make a selection, so that the rectangle is properly
* adjusted to the unit size of the plugin.
* The framework itself will draw the rectangle exactly where the
* user puts the mouse, but this is usually not the location what the user
* really intended to select.
* m_Left/m_Top are the current scroll values so the plugin
* knows where the rectangle really is.
*
* If the plugin changed the values, it must return true to tell the
* framework to redraw the rectangle with the new coordinates.
*/
virtual bool SnapToUnit(SRectangle &r);
/**
* GetBoundary returns the start/end offset in the file for
* a given rectangle. For a description of the parameters look at
* SnapToUnit().
*
* If false is returned the values should not be used.
*/
virtual bool GetBoundary(wxFile &f, SRectangle &r, FILE_LENGTH_TYPE &Start, FILE_LENGTH_TYPE &End);
/**
* CopySelectionAsText should create a string which represents the
* selected rectangle.
* If the plugin doesn't support copying as strings or an error
* encounters then return false, otherwise true.
*
* r contains the description of the rectangle. f represents the
* file and s is the string which should be returned.
*/
virtual bool CopyRectangleAsText(CPlugin::SRectangle &r, wxFile &f, wxString &s);
/**
* GetCaretSize returns the size of the caret required for that plugin.
* if the returncode is false the values are ignored. This function is only
* required if HasEditor returns true, otherwise it should never be called
* but return false if it is called.
*/
virtual bool GetCaretSize(int &w, int &h);
/**
* EnterEditMode is called when the users signaled that he wants to edit
* values. If the plugin supports it, it should now prepare itself for
* editing. If the function returns true the screen is refreshed.
* Rectangle contains the coordinates where the event took place. Of course
* Width and Height will not be set as there is no such thing at this point.
*
* Note that EnterEditMode and LeaveEditMode don't need to match. The plugin
* can receive an Enter without a Leave and vice versa.
*/
virtual bool EnterEditMode(wxWindow *, wxFile &, CPlugin::SRectangle &Rectangle, AReturnCode &);
/**
* LeaveEditMode is called when the users wants to end editing. The
* plugin should flush outstanding data in case the user modified some
* values. If true is returned the display is refreshed.
*
* If REFRESH is returned, it is assumed that the EditMode has been
* exited, otherwise it continues.
*/
virtual bool LeaveEditMode(wxWindow *, wxFile &, AReturnCode &);
/**
* OnChar processes keyboard events. If the display has to be refreshed
* after the plugin processed it, the function must return true, otherwise
* false.
* OnChar will be called on all keyboardevents the framework receives unless
* the framework processes some of them itself. The framework does not
* distuinguish between editmode and non-editmode. The plugin must determine
* this itself by setting it's state on Enter/LeaveEditMode.
*
* The plugin may return ERC_DIRTY here to indicate that the data has been modified.
* In this case the title of the window is updated to remind the user of the fact.
* This returncode should be only sent once,
*/
virtual CPlugin::EReturnCode OnChar(wxWindow *, wxFile &, CPlugin::SRectangle &r, wxKeyEvent &event, AReturnCode &);
/**
* ProcessKeyTable will scan a KeyMap table and call the appropriate handler.
* The keytable must be terminated by a KeyType entry which is set to KMT_END.
* If no appropriate keyhandler could be found the value ERC_INVALID is returned,
* otherwise the returnvalue of the keyhandler is returned.
*/
virtual CPlugin::EReturnCode ProcessKeyTable(SKeyMap *, wxWindow *, wxFile &, CPlugin::SRectangle &r, wxKeyEvent &event, AReturnCode &);
protected:
bool m_HasConfigDlg;
bool m_HasEditor;
int m_BaseId;
};
class CReturnCode {
public:
CReturnCode &operator=(const CReturnCode &s) { m_ReturnCode = s.m_ReturnCode; m_ErrorText = s.m_ErrorText; return *this; }
public:
CPlugin::EReturnCode m_ReturnCode;
wxString m_ErrorText;
long m_Code1;
long m_Code2;
};
WX_DEFINE_ARRAY(CPlugin::SPluginInfo *, APluginInfo);
WX_DEFINE_ARRAY(CPlugin *, APlugin);
#endif