зеркало из https://github.com/mozilla/gecko-dev.git
1294 строки
29 KiB
C++
1294 строки
29 KiB
C++
/* $Id: forms.cpp,v 1.2 1998/10/20 02:40:45 cls%seawood.org Exp $
|
|
*
|
|
* The contents of this file are subject to the Netscape Public License
|
|
* Version 1.0 (the "NPL"); you may not use this file except in
|
|
* compliance with the NPL. You may obtain a copy of the NPL at
|
|
* http://www.mozilla.org/NPL/
|
|
*
|
|
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
|
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
|
* for the specific language governing rights and limitations under the
|
|
* NPL.
|
|
*
|
|
* The Initial Developer of this code under the NPL is Netscape
|
|
* Communications Corporation. Portions created by Netscape are
|
|
* Copyright (C) 1998 Netscape Communications Corporation. Portions
|
|
* created by Warwick Allison, Kalle Dalheimer, Eirik Eng, Matthias
|
|
* Ettrich, Arnt Gulbrandsen, Haavard Nord and Paul Olav Tvete are
|
|
* Copyright (C) 1998 Warwick Allison, Kalle Dalheimer, Eirik Eng,
|
|
* Matthias Ettrich, Arnt Gulbrandsen, Haavard Nord and Paul Olav
|
|
* Tvete. All Rights Reserved.
|
|
*/
|
|
|
|
#include <qlined.h>
|
|
#include <qmlined.h>
|
|
#include <qradiobt.h>
|
|
#include <qpushbt.h>
|
|
#include <qcombo.h>
|
|
#include <qchkbox.h>
|
|
#include <qlistbox.h>
|
|
#include <qlabel.h>
|
|
#include <qlistview.h>
|
|
#include <qkeycode.h>
|
|
#include <qdir.h>
|
|
#if defined(XP_UNIX)
|
|
#include <xpform.h>
|
|
#endif
|
|
#include <libevent.h>
|
|
#include "dirview.h"
|
|
#include "QtBrowserContext.h"
|
|
|
|
|
|
#if defined(XP_WIN)
|
|
/*
|
|
Since xpform isn't part of the Windows distribution of Mozilla,
|
|
we include the necessary sources here.
|
|
|
|
Then we just don't use them, but leave them here for reference.
|
|
*/
|
|
#include "xpassert.h"
|
|
|
|
LO_FormElementData*
|
|
XP_GetFormElementData(LO_FormElementStruct *form)
|
|
{
|
|
return form->element_data;
|
|
}
|
|
|
|
LO_TextAttr*
|
|
XP_GetFormTextAttr(LO_FormElementStruct *form)
|
|
{
|
|
return form->text_attr;
|
|
}
|
|
|
|
uint16
|
|
XP_GetFormEleAttrmask(LO_FormElementStruct *form)
|
|
{
|
|
return form->ele_attrmask;
|
|
}
|
|
|
|
int32
|
|
XP_FormGetType(LO_FormElementData *form)
|
|
{
|
|
return form->type;
|
|
}
|
|
|
|
void
|
|
XP_FormSetFEData(LO_FormElementData *form,
|
|
void* fe_data)
|
|
{
|
|
form->ele_minimal.FE_Data = fe_data;
|
|
}
|
|
|
|
|
|
void*
|
|
XP_FormGetFEData(LO_FormElementData *form)
|
|
{
|
|
return form->ele_minimal.FE_Data;
|
|
}
|
|
|
|
/* Methods that work for Hidden, Submit, Reset, Button, and Readonly
|
|
form elements. */
|
|
PA_Block
|
|
XP_FormGetValue(LO_FormElementData *form)
|
|
{
|
|
XP_ASSERT(form->type == FORM_TYPE_HIDDEN
|
|
|| form->type == FORM_TYPE_SUBMIT
|
|
|| form->type == FORM_TYPE_RESET
|
|
|| form->type == FORM_TYPE_BUTTON
|
|
|| form->type == FORM_TYPE_READONLY);
|
|
|
|
return form->ele_minimal.value;
|
|
}
|
|
|
|
Bool
|
|
XP_FormGetDisabled(LO_FormElementData *form)
|
|
{
|
|
XP_ASSERT(form->type == FORM_TYPE_SELECT_ONE
|
|
|| form->type == FORM_TYPE_SELECT_MULT
|
|
|| form->type == FORM_TYPE_TEXT
|
|
|| form->type == FORM_TYPE_TEXTAREA
|
|
|| form->type == FORM_TYPE_RADIO
|
|
|| form->type == FORM_TYPE_CHECKBOX
|
|
|| form->type == FORM_TYPE_SUBMIT
|
|
|| form->type == FORM_TYPE_RESET
|
|
|| form->type == FORM_TYPE_BUTTON
|
|
|| form->type == FORM_TYPE_READONLY);
|
|
|
|
if (form->type == FORM_TYPE_SELECT_ONE
|
|
|| form->type == FORM_TYPE_SELECT_MULT
|
|
|| form->type == FORM_TYPE_TEXT
|
|
|| form->type == FORM_TYPE_TEXTAREA
|
|
|| form->type == FORM_TYPE_RADIO
|
|
|| form->type == FORM_TYPE_CHECKBOX
|
|
|| form->type == FORM_TYPE_SUBMIT
|
|
|| form->type == FORM_TYPE_RESET
|
|
|| form->type == FORM_TYPE_BUTTON
|
|
|| form->type == FORM_TYPE_READONLY)
|
|
return form->ele_minimal.disabled;
|
|
else
|
|
return FALSE;
|
|
}
|
|
|
|
/* Methods that work on text or text area form elements */
|
|
PA_Block
|
|
XP_FormGetDefaultText(LO_FormElementData *form)
|
|
{
|
|
XP_ASSERT(form->type == FORM_TYPE_TEXT
|
|
|| form->type == FORM_TYPE_TEXTAREA
|
|
|| form->type == FORM_TYPE_PASSWORD
|
|
|| form->type == FORM_TYPE_READONLY
|
|
|| form->type == FORM_TYPE_FILE);
|
|
|
|
switch(form->type)
|
|
{
|
|
case FORM_TYPE_TEXT:
|
|
case FORM_TYPE_PASSWORD:
|
|
case FORM_TYPE_FILE:
|
|
case FORM_TYPE_READONLY:
|
|
return form->ele_text.default_text;
|
|
case FORM_TYPE_TEXTAREA:
|
|
return form->ele_textarea.default_text;
|
|
default:
|
|
return NULL;
|
|
}
|
|
}
|
|
|
|
PA_Block
|
|
XP_FormGetCurrentText(LO_FormElementData *form)
|
|
{
|
|
XP_ASSERT(form->type == FORM_TYPE_TEXT
|
|
|| form->type == FORM_TYPE_TEXTAREA
|
|
|| form->type == FORM_TYPE_PASSWORD
|
|
|| form->type == FORM_TYPE_READONLY
|
|
|| form->type == FORM_TYPE_FILE);
|
|
|
|
switch(form->type)
|
|
{
|
|
case FORM_TYPE_TEXT:
|
|
case FORM_TYPE_PASSWORD:
|
|
case FORM_TYPE_FILE:
|
|
case FORM_TYPE_READONLY:
|
|
return form->ele_text.current_text;
|
|
case FORM_TYPE_TEXTAREA:
|
|
return form->ele_textarea.current_text;
|
|
default:
|
|
return NULL;
|
|
}
|
|
}
|
|
|
|
void
|
|
XP_FormSetCurrentText(LO_FormElementData *form,
|
|
PA_Block current_text)
|
|
{
|
|
XP_ASSERT(form->type == FORM_TYPE_TEXT
|
|
|| form->type == FORM_TYPE_TEXTAREA
|
|
|| form->type == FORM_TYPE_PASSWORD
|
|
|| form->type == FORM_TYPE_READONLY
|
|
|| form->type == FORM_TYPE_FILE);
|
|
|
|
switch(form->type)
|
|
{
|
|
case FORM_TYPE_TEXT:
|
|
case FORM_TYPE_PASSWORD:
|
|
case FORM_TYPE_FILE:
|
|
case FORM_TYPE_READONLY:
|
|
form->ele_text.current_text = current_text;
|
|
break;
|
|
case FORM_TYPE_TEXTAREA:
|
|
form->ele_textarea.current_text = current_text;
|
|
break;
|
|
}
|
|
}
|
|
|
|
Bool
|
|
XP_FormGetReadonly(LO_FormElementData *form)
|
|
{
|
|
XP_ASSERT(form->type == FORM_TYPE_TEXT
|
|
|| form->type == FORM_TYPE_TEXTAREA
|
|
|| form->type == FORM_TYPE_PASSWORD
|
|
|| form->type == FORM_TYPE_READONLY);
|
|
|
|
switch(form->type)
|
|
{
|
|
case FORM_TYPE_TEXT:
|
|
case FORM_TYPE_PASSWORD:
|
|
case FORM_TYPE_READONLY:
|
|
return form->ele_text.readonly;
|
|
case FORM_TYPE_TEXTAREA:
|
|
return form->ele_textarea.readonly;
|
|
default:
|
|
return FALSE;
|
|
}
|
|
}
|
|
|
|
/* text specific methods. */
|
|
int32
|
|
XP_FormTextGetSize(LO_FormElementData *form)
|
|
{
|
|
XP_ASSERT(form->type == FORM_TYPE_TEXT
|
|
|| form->type == FORM_TYPE_PASSWORD
|
|
|| form->type == FORM_TYPE_READONLY
|
|
|| form->type == FORM_TYPE_FILE);
|
|
|
|
return form->ele_text.size;
|
|
}
|
|
|
|
int32
|
|
XP_FormTextGetMaxSize(LO_FormElementData *form)
|
|
{
|
|
XP_ASSERT(form->type == FORM_TYPE_TEXT
|
|
|| form->type == FORM_TYPE_PASSWORD
|
|
|| form->type == FORM_TYPE_READONLY
|
|
|| form->type == FORM_TYPE_FILE);
|
|
|
|
return form->ele_text.max_size;
|
|
}
|
|
|
|
/* text area specific methods. */
|
|
void
|
|
XP_FormTextAreaGetDimensions(LO_FormElementData *form,
|
|
int32 *rows,
|
|
int32 *cols)
|
|
{
|
|
XP_ASSERT(form->type == FORM_TYPE_TEXTAREA);
|
|
|
|
if (rows)
|
|
*rows = form->ele_textarea.rows;
|
|
if (cols)
|
|
*cols = form->ele_textarea.cols;
|
|
}
|
|
|
|
uint8
|
|
XP_FormTextAreaGetAutowrap(LO_FormElementData *form)
|
|
{
|
|
XP_ASSERT(form->type == FORM_TYPE_TEXTAREA);
|
|
|
|
return form->ele_textarea.auto_wrap;
|
|
}
|
|
|
|
/* radio/checkbox specific methods */
|
|
Bool
|
|
XP_FormGetDefaultToggled(LO_FormElementData *form)
|
|
{
|
|
XP_ASSERT(form->type == FORM_TYPE_RADIO
|
|
|| form->type == FORM_TYPE_CHECKBOX);
|
|
|
|
return form->ele_toggle.default_toggle;
|
|
}
|
|
|
|
Bool
|
|
XP_FormGetElementToggled(LO_FormElementData *form)
|
|
{
|
|
XP_ASSERT(form->type == FORM_TYPE_RADIO
|
|
|| form->type == FORM_TYPE_CHECKBOX);
|
|
|
|
return form->ele_toggle.toggled;
|
|
}
|
|
|
|
void
|
|
XP_FormSetElementToggled(LO_FormElementData *form,
|
|
Bool toggled)
|
|
{
|
|
XP_ASSERT(form->type == FORM_TYPE_RADIO
|
|
|| form->type == FORM_TYPE_CHECKBOX);
|
|
|
|
form->ele_toggle.toggled = toggled;
|
|
}
|
|
|
|
/* select specific methods */
|
|
int32
|
|
XP_FormSelectGetSize(LO_FormElementData *form)
|
|
{
|
|
XP_ASSERT(form->type == FORM_TYPE_SELECT_ONE
|
|
|| form->type == FORM_TYPE_SELECT_MULT);
|
|
|
|
return form->ele_select.size;
|
|
}
|
|
|
|
Bool
|
|
XP_FormSelectGetMultiple(LO_FormElementData *form)
|
|
{
|
|
XP_ASSERT(form->type == FORM_TYPE_SELECT_ONE
|
|
|| form->type == FORM_TYPE_SELECT_MULT);
|
|
|
|
return form->ele_select.multiple;
|
|
}
|
|
|
|
Bool
|
|
XP_FormSelectGetOptionsValid(LO_FormElementData *form) /* XXX ? */
|
|
{
|
|
XP_ASSERT(form->type == FORM_TYPE_SELECT_ONE
|
|
|| form->type == FORM_TYPE_SELECT_MULT);
|
|
|
|
return form->ele_select.options_valid;
|
|
}
|
|
|
|
int32
|
|
XP_FormSelectGetOptionsCount(LO_FormElementData *form)
|
|
{
|
|
XP_ASSERT(form->type == FORM_TYPE_SELECT_ONE
|
|
|| form->type == FORM_TYPE_SELECT_MULT);
|
|
|
|
return form->ele_select.option_cnt;
|
|
}
|
|
|
|
lo_FormElementOptionData*
|
|
XP_FormSelectGetOption(LO_FormElementData *form,
|
|
int option_index)
|
|
{
|
|
XP_ASSERT((form->type == FORM_TYPE_SELECT_ONE
|
|
|| form->type == FORM_TYPE_SELECT_MULT)
|
|
&& option_index >= 0
|
|
&& option_index < form->ele_select.option_cnt);
|
|
|
|
return &((lo_FormElementOptionData*)form->ele_select.options)[option_index];
|
|
}
|
|
|
|
/* option specific methods */
|
|
Bool
|
|
XP_FormOptionGetDefaultSelected(lo_FormElementOptionData *option_element)
|
|
{
|
|
return option_element->def_selected;
|
|
}
|
|
|
|
Bool
|
|
XP_FormOptionGetSelected(lo_FormElementOptionData *option_element)
|
|
{
|
|
return option_element->selected;
|
|
}
|
|
|
|
void
|
|
XP_FormOptionSetSelected(lo_FormElementOptionData *option_element,
|
|
Bool selected)
|
|
{
|
|
option_element->selected = selected;
|
|
}
|
|
|
|
/* object */
|
|
LO_JavaAppStruct*
|
|
XP_FormObjectGetJavaApp(LO_FormElementData *form)
|
|
{
|
|
XP_ASSERT(form->type == FORM_TYPE_OBJECT);
|
|
|
|
return form->ele_object.object;
|
|
}
|
|
|
|
void
|
|
XP_FormObjectSetJavaApp(LO_FormElementData *form,
|
|
LO_JavaAppStruct *java_app)
|
|
{
|
|
XP_ASSERT(form->type == FORM_TYPE_OBJECT);
|
|
|
|
form->ele_object.object = java_app;
|
|
}
|
|
|
|
/* keygen */
|
|
PA_Block
|
|
XP_FormKeygenGetChallenge(LO_FormElementData *form)
|
|
{
|
|
XP_ASSERT(form->type == FORM_TYPE_KEYGEN);
|
|
|
|
return form->ele_keygen.challenge;
|
|
}
|
|
|
|
PA_Block
|
|
XP_FormKeygenGetKeytype(LO_FormElementData *form)
|
|
{
|
|
XP_ASSERT(form->type == FORM_TYPE_KEYGEN);
|
|
|
|
return form->ele_keygen.key_type;
|
|
}
|
|
|
|
PA_Block
|
|
XP_FormKeygenGetPQG(LO_FormElementData *form)
|
|
{
|
|
XP_ASSERT(form->type == FORM_TYPE_KEYGEN);
|
|
|
|
return form->ele_keygen.pqg;
|
|
}
|
|
|
|
char*
|
|
XP_FormKeygenGetValueStr(LO_FormElementData *form)
|
|
{
|
|
XP_ASSERT(form->type == FORM_TYPE_KEYGEN);
|
|
|
|
return form->ele_keygen.value_str;
|
|
}
|
|
|
|
/* setter routines? */
|
|
#endif // XP_WIN
|
|
|
|
|
|
|
|
class QtFormElement : QObject {
|
|
LO_FormElementStruct *form;
|
|
QtContext* context;
|
|
protected:
|
|
LO_FormElementData* elementData() const { return form->element_data; }
|
|
|
|
public:
|
|
QtFormElement( LO_FormElementStruct *form_struct, QtContext* cx ) :
|
|
form(form_struct),
|
|
context(cx)
|
|
{
|
|
}
|
|
void set(LO_FormElementStruct *form_struct, QtContext* cx)
|
|
{
|
|
form = form_struct;
|
|
context = cx;
|
|
}
|
|
|
|
void getSize()
|
|
{
|
|
int bw = borderWidth();
|
|
int w = width();
|
|
int h = height();
|
|
form->width = w + bw*2;
|
|
form->height = h + bw*2;
|
|
form->baseline = baseLine() + bw;
|
|
widget()->resize(w,h);
|
|
}
|
|
|
|
virtual int borderWidth() const
|
|
{ return 5; }
|
|
virtual int width() const
|
|
{ return widget()->sizeHint().width(); }
|
|
virtual int height() const
|
|
{ return widget()->sizeHint().height(); }
|
|
int baseLine() const
|
|
{
|
|
QFontMetrics fm = widget()->fontMetrics();
|
|
return height() - fm.descent() - baseLineAdjust();
|
|
}
|
|
virtual int baseLineAdjust() const
|
|
{
|
|
return 6; // magic look-good value
|
|
}
|
|
|
|
virtual void freeStorage()
|
|
{
|
|
}
|
|
|
|
virtual void getValue()
|
|
{
|
|
}
|
|
|
|
virtual void reset()
|
|
{
|
|
}
|
|
|
|
virtual void setToggle( bool ) { }
|
|
|
|
virtual bool submitOnClick() const { return FALSE; }
|
|
virtual bool submitOnEnter() const { return FALSE; }
|
|
|
|
virtual QWidget* widget() const
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
// Stuff for submission
|
|
void isSubmit()
|
|
{
|
|
widget()->installEventFilter(this);
|
|
}
|
|
|
|
protected:
|
|
int type() const
|
|
{
|
|
return elementData()->type;
|
|
}
|
|
|
|
lo_FormElementObjectData* object() const
|
|
{ return (lo_FormElementObjectData*)elementData(); }
|
|
lo_FormElementKeygenData* keygen() const
|
|
{ return (lo_FormElementKeygenData*)elementData(); }
|
|
|
|
private:
|
|
bool eventFilter( QObject *, QEvent* );
|
|
};
|
|
|
|
|
|
class QtFormToggleElement : public QtFormElement {
|
|
protected:
|
|
lo_FormElementToggleData* toggle() const
|
|
{ return (lo_FormElementToggleData*)elementData(); }
|
|
public:
|
|
QtFormToggleElement(LO_FormElementStruct *form, QtContext* cx) :
|
|
QtFormElement(form, cx)
|
|
{
|
|
}
|
|
};
|
|
|
|
class QtFormRadioElement : public QtFormToggleElement {
|
|
QRadioButton *w;
|
|
public:
|
|
QtFormRadioElement(LO_FormElementStruct *form, QtContext* cx) :
|
|
QtFormToggleElement(form, cx)
|
|
{
|
|
w = new QRadioButton(cx->contentWidget());
|
|
}
|
|
|
|
virtual QWidget* widget() const
|
|
{
|
|
return w;
|
|
}
|
|
|
|
virtual void getValue()
|
|
{
|
|
toggle()->toggled = w->isChecked();
|
|
}
|
|
|
|
virtual void setToggle( bool y )
|
|
{
|
|
w->setChecked( y );
|
|
}
|
|
|
|
virtual int baseLineAdjust() const
|
|
{
|
|
return 3; // magic look-good value
|
|
}
|
|
};
|
|
|
|
class QtFormCheckBoxElement : public QtFormToggleElement {
|
|
QCheckBox *w;
|
|
public:
|
|
QtFormCheckBoxElement(LO_FormElementStruct *form, QtContext* cx) :
|
|
QtFormToggleElement(form, cx)
|
|
{
|
|
w = new QCheckBox(cx->contentWidget());
|
|
}
|
|
|
|
virtual QWidget* widget() const
|
|
{
|
|
return w;
|
|
}
|
|
|
|
virtual void getValue()
|
|
{
|
|
toggle()->toggled = w->isChecked();
|
|
}
|
|
|
|
virtual void setToggle( bool y )
|
|
{
|
|
w->setChecked( y );
|
|
}
|
|
|
|
virtual int baseLineAdjust() const
|
|
{
|
|
return 3; // magic look-good value
|
|
}
|
|
};
|
|
|
|
class QtFormTextlikeElement : public QtFormElement {
|
|
protected:
|
|
lo_FormElementTextData* text() const
|
|
{ return (lo_FormElementTextData*)elementData(); }
|
|
|
|
QtFormTextlikeElement(LO_FormElementStruct *form, QtContext* cx) :
|
|
QtFormElement(form, cx)
|
|
{
|
|
}
|
|
|
|
virtual const char* currentText()
|
|
{
|
|
return "";
|
|
}
|
|
|
|
virtual void getValue()
|
|
{
|
|
const char* t = currentText();
|
|
text()->current_text = PA_Block(qstrdup(t));
|
|
if (text()->max_size > 0 && (int)strlen(t) >= text()->max_size )
|
|
text()->current_text[text()->max_size] = 0;
|
|
}
|
|
};
|
|
|
|
class QtFormButtonElement : public QtFormElement {
|
|
QPushButton *w;
|
|
|
|
lo_FormElementMinimalData_struct* minimal() const
|
|
{ return (lo_FormElementMinimalData_struct*)elementData(); }
|
|
public:
|
|
QtFormButtonElement(LO_FormElementStruct *form, QtContext* cx) :
|
|
QtFormElement(form, cx)
|
|
{
|
|
w = new QPushButton(cx->contentWidget());
|
|
w->setText( (char*)minimal()->value );
|
|
}
|
|
|
|
virtual QWidget* widget() const
|
|
{
|
|
return w;
|
|
}
|
|
|
|
virtual bool submitOnClick() const { return TRUE; }
|
|
};
|
|
|
|
class QtFormSubmitElement : public QtFormButtonElement {
|
|
public:
|
|
QtFormSubmitElement(LO_FormElementStruct *form, QtContext* cx) :
|
|
QtFormButtonElement(form, cx)
|
|
{
|
|
isSubmit();
|
|
}
|
|
virtual bool submitOnClick() const { return TRUE; }
|
|
};
|
|
|
|
class QtFormResetElement : public QtFormButtonElement {
|
|
public:
|
|
QtFormResetElement(LO_FormElementStruct *form, QtContext* cx) :
|
|
QtFormButtonElement(form, cx)
|
|
{
|
|
}
|
|
};
|
|
|
|
class QtJotter : public QFrame {
|
|
QPixmap pm;
|
|
QPoint ppos;
|
|
public:
|
|
QtJotter( QWidget* parent ) :
|
|
QFrame(parent)
|
|
{
|
|
setFrameStyle( Panel | Sunken );
|
|
}
|
|
void resizeEvent(QResizeEvent*)
|
|
{
|
|
int fw = frameWidth();
|
|
QPixmap newpm(width()-fw*2, height()-fw*2);
|
|
if ( !pm.isNull() )
|
|
bitBlt(&newpm, 0, 0, &pm);
|
|
pm = newpm;
|
|
}
|
|
void paintEvent(QPaintEvent*)
|
|
{
|
|
int fw = frameWidth();
|
|
bitBlt( this, fw, fw, &pm );
|
|
}
|
|
void mousePressEvent(QMouseEvent* e)
|
|
{
|
|
ppos = e->pos();
|
|
}
|
|
void mouseMoveEvent(QMouseEvent* e)
|
|
{
|
|
QPoint off(frameWidth(),frameWidth());
|
|
QPainter p1(this);
|
|
p1.drawLine(ppos,e->pos());
|
|
QPainter p2(&pm);
|
|
p2.drawLine(ppos-off,e->pos()-off);
|
|
ppos = e->pos();
|
|
}
|
|
};
|
|
|
|
class QtFormJotElement : public QtFormElement {
|
|
QtJotter *w;
|
|
public:
|
|
QtFormJotElement(LO_FormElementStruct *form, QtContext* cx) :
|
|
QtFormElement(form, cx)
|
|
{
|
|
w = new QtJotter(cx->contentWidget());
|
|
}
|
|
|
|
virtual QWidget* widget() const
|
|
{
|
|
return w;
|
|
}
|
|
};
|
|
|
|
class QtFormSelectElement : public QtFormElement {
|
|
protected:
|
|
lo_FormElementSelectData* select() const
|
|
{ return (lo_FormElementSelectData*)elementData(); }
|
|
lo_FormElementOptionData& option(int i) const
|
|
{ return ((lo_FormElementOptionData*)(select()->options))[i]; }
|
|
|
|
QtFormSelectElement(LO_FormElementStruct *form, QtContext* cx) :
|
|
QtFormElement(form, cx)
|
|
{
|
|
}
|
|
};
|
|
|
|
class QtFormSelectOneElement : public QtFormSelectElement {
|
|
QComboBox *w;
|
|
public:
|
|
QtFormSelectOneElement(LO_FormElementStruct *form, QtContext* cx) :
|
|
QtFormSelectElement(form, cx)
|
|
{
|
|
w = new QComboBox(cx->contentWidget());
|
|
int nitems = select()->option_cnt;
|
|
int vlines = select()->size;
|
|
if ( vlines <= 0 ) vlines = nitems;
|
|
for (int i=0; i < nitems; i++)
|
|
w->insertItem((char*)option(i).text_value);
|
|
}
|
|
|
|
virtual QWidget* widget() const
|
|
{
|
|
return w;
|
|
}
|
|
|
|
virtual void getValue()
|
|
{
|
|
for (int i=0; i < select()->option_cnt; i++)
|
|
option(i).selected = (w->currentItem() == i);
|
|
}
|
|
|
|
virtual void reset()
|
|
{
|
|
for (int i=0; i < select()->option_cnt; i++)
|
|
if ( option(i).def_selected ) {
|
|
w->setCurrentItem(i);
|
|
break;
|
|
}
|
|
}
|
|
};
|
|
|
|
class QtFormSelectMultElement : public QtFormSelectElement {
|
|
QListBox *w;
|
|
public:
|
|
QtFormSelectMultElement(LO_FormElementStruct *form, QtContext* cx) :
|
|
QtFormSelectElement(form, cx)
|
|
{
|
|
w = new QListBox(cx->contentWidget());
|
|
w->setMultiSelection( select()->multiple );
|
|
int nitems = select()->option_cnt;
|
|
int vlines = select()->size;
|
|
if ( vlines <= 0 ) vlines = nitems;
|
|
for (int i=0; i < nitems; i++)
|
|
w->insertItem((char*)option(i).text_value);
|
|
w->setFixedVisibleLines( vlines );
|
|
}
|
|
|
|
virtual QWidget* widget() const
|
|
{
|
|
return w;
|
|
}
|
|
|
|
virtual void getValue()
|
|
{
|
|
for (int i=0; i < select()->option_cnt; i++)
|
|
option(i).selected = w->isSelected(i);
|
|
}
|
|
|
|
virtual void reset()
|
|
{
|
|
for (int i=0; i < select()->option_cnt; i++)
|
|
w->setSelected(i, option(i).def_selected);
|
|
}
|
|
};
|
|
|
|
class QtFormTextAreaElement : public QtFormElement {
|
|
QMultiLineEdit *w;
|
|
lo_FormElementTextareaData* textarea() const
|
|
{ return (lo_FormElementTextareaData*)elementData(); }
|
|
public:
|
|
QtFormTextAreaElement(LO_FormElementStruct *form, QtContext* cx) :
|
|
QtFormElement(form, cx)
|
|
{
|
|
w = new QMultiLineEdit(cx->contentWidget());
|
|
}
|
|
|
|
virtual QWidget* widget() const
|
|
{
|
|
return w;
|
|
}
|
|
|
|
virtual void getValue()
|
|
{
|
|
textarea()->current_text = PA_Block(qstrdup(w->text()));
|
|
}
|
|
|
|
virtual void freeStorage()
|
|
{
|
|
if ( textarea()->current_text != textarea()->default_text ) {
|
|
delete textarea()->current_text;
|
|
textarea()->current_text = 0;
|
|
}
|
|
}
|
|
|
|
virtual void reset()
|
|
{
|
|
freeStorage();
|
|
w->setText( (char*)textarea()->default_text );
|
|
textarea()->current_text = textarea()->default_text;
|
|
}
|
|
|
|
virtual int width() const
|
|
{
|
|
QFontMetrics fm = w->fontMetrics();
|
|
int c=textarea()->cols; if (!c) c=20;
|
|
return c * fm.width("X");
|
|
}
|
|
|
|
virtual int height() const
|
|
{
|
|
w->setFixedVisibleLines(textarea()->rows);
|
|
return w->height();
|
|
}
|
|
|
|
virtual int baseLineAdjust() const
|
|
{
|
|
return 5; // magic look-good value
|
|
}
|
|
};
|
|
|
|
class QtFormPasswordElement : public QtFormTextlikeElement {
|
|
protected:
|
|
QLineEdit *w;
|
|
public:
|
|
QtFormPasswordElement(LO_FormElementStruct *form, QtContext* cx) :
|
|
QtFormTextlikeElement(form, cx)
|
|
{
|
|
w = new QLineEdit(cx->contentWidget());
|
|
w->setEchoMode(QLineEdit::Password);
|
|
if ( text()->max_size > 0 )
|
|
w->setMaxLength(text()->max_size);
|
|
}
|
|
|
|
virtual QWidget* widget() const
|
|
{
|
|
return w;
|
|
}
|
|
|
|
virtual const char* currentText()
|
|
{
|
|
return w->text();
|
|
}
|
|
|
|
virtual void freeStorage()
|
|
{
|
|
if ( text()->current_text != text()->default_text ) {
|
|
delete text()->current_text;
|
|
text()->current_text = 0;
|
|
}
|
|
}
|
|
|
|
virtual int width() const
|
|
{
|
|
QFontMetrics fm = w->fontMetrics();
|
|
int c=text()->size; if (!c) c=20;
|
|
return c * fm.width("X")
|
|
+ (w->frame() ? 2 : 0)*2 + 3 // magic from qlineedit.cpp
|
|
- fm.minLeftBearing()
|
|
- fm.minRightBearing();
|
|
}
|
|
|
|
virtual void reset()
|
|
{
|
|
w->setText( (char*)text()->default_text );
|
|
}
|
|
|
|
|
|
virtual int baseLineAdjust() const
|
|
{
|
|
return 5; // magic look-good value
|
|
}
|
|
|
|
virtual bool submitOnEnter() const { return TRUE; }
|
|
};
|
|
|
|
class QtFormTextElement : public QtFormPasswordElement {
|
|
public:
|
|
QtFormTextElement(LO_FormElementStruct *form, QtContext* cx) :
|
|
QtFormPasswordElement(form, cx)
|
|
{
|
|
w->setEchoMode(QLineEdit::Normal);
|
|
}
|
|
};
|
|
|
|
class QtFormHiddenElement : public QtFormTextElement {
|
|
public:
|
|
QtFormHiddenElement(LO_FormElementStruct *form, QtContext* cx) :
|
|
QtFormTextElement(form, cx)
|
|
{
|
|
warning("Hidden should not be created by BE");
|
|
}
|
|
};
|
|
|
|
class QtFormIsIndexElement : public QtFormTextElement {
|
|
public:
|
|
QtFormIsIndexElement(LO_FormElementStruct *form, QtContext* cx) :
|
|
QtFormTextElement(form, cx)
|
|
{
|
|
warning("IsIndex should not be created by BE");
|
|
}
|
|
};
|
|
|
|
class QtFormImageElement : public QtFormElement {
|
|
QLabel *w;
|
|
public:
|
|
QtFormImageElement(LO_FormElementStruct *form, QtContext* cx) :
|
|
QtFormElement(form, cx)
|
|
{
|
|
warning("Image should not be created by BE");
|
|
}
|
|
|
|
virtual QWidget* widget() const
|
|
{
|
|
return w;
|
|
}
|
|
|
|
virtual bool submitOnClick() const { return TRUE; }
|
|
};
|
|
|
|
class QtFormFileElement : public QtFormTextlikeElement {
|
|
|
|
// This is really just showing-off. We could just use a boring
|
|
// lineedit + browse button like other browsers usually do.
|
|
|
|
QListView *w;
|
|
QString current;
|
|
public:
|
|
QtFormFileElement(LO_FormElementStruct *form, QtContext* cx) :
|
|
QtFormTextlikeElement(form, cx)
|
|
{
|
|
// Just to show off, we use the Directory example program.
|
|
w = new QListView(cx->contentWidget());
|
|
w->addColumn( "Name" );
|
|
w->addColumn( "Type" );
|
|
Directory * root = new Directory( w );
|
|
root->setOpen( TRUE );
|
|
}
|
|
|
|
virtual QWidget* widget() const
|
|
{
|
|
return w;
|
|
}
|
|
|
|
virtual const char* currentText()
|
|
{
|
|
// This is a bit ugly...
|
|
QListViewItem * c = w->currentItem();
|
|
current = "";
|
|
if (c) {
|
|
// We know it's parent is a Directory, we put it there.
|
|
Directory* d = (Directory*)c->parent();
|
|
if (d)
|
|
current = d->fullName() + c->text(0);
|
|
}
|
|
//debug("FILE: \"%s\"",(const char*)current);
|
|
|
|
return QDir::convertSeparators(current);
|
|
}
|
|
|
|
virtual int width() const { return 400; }
|
|
virtual int height() const { return 300; }
|
|
};
|
|
|
|
class QtFormKeyGenElement : public QtFormElement {
|
|
QLabel *w;
|
|
public:
|
|
QtFormKeyGenElement(LO_FormElementStruct *form, QtContext* cx) :
|
|
QtFormElement(form, cx)
|
|
{
|
|
warning("Keygen should not be created by BE");
|
|
}
|
|
|
|
virtual QWidget* widget() const
|
|
{
|
|
return w;
|
|
}
|
|
};
|
|
|
|
class QtFormReadOnlyElement : public QtFormTextElement {
|
|
public:
|
|
QtFormReadOnlyElement(LO_FormElementStruct *form, QtContext* cx) :
|
|
QtFormTextElement(form, cx)
|
|
{
|
|
debug("What is a READONLY?");
|
|
}
|
|
};
|
|
|
|
class QtFormObjectElement : public QtFormElement {
|
|
QLabel *w;
|
|
public:
|
|
QtFormObjectElement(LO_FormElementStruct *form, QtContext* cx) :
|
|
QtFormElement(form, cx)
|
|
{
|
|
warning("Object should not be created by BE");
|
|
}
|
|
|
|
virtual QWidget* widget() const
|
|
{
|
|
return w;
|
|
}
|
|
};
|
|
|
|
|
|
static
|
|
QtFormElement* element(LO_FormElementStruct *form)
|
|
{
|
|
LO_FormElementData *form_data = form->element_data;
|
|
if (!form_data) return 0;
|
|
return (QtFormElement*)form_data->ele_minimal.FE_Data;
|
|
}
|
|
|
|
|
|
/* From ./forms.c: */
|
|
void QtContext::getFormElementInfo(LO_FormElementStruct *form)
|
|
{
|
|
// printf( "QTFE_GetFormElementInfo %p \n", form );
|
|
|
|
LO_FormElementData *form_data = form->element_data;
|
|
if ( !form_data ) return;
|
|
|
|
QtFormElement *fel = (QtFormElement*)form_data->ele_minimal.FE_Data;
|
|
if ( !fel ) {
|
|
switch ( form_data->type ) {
|
|
case FORM_TYPE_NONE:
|
|
return;
|
|
break;
|
|
case FORM_TYPE_TEXT:
|
|
fel = new QtFormTextElement( form, this );
|
|
break;
|
|
case FORM_TYPE_RADIO:
|
|
fel = new QtFormRadioElement( form, this );
|
|
break;
|
|
case FORM_TYPE_CHECKBOX:
|
|
fel = new QtFormCheckBoxElement( form, this );
|
|
break;
|
|
case FORM_TYPE_HIDDEN:
|
|
fel = new QtFormHiddenElement( form, this );
|
|
break;
|
|
case FORM_TYPE_SUBMIT:
|
|
fel = new QtFormSubmitElement( form, this );
|
|
break;
|
|
case FORM_TYPE_RESET:
|
|
fel = new QtFormResetElement( form, this );
|
|
break;
|
|
case FORM_TYPE_PASSWORD:
|
|
fel = new QtFormPasswordElement( form, this );
|
|
break;
|
|
case FORM_TYPE_BUTTON:
|
|
fel = new QtFormButtonElement( form, this );
|
|
break;
|
|
case FORM_TYPE_JOT:
|
|
fel = new QtFormJotElement( form, this );
|
|
break;
|
|
case FORM_TYPE_SELECT_ONE:
|
|
fel = new QtFormSelectOneElement( form, this );
|
|
break;
|
|
case FORM_TYPE_SELECT_MULT:
|
|
fel = new QtFormSelectMultElement( form, this );
|
|
break;
|
|
case FORM_TYPE_TEXTAREA:
|
|
fel = new QtFormTextAreaElement( form, this );
|
|
break;
|
|
case FORM_TYPE_ISINDEX:
|
|
fel = new QtFormIsIndexElement( form, this );
|
|
break;
|
|
case FORM_TYPE_IMAGE:
|
|
fel = new QtFormImageElement( form, this );
|
|
break;
|
|
case FORM_TYPE_FILE:
|
|
fel = new QtFormFileElement( form, this );
|
|
break;
|
|
case FORM_TYPE_KEYGEN:
|
|
fel = new QtFormKeyGenElement( form, this );
|
|
break;
|
|
case FORM_TYPE_READONLY:
|
|
fel = new QtFormReadOnlyElement( form, this );
|
|
break;
|
|
case FORM_TYPE_OBJECT:
|
|
fel = new QtFormObjectElement( form, this );
|
|
break;
|
|
}
|
|
form_data->ele_minimal.FE_Data = fel;
|
|
} else {
|
|
fel->set(form, this);
|
|
}
|
|
|
|
LO_TextAttr *a = form->text_attr;
|
|
if (a) {
|
|
QWidget* w=fel->widget();
|
|
w->setFont(getFont(a));
|
|
QColor fg(a->fg.red, a->fg.green, a->fg.blue);
|
|
QColor bg(a->bg.red, a->bg.green, a->bg.blue);
|
|
|
|
// Qt doesn't currently work well with 100% white or black
|
|
// backgrounds, but they are common on the web, so we adjust.
|
|
//
|
|
QColor topsh = bg.light();
|
|
QColor botsh = bg.dark();
|
|
int h,s,v;
|
|
bg.hsv(&h,&s,&v);
|
|
if ( v > 200 ) {
|
|
topsh.setHsv(h,s,200);
|
|
} else if ( v < 90 ) {
|
|
topsh.setHsv(h,s,90);
|
|
botsh.setHsv(h,s,60);
|
|
}
|
|
|
|
QColorGroup g(fg,
|
|
bg,
|
|
topsh,
|
|
botsh,
|
|
bg,
|
|
fg,
|
|
contentWidget()->colorGroup().base());
|
|
|
|
w->setPalette(QPalette(g,g,g));
|
|
}
|
|
fel->reset();
|
|
fel->getSize();
|
|
}
|
|
|
|
/* From ./forms.c: */
|
|
void QtContext::getFormElementValue(LO_FormElementStruct *, bool, bool)
|
|
{
|
|
}
|
|
|
|
/* XXX - wtf does submit_p do? */
|
|
void QtBrowserContext::getFormElementValue(LO_FormElementStruct *form,
|
|
bool delete_p, bool submit_p)
|
|
{
|
|
element(form)->getValue();
|
|
if ( delete_p ) {
|
|
// How MUCH do we delete of it?
|
|
showSubWidget( element(form)->widget(), FALSE );
|
|
}
|
|
}
|
|
|
|
/* From ./forms.c: */
|
|
void QtContext::resetFormElement(LO_FormElementStruct *form)
|
|
{
|
|
element(form)->reset();
|
|
}
|
|
|
|
/* From ./forms.c: */
|
|
void QtContext::setFormElementToggle(LO_FormElementStruct *form,
|
|
bool state)
|
|
{
|
|
element(form)->setToggle(state);
|
|
}
|
|
|
|
/* From ./forms.c: */
|
|
void QtContext::formTextIsSubmit(LO_FormElementStruct *form)
|
|
{
|
|
element(form)->isSubmit();
|
|
}
|
|
|
|
/* From ./forms.c: */
|
|
void QtContext::displayFormElement(int iLocation,
|
|
LO_FormElementStruct *form)
|
|
{
|
|
debug( "QTFE_DisplayFormElement %d, %p", iLocation, form);
|
|
}
|
|
|
|
/* From ./forms.c: */
|
|
void QtBrowserContext::displayFormElement(int /*iLocation*/,
|
|
LO_FormElementStruct *form)
|
|
{
|
|
// The back-end calls this too early some times (eg. when laying
|
|
// out tables).
|
|
|
|
QtFormElement *e = element(form);
|
|
if ( e && form->ele_attrmask & LO_ELE_INVISIBLE ) {
|
|
QWidget * w = e->widget();
|
|
// We are already taking document[XY]Offset() into account.
|
|
// Mozilla puts all the logic for dealing with the window-system
|
|
// co-ordinate range limitations of the window system.
|
|
int x = form->x + form->x_offset + e->borderWidth() + getXOrigin();
|
|
int y = form->y + form->y_offset + e->borderWidth() + getYOrigin();
|
|
w->resize( form->width-e->borderWidth()*2,
|
|
form->height-e->borderWidth()*2 );
|
|
moveSubWidget( w, x, y );
|
|
}
|
|
}
|
|
|
|
/* From ./forms.c: */
|
|
void QtContext::freeFormElement(LO_FormElementData *form_data)
|
|
{
|
|
// take it out and delete it - easier than loads of destructors.
|
|
QtFormElement *e = (QtFormElement*)form_data->ele_minimal.FE_Data;
|
|
if ( e ) {
|
|
QWidget * w = e->widget();
|
|
delete e;
|
|
delete w;
|
|
}
|
|
form_data->ele_minimal.FE_Data = 0;
|
|
}
|
|
|
|
|
|
|
|
void
|
|
submitForm(MWContext *context, LO_Element *element,
|
|
int32 /*event*/, void *closure,
|
|
ETEventStatus status)
|
|
{
|
|
QtContext *cx = QtContext::qt(context);
|
|
if (status != EVENT_OK) return;
|
|
|
|
LO_FormSubmitData *data;
|
|
if ( element->type == LO_IMAGE && closure ) {
|
|
QPoint *p = (QPoint*)closure;
|
|
data = LO_SubmitImageForm (context, &element->lo_image, p->x(), p->y() );
|
|
} else {
|
|
data = LO_SubmitForm (context, (LO_FormElementStruct *) element);
|
|
}
|
|
if (!data) return;
|
|
|
|
URL_Struct *url = NET_CreateURLStruct ((char *) data->action, NET_DONT_RELOAD);
|
|
|
|
NET_AddLOSubmitDataToURLStruct(data, url);
|
|
|
|
// Add the referer to the URL.
|
|
History_entry *he = SHIST_GetCurrent (&context->hist);
|
|
if (url->referer)
|
|
free (url->referer);
|
|
url->referer = he->address ? XP_STRDUP (he->address) : 0;
|
|
|
|
cx->getURL(url);
|
|
LO_FreeSubmitData (data);
|
|
}
|
|
|
|
static
|
|
void
|
|
send_submit(MWContext *context, LO_Element *element,
|
|
int32 /*event*/, void *closure,
|
|
ETEventStatus /*status*/)
|
|
{
|
|
JSEvent *js_event = XP_NEW_ZAP(JSEvent);
|
|
js_event->type = EVENT_SUBMIT;
|
|
ET_SendEvent(context, element, js_event, submitForm, closure);
|
|
}
|
|
|
|
|
|
|
|
bool QtFormElement::eventFilter( QObject *o, QEvent *e )
|
|
{
|
|
// ### This code is a bit too eager!
|
|
ASSERT(o==widget());
|
|
JSEvent *js_event = XP_NEW_ZAP(JSEvent);
|
|
bool send = FALSE;
|
|
switch (e->type()) {
|
|
case Event_MouseButtonPress:
|
|
case Event_MouseButtonRelease:
|
|
{
|
|
QMouseEvent *me = (QMouseEvent*)e;
|
|
if (me->button() == LeftButton) js_event->which = 1;
|
|
else if (me->button() == MidButton) js_event->which = 2;
|
|
else if (me->button() == RightButton) js_event->which = 3;
|
|
send = submitOnClick();
|
|
} break;
|
|
case Event_MouseMove:
|
|
break;
|
|
case Event_KeyPress:
|
|
case Event_KeyRelease:
|
|
{
|
|
QKeyEvent* ke = (QKeyEvent*)e;
|
|
js_event->which = ke->ascii();
|
|
send = submitOnEnter() && ( ke->key() == Key_Return || ke->key() == Key_Enter );
|
|
} break;
|
|
default:
|
|
break;
|
|
}
|
|
if ( send ) {
|
|
// Mozilla says: "send me a click, dammit!"
|
|
js_event->type = EVENT_CLICK;
|
|
ET_SendEvent(context->mwContext(), (LO_Element *)form, js_event,
|
|
send_submit, 0);
|
|
}
|
|
return FALSE;
|
|
}
|