diff -uNr officecfg/registry/data/org/openoffice/Office/UI/CalcCommands.xcu officecfg/registry/data/org/openoffice/Office/UI/CalcCommands.xcu
--- officecfg/registry/data/org/openoffice/Office/UI/CalcCommands.xcu	2007-09-18 14:20:48.000000000 +0800
+++ officecfg/registry/data/org/openoffice/Office/UI/CalcCommands.xcu	2007-09-18 14:20:23.000000000 +0800
@@ -1169,6 +1169,12 @@
 					<value xml:lang="en-US">~Remove Filter</value>
 				</prop>
 			</node>
+                        <node oor:name=".uno:DataForm" oor:op="replace">
+                                <prop oor:name="Label" oor:type="xs:string">
+                                        <value xml:lang="de">D~atenForm...</value>
+                                        <value xml:lang="en-US">D~ataForm...</value>
+                                </prop>
+                        </node>
 			<node oor:name=".uno:DataSubTotals" oor:op="replace">
 				<prop oor:name="Label" oor:type="xs:string">
 					<value xml:lang="en-US">Sub~totals...</value>
diff -uNr sc/inc/document.hxx sc/inc/document.hxx
--- sc/inc/document.hxx	2007-09-18 13:29:33.000000000 +0800
+++ sc/inc/document.hxx	2007-09-18 13:31:06.000000000 +0800
@@ -733,7 +733,10 @@
 	void			PutCell(SCCOL nCol, SCROW nRow, SCTAB nTab, ScBaseCell* pCell,
 							ULONG nFormatIndex, BOOL bForceTab = FALSE);
 					//	return TRUE = Zahlformat gesetzt
-	BOOL			SetString( SCCOL nCol, SCROW nRow, SCTAB nTab, const String& rString );
+	//BOOL			SetString( SCCOL nCol, SCROW nRow, SCTAB nTab, const String& rString );
+	//for dataform
+	SC_DLLPUBLIC  BOOL			SetString( SCCOL nCol, SCROW nRow, SCTAB nTab, const String& rString );
+	//end
 	void			SetValue( SCCOL nCol, SCROW nRow, SCTAB nTab, const double& rVal );
 	void			SetNote( SCCOL nCol, SCROW nRow, SCTAB nTab, const ScPostIt& rNote );
 	void 			SetError( SCCOL nCol, SCROW nRow, SCTAB nTab, const USHORT nError);
@@ -894,8 +897,10 @@
 							   SCCOL nEndCol,   SCTAB nEndTab,
 							   SCROW nStartRow, SCSIZE nSize,
 							   ScDocument* pRefUndoDoc = NULL, BOOL* pUndoOutline = NULL );
-	void			DeleteRow( const ScRange& rRange,
+	//for dataform
+	SC_DLLPUBLIC    void			DeleteRow( const ScRange& rRange,
 							   ScDocument* pRefUndoDoc = NULL, BOOL* pUndoOutline = NULL );
+							   
 	BOOL			InsertCol( SCROW nStartRow, SCTAB nStartTab,
 							   SCROW nEndRow,   SCTAB nEndTab,
 							   SCCOL nStartCol, SCSIZE nSize, ScDocument* pRefUndoDoc = NULL );
@@ -1186,7 +1191,9 @@
 											USHORT nNewHeight );
 	void			SetManualHeight( SCROW nStartRow, SCROW nEndRow, SCTAB nTab, BOOL bManual );
 
-	USHORT			GetColWidth( SCCOL nCol, SCTAB nTab ) const;
+	//for dataform
+	SC_DLLPUBLIC    USHORT			GetColWidth( SCCOL nCol, SCTAB nTab ) const;
+	
 	USHORT			GetRowHeight( SCROW nRow, SCTAB nTab ) const;
 	ULONG			GetRowHeight( SCROW nStartRow, SCROW nEndRow, SCTAB nTab ) const;
 	ULONG			GetScaledRowHeight( SCROW nStartRow, SCROW nEndRow, SCTAB nTab, double fScale ) const;
diff -uNr sc/inc/scabstdlg.hxx sc/inc/scabstdlg.hxx
--- sc/inc/scabstdlg.hxx	2007-09-18 13:29:33.000000000 +0800
+++ sc/inc/scabstdlg.hxx	2007-09-18 13:31:07.000000000 +0800
@@ -52,6 +52,8 @@
 #include "global.hxx"
 #include "pivot.hxx"
 
+#include <tabvwsh.hxx>
+
 class ScAsciiOptions;
 class ScAutoFormat;
 class ScAutoFormatData;
@@ -120,6 +122,12 @@
 	virtual DelCellCmd GetDelCellCmd() const = 0;
 };
 
+//for dataform
+class AbstractScDataFormDlg : public VclAbstractDialog  //add for ScDeleteCellDlg
+{
+
+};
+
 class AbstractScDeleteContentsDlg: public VclAbstractDialog  //add for ScDeleteContentsDlg
 {
 public:
@@ -333,6 +341,9 @@
 
 	virtual AbstractScDeleteCellDlg * CreateScDeleteCellDlg( Window* pParent, int nId, BOOL bDisallowCellMove = FALSE ) = 0 ; //add for ScDeleteCellDlg
 
+	//for dataform
+	virtual AbstractScDataFormDlg * CreateScDataFormDlg( Window* pParent, int nId, ScTabViewShell*      pTabViewShell ) = 0 ; //add for ScDataFormDlg
+
 	virtual AbstractScDeleteContentsDlg * CreateScDeleteContentsDlg(Window* pParent,int nId, //add for ScDeleteContentsDlg
 																 USHORT  nCheckDefaults = 0 ) = 0;
 	virtual AbstractScFillSeriesDlg * CreateScFillSeriesDlg( Window*		pParent, //add for ScFillSeriesDlg
diff -uNr sc/inc/sc.hrc sc/inc/sc.hrc
--- sc/inc/sc.hrc	2007-09-18 13:29:33.000000000 +0800
+++ sc/inc/sc.hrc	2007-09-18 13:31:07.000000000 +0800
@@ -635,6 +635,7 @@
 #define SC_HINT_DOC_SAVED		(SC_MESSAGE_START + 35)
 #define SC_HINT_FORCESETTAB		(SC_MESSAGE_START + 36)
 #define SC_HINT_TABLECHANGED    (SC_MESSAGE_START + 37)
+#define SID_DATAFORM_NEW		(SC_MESSAGE_START + 38)  // Amelia Wang
 
 // Nachricht zum Oeffnen von Dialogen:
 #define SID_OPENDLG_CONSOLIDATE		(SC_MESSAGE_START + 50)
@@ -803,9 +804,10 @@
 
 #define SID_SORT_DESCENDING		(DATA_MENU_START + 23)
 #define SID_SORT_ASCENDING		(DATA_MENU_START + 24)
+#define SID_DATA_FORM		    (DATA_MENU_START + 25)
 //
 //
-#define DATA_MENU_END           (DATA_MENU_START + 25)
+#define DATA_MENU_END           (DATA_MENU_START + 26)
 
 #define TAB_POPUP_START			(DATA_MENU_END)
 #define RID_POPUP_TAB			(TAB_POPUP_START)
@@ -1600,6 +1602,9 @@
 #define RID_SCDLG_DPDATEGROUP           (SC_DIALOGS_START + 136)
 #define RID_SCDLG_DPSHOWDETAIL          (SC_DIALOGS_START + 137)
 
+#define RID_SCDLG_DATAFORM				(SC_DIALOGS_START + 138)
+
+
 #define SC_DIALOGS_END          (SC_DIALOGS_START + 150)
 
 #ifndef STD_MASKCOLOR
diff -uNr sc/sdi/cellsh.sdi sc/sdi/cellsh.sdi
--- sc/sdi/cellsh.sdi	2007-09-18 13:29:33.000000000 +0800
+++ sc/sdi/cellsh.sdi	2007-09-18 13:31:08.000000000 +0800
@@ -64,6 +64,7 @@
 	SID_SBA_BRW_INSERT		[ ExecMethod = ExecuteDB; StateMethod = GetDBState; ]
 	SID_SELECT_DB			[ ExecMethod = ExecuteDB; StateMethod = GetDBState; ]
 	SID_SORT				[ ExecMethod = ExecuteDB; StateMethod = GetDBState; ]
+	SID_DATA_FORM			[ ExecMethod = ExecuteDB; StateMethod = GetDBState; ]
 	FID_FILTER_OK			[ ExecMethod = ExecuteDB; StateMethod = GetDBState; ]
 	SID_AUTO_FILTER			[ ExecMethod = ExecuteDB; StateMethod = GetDBState; ]
 	SID_AUTOFILTER_HIDE		[ ExecMethod = ExecuteDB; StateMethod = GetDBState; ]
diff -uNr sc/sdi/scalc.sdi sc/sdi/scalc.sdi
--- sc/sdi/scalc.sdi	2007-09-18 13:29:33.000000000 +0800
+++ sc/sdi/scalc.sdi	2007-09-18 13:31:08.000000000 +0800
@@ -1606,6 +1606,31 @@
 ]
 
 //--------------------------------------------------------------------------
+SfxVoidItem DataForm SID_DATA_FORM
+()
+[
+	/* flags: */
+	AutoUpdate = FALSE,
+	Cachable = Cachable,
+	FastCall = FALSE,
+	HasCoreId = FALSE,
+	HasDialog = TRUE,
+	ReadOnlyDoc = TRUE,
+	Toggle = FALSE,
+	Container = FALSE,
+	RecordAbsolute = FALSE,
+	RecordPerSet;
+	Synchron;
+
+	/* config: */
+	AccelConfig = TRUE,
+	MenuConfig = TRUE,
+	StatusBarConfig = FALSE,
+	ToolBoxConfig = FALSE,
+	GroupId = GID_DATA;
+]
+
+//--------------------------------------------------------------------------
 SfxVoidItem DataSubTotals SID_SUBTOTALS
 ()
 [
diff -uNr sc/source/ui/attrdlg/scdlgfact.cxx sc/source/ui/attrdlg/scdlgfact.cxx
--- sc/source/ui/attrdlg/scdlgfact.cxx	2007-09-18 13:29:39.000000000 +0800
+++ sc/source/ui/attrdlg/scdlgfact.cxx	2007-09-18 13:31:18.000000000 +0800
@@ -81,6 +81,8 @@
 #include "tpstat.hxx" //add for ScDocStatPage
 #include "tpusrlst.hxx" //add for ScTpUserLists
 #include "tpview.hxx" //add for ScTpContentOptions
+//for dataform
+#include "datafdlg.hxx" //add for ScDataFormDlg
 
 // ause
 #include "editutil.hxx"
@@ -93,6 +95,8 @@
 IMPL_ABSTDLG_BASE(AbstractScDataPilotSourceTypeDlg_Impl); //add for ScDataPilotSourceTypeDlg
 IMPL_ABSTDLG_BASE(AbstractScDataPilotServiceDlg_Impl); //add for ScDataPilotServiceDlg
 IMPL_ABSTDLG_BASE(AbstractScDeleteCellDlg_Impl); //add for ScDeleteCellDlg
+//for dataform
+IMPL_ABSTDLG_BASE(AbstractScDataFormDlg_Impl); //add for ScDataFormDlg
 IMPL_ABSTDLG_BASE(AbstractScDeleteContentsDlg_Impl); //add for ScDeleteContentsDlg
 IMPL_ABSTDLG_BASE(AbstractScFillSeriesDlg_Impl); //add for ScFillSeriesDlg
 IMPL_ABSTDLG_BASE(AbstractScGroupDlg_Impl); //add for ScGroupDlg
@@ -761,6 +765,26 @@
 
 //add for ScDeleteCellDlg  end
 
+//add for ScDataFormDlg begin
+AbstractScDataFormDlg* ScAbstractDialogFactory_Impl::CreateScDataFormDlg( Window* pParent, int nId, ScTabViewShell*	pTabViewShell )
+{
+	ScDataFormDlg * pDlg=NULL;
+	switch ( nId )
+	{
+		case RID_SCDLG_DATAFORM :
+			pDlg = new ScDataFormDlg( pParent, pTabViewShell);
+			break;
+		default:
+			break;
+	}
+
+	if ( pDlg )
+		return new AbstractScDataFormDlg_Impl( pDlg );
+	return 0;
+}
+
+//add for ScDataFormDlg  end
+
 //add for ScDeleteContentsDlg begin
 AbstractScDeleteContentsDlg* ScAbstractDialogFactory_Impl::CreateScDeleteContentsDlg(Window* pParent,int nId, //add for ScDeleteContentsDlg
 																 USHORT  nCheckDefaults )
diff -uNr sc/source/ui/attrdlg/scdlgfact.hxx sc/source/ui/attrdlg/scdlgfact.hxx
--- sc/source/ui/attrdlg/scdlgfact.hxx	2007-09-18 13:29:39.000000000 +0800
+++ sc/source/ui/attrdlg/scdlgfact.hxx	2007-09-18 13:31:18.000000000 +0800
@@ -45,6 +45,7 @@
 class ScDataPilotSourceTypeDlg;
 class ScDataPilotServiceDlg;
 class ScDeleteCellDlg;
+class ScDataFormDlg;
 class ScDeleteContentsDlg;
 class ScFillSeriesDlg;
 class ScGroupDlg;
@@ -167,6 +168,12 @@
 	virtual DelCellCmd GetDelCellCmd() const;
 };
 
+//for dataform
+class AbstractScDataFormDlg_Impl : public AbstractScDataFormDlg  //add for ScDataFormDlg
+{
+	DECL_ABSTDLG_BASE(AbstractScDataFormDlg_Impl,ScDataFormDlg);
+};
+
 class AbstractScDeleteContentsDlg_Impl : public AbstractScDeleteContentsDlg  //add for ScDeleteContentsDlg
 {
 	DECL_ABSTDLG_BASE( AbstractScDeleteContentsDlg_Impl,ScDeleteContentsDlg)
@@ -395,6 +402,9 @@
 	virtual AbstractScDeleteCellDlg * CreateScDeleteCellDlg( Window* pParent, int nId,
 															BOOL bDisallowCellMove = FALSE ); //add for ScDeleteCellDlg
 
+	//for dataform
+	virtual AbstractScDataFormDlg * CreateScDataFormDlg( Window* pParent, int nId, ScTabViewShell*      pTabViewShell); //add for ScDeleteCellDlg
+
 	virtual AbstractScDeleteContentsDlg * CreateScDeleteContentsDlg(Window* pParent,int nId, //add for ScDeleteContentsDlg
 																 USHORT  nCheckDefaults = 0 );
 
diff -uNr sc/source/ui/inc/datafdlg.hrc sc/source/ui/inc/datafdlg.hrc
--- sc/source/ui/inc/datafdlg.hrc	1970-01-01 08:00:00.000000000 +0800
+++ sc/source/ui/inc/datafdlg.hrc	2007-09-18 13:31:09.000000000 +0800
@@ -0,0 +1,49 @@
+/*************************************************************************
+ *
+ *  OpenOffice.org - a multi-platform office productivity suite
+ *
+ *  $RCSfile: datafdlg.hrc,v $
+ *
+ *  $Revision: 1.00 $
+ *
+ *  last change: $Author: rt $ $Date: 2005/09/08 21:37:12 $
+ *
+ *  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
+ *
+ ************************************************************************/
+
+#include "sc.hrc"	// -> RID_SCDLG_DATAFORM
+
+//dataform
+#define BTN_DATAFORM_NEW          1001
+#define BTN_DATAFORM_DELETE       1002
+#define BTN_DATAFORM_RESTORE      1003
+#define BTN_DATAFORM_LAST         1004
+#define BTN_DATAFORM_NEXT         1005
+#define BTN_DATAFORM_CLOSE        1007
+#define WND_DATAFORM_SCROLLBAR    1008
+#define LAB_DATAFORM_RECORDNO     1009
+
+#define FT_DATAFORM_FIXEDTEXT1    2001
+#define ED_DATAFORM_EDIT1         2002
\ No newline at end of file
diff -uNr sc/source/ui/inc/datafdlg.hxx sc/source/ui/inc/datafdlg.hxx
--- sc/source/ui/inc/datafdlg.hxx	1970-01-01 08:00:00.000000000 +0800
+++ sc/source/ui/inc/datafdlg.hxx	2007-09-18 13:31:09.000000000 +0800
@@ -0,0 +1,121 @@
+/*************************************************************************
+ *
+ *  OpenOffice.org - a multi-platform office productivity suite
+ *
+ *  $RCSfile: datafdlg.hxx,v $
+ *
+ *  $Revision: 1.00 $
+ *
+ *  last change: $Author: rt $ $Date: 2005/09/08 21:20:35 $
+ *
+ *  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 SC_DATAFDLG_HXX
+#define SC_DATAFDLG_HXX
+
+
+#ifndef _SV_DIALOG_HXX //autogen
+#include <vcl/dialog.hxx>
+#endif
+
+#ifndef _SV_BUTTON_HXX //autogen
+#include <vcl/imagebtn.hxx>
+#endif
+
+#ifndef _SV_FIXED_HXX //autogen
+#include <vcl/fixed.hxx>
+#endif
+
+
+#include "global.hxx"
+
+#include <tabvwsh.hxx>
+#include <sfx2/bindings.hxx>
+#include <sfx2/dispatch.hxx>
+
+#define MAX_DATAFORM_COLS   256
+#define MAX_DATAFORM_ROWS   32000
+#define CTRL_HEIGHT         22
+#define FIXED_WIDTH         60
+#define EDIT_WIDTH          140 
+#define FIXED_LEFT          12
+#define EDIT_LEFT           78
+#define LINE_HEIGHT         30
+
+//zhangyun
+class ScDataFormDlg : public ModalDialog
+{
+private:
+
+	PushButton      aBtnNew;
+	PushButton      aBtnDelete;
+	PushButton      aBtnRestore;
+	PushButton      aBtnLast;
+	PushButton      aBtnNext;
+	PushButton      aBtnClose;
+	ScrollBar       aSlider;
+	FixedText       aFixedText;
+	//FixedText       aFixedText1;
+	//Edit            aEdit1;
+	
+	ScTabViewShell*	pTabViewShell;
+    ScDocument*     pDoc;
+	sal_uInt16      aColLength;
+	SCROW           aCurrentRow;
+	SCCOL           nStartCol;
+	SCCOL           nEndCol;
+	SCROW	        nStartRow;
+	SCROW	        nEndRow;
+	SCTAB	        nTab;
+	BOOL            bNoSelection;
+	
+	FixedText** pFixedTexts;
+    Edit** pEdits;
+
+public:
+	ScDataFormDlg( Window* pParent, ScTabViewShell*	pTabViewShell);
+	~ScDataFormDlg();
+	
+	void FillCtrls(SCROW nCurrentRow);
+private:
+
+	void SetButtonState();
+
+	// Handler:
+	DECL_LINK( Impl_NewHdl,		PushButton*    );
+	DECL_LINK( Impl_LastHdl,	PushButton*    );
+	DECL_LINK( Impl_NextHdl,	PushButton*    );
+	
+	DECL_LINK( Impl_RestoreHdl,	PushButton*    );
+	DECL_LINK( Impl_DeleteHdl,	PushButton*    );
+	DECL_LINK( Impl_CloseHdl,	PushButton*    );
+	
+	DECL_LINK( Impl_ScrollHdl,	ScrollBar*    );
+	DECL_LINK( Impl_DataModifyHdl,  Edit*    );
+};
+#endif // SC_DATAFDLG_HXX
+
+
diff -uNr sc/source/ui/inc/undodat.hxx sc/source/ui/inc/undodat.hxx
--- sc/source/ui/inc/undodat.hxx	2007-09-18 13:29:34.000000000 +0800
+++ sc/source/ui/inc/undodat.hxx	2007-09-18 13:31:09.000000000 +0800
@@ -554,7 +554,43 @@
 	void				Init();
 };
 
+// amelia
+class ScUndoDataForm: public ScBlockUndo
+{
+public:
+					TYPEINFO();
+					ScUndoDataForm( ScDocShell* pNewDocShell,
+								SCCOL nStartX, SCROW nStartY, SCTAB nStartZ,
+								SCCOL nEndX, SCROW nEndY, SCTAB nEndZ,
+								const ScMarkData& rMark,
+								ScDocument* pNewUndoDoc, ScDocument* pNewRedoDoc,
+								USHORT nNewFlags,
+								ScRefUndoData* pRefData, void* pFill1, void* pFill2, void* pFill3,
+								BOOL bRedoIsFilled = TRUE
+								 );
+	virtual		~ScUndoDataForm();
 
+	virtual	void	Undo();
+	virtual	void	Redo();
+	virtual void	Repeat(SfxRepeatTarget& rTarget);
+	virtual BOOL	CanRepeat(SfxRepeatTarget& rTarget) const;
+
+	virtual String	GetComment() const;
+
+private:
+	ScMarkData		aMarkData;
+	ScDocument*		pUndoDoc;
+	ScDocument*		pRedoDoc;
+	USHORT			nFlags;
+	ScRefUndoData*		pRefUndoData;
+	ScRefUndoData*		pRefRedoData;
+	ULONG			nStartChangeAction;
+	ULONG			nEndChangeAction;
+	BOOL			bRedoFilled;
+
+	void			DoChange( const BOOL bUndo );
+	void			SetChangeTrack();
+};
 
 
 #endif
diff -uNr sc/source/ui/inc/viewfunc.hxx sc/source/ui/inc/viewfunc.hxx
--- sc/source/ui/inc/viewfunc.hxx	2007-09-18 13:29:34.000000000 +0800
+++ sc/source/ui/inc/viewfunc.hxx	2007-09-18 13:31:09.000000000 +0800
@@ -340,6 +340,13 @@
 	void			ForgetFormatArea()		{ bFormatValid = FALSE; }
 	BOOL			SelectionEditable( BOOL* pOnlyNotBecauseOfMatrix = NULL );
 
+        // Amelia Wang
+        SC_DLLPUBLIC void                   DataFormPutData( SCROW nCurrentRow ,
+                                                             SCROW nStartRow , SCCOL nStartCol ,
+                                                             SCROW nEndRow , SCCOL nEndCol ,
+                                                             Edit** pEdits ,
+                                                             sal_uInt16 aColLength );
+
 												// interne Hilfsfunktionen
 protected:
 	void			UpdateLineAttrs( SvxBorderLine&		  rLine,
diff -uNr sc/source/ui/miscdlgs/datafdlg.cxx sc/source/ui/miscdlgs/datafdlg.cxx
--- sc/source/ui/miscdlgs/datafdlg.cxx	1970-01-01 08:00:00.000000000 +0800
+++ sc/source/ui/miscdlgs/datafdlg.cxx	2007-09-18 13:31:17.000000000 +0800
@@ -0,0 +1,434 @@
+/*************************************************************************
+ *
+ *  OpenOffice.org - a multi-platform office productivity suite
+ *
+ *  $RCSfile: datafdlg.cxx,v $
+ *
+ *  $Revision: 1.00 $
+ *
+ *  last change: $Author: kz $ $Date: 2006/07/21 14:04:33 $
+ *
+ *  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_sc.hxx"
+
+#undef SC_DLLIMPLEMENTATION
+
+//------------------------------------------------------------------
+
+#include "datafdlg.hxx"
+#include "scresid.hxx"
+#include "datafdlg.hrc"
+#include "viewdata.hxx"
+//#include "document.hxx"
+#include "docsh.hxx"
+#include "refundo.hxx"
+#include "undodat.hxx"
+
+static BYTE nDelItemChecked=0;
+#define HDL(hdl)			LINK( this, ScDataFormDlg, hdl )
+
+//zhangyun
+ScDataFormDlg::ScDataFormDlg( Window* pParent, ScTabViewShell*	pTabViewShellOri) :
+	ModalDialog     ( pParent, ScResId( RID_SCDLG_DATAFORM ) ),
+	//
+	aFixedText          ( this, ScResId( LAB_DATAFORM_RECORDNO ) ),
+	aBtnNew          ( this, ScResId( BTN_DATAFORM_NEW ) ),
+	aBtnDelete          ( this, ScResId( BTN_DATAFORM_DELETE ) ),
+	aBtnRestore          ( this, ScResId( BTN_DATAFORM_RESTORE ) ),
+	aBtnLast          ( this, ScResId( BTN_DATAFORM_LAST ) ),
+	aBtnNext          ( this, ScResId( BTN_DATAFORM_NEXT ) ),
+    aBtnClose          ( this, ScResId( BTN_DATAFORM_CLOSE ) ),
+    aSlider			( this, ScResId( WND_DATAFORM_SCROLLBAR ) )
+    //aSlider          ( this, ScResId( WND_DATAFORM_SCROLLBAR ) ),
+    //aFixedText1          ( this, ScResId( FT_DATAFORM_FIXEDTEXT1 ) ),
+    //aEdit1          ( this, ScResId( ED_DATAFORM_EDIT1 ) )
+{
+    pTabViewShell = pTabViewShellOri;
+    FreeResource();
+    //read header form current document, and add new controls
+    DBG_ASSERT( pTabViewShell, "pTabViewShell is NULL! :-/" );
+    ScViewData*	pViewData = pTabViewShell->GetViewData();
+    
+    //int aColLength=20;
+    //FixedText** pFixedTexts;
+    //Edit** pEdits;
+    //pFixedTexts = new FixedText*[aColLength];
+	//pEdits = new Edit*[aColLength];
+    
+    pDoc = pViewData->GetDocument();
+    if (pDoc)
+    {
+        ScRange aRange;
+        pViewData->GetSimpleArea( aRange );
+        ScAddress aStart = aRange.aStart;
+        ScAddress aEnd = aRange.aEnd;
+        
+        nStartCol = aStart.Col();
+		nEndCol = aEnd.Col();
+		nStartRow	= aStart.Row();
+		nEndRow	= aEnd.Row();
+		
+		nTab = pViewData->GetTabNo();
+		//if there is no selection
+		if ((nStartCol == nEndCol) && (nStartRow == nEndRow))
+		    bNoSelection = TRUE;
+		
+		if (bNoSelection)
+		{
+		    //find last not blank cell in row
+		    for (int i=1;i<=MAX_DATAFORM_COLS;i++)
+		    {
+		        String	aColName;
+		        nEndCol++;
+		        pDoc->GetString( nEndCol, nStartRow, nTab, aColName );
+		        int nColWidth = pDoc->GetColWidth( nEndCol, nTab );
+		        if ( aColName.Len() == 0 && nColWidth)
+		        {
+                    nEndCol--;
+                    break;
+                }
+		    }
+		    
+		    //find first not blank cell in row
+		    for (int i=1;i<=MAX_DATAFORM_COLS;i++)
+		    {
+		        String	aColName;
+		        if (nStartCol <= 0)
+		            break;
+		        nStartCol--;
+
+		        pDoc->GetString( nStartCol, nStartRow, nTab, aColName );
+		        int nColWidth = pDoc->GetColWidth( nEndCol, nTab );
+		        if ( aColName.Len() == 0 && nColWidth)
+		        {
+                    nStartCol++;
+                    break;
+                }
+		    }
+		    
+		    //skip leading hide column
+		    for (int i=1;i<=MAX_DATAFORM_COLS;i++)
+		    {
+		        String	aColName;
+		        int nColWidth = pDoc->GetColWidth( nStartCol, nTab );
+		        if (nColWidth)
+		            break;
+		        nStartCol++;
+		    }
+
+		    if (nEndCol < nStartCol)
+		        nEndCol = nStartCol;
+		        
+		    //find last not blank cell in row
+		    for (int i=1;i<=MAX_DATAFORM_ROWS;i++)
+		    {
+		        String	aColName;
+		        nEndRow++;
+		        pDoc->GetString( nStartCol, nEndRow, nTab, aColName );
+		        if ( aColName.Len() == 0 )
+		        {
+                    nEndRow--;
+                    break;
+                }
+		    }
+		    
+		    //find first not blank cell in row
+		    for (int i=1;i<=MAX_DATAFORM_ROWS;i++)
+		    {
+		        String	aColName;
+		        if (nStartRow <= 0)
+		            break;
+		        nStartRow--;
+
+		        pDoc->GetString( nStartCol, nStartRow, nTab, aColName );
+		        if ( aColName.Len() == 0 )
+		        {
+                    nStartRow++;
+                    break;
+                }
+		    }
+
+		    if (nEndRow < nStartRow)
+		        nEndRow = nStartRow;
+		}
+		
+		aCurrentRow = nStartRow + 1;
+		
+		SCCOL	col;
+		String	aFieldName;
+
+		int nTop = 12;
+
+		Size	nFixedSize(FIXED_WIDTH, CTRL_HEIGHT );
+	    Size	nEditSize(EDIT_WIDTH, CTRL_HEIGHT );
+		
+		//pFtArray = new FixedText(this);
+		aColLength = nEndCol - nStartCol + 1;
+	    
+	    //new the controls
+	    pFixedTexts = new FixedText*[aColLength];
+	    pEdits = new Edit*[aColLength];
+	    
+	    for(sal_uInt16 nIndex = 0; nIndex < aColLength; nIndex++)
+		{
+    		pDoc->GetString( nIndex + nStartCol, nStartRow, nTab, aFieldName );
+    		int nColWidth = pDoc->GetColWidth( nIndex + nStartCol, nTab );
+    		if (nColWidth)
+    		{
+        		pFixedTexts[nIndex] = new FixedText(this);
+        		pEdits[nIndex] = new Edit(this, WB_BORDER);
+        
+        		pFixedTexts[nIndex]->SetSizePixel(nFixedSize);
+        		pEdits[nIndex]->SetSizePixel(nEditSize);
+        		pFixedTexts[nIndex]->SetPosPixel(Point(FIXED_LEFT, nTop));
+        		pEdits[nIndex]->SetPosPixel(Point(EDIT_LEFT, nTop));
+        		//pFixedTexts[nIndex]->SetText(String::CreateFromAscii("W4W-Filter Nr. "));
+        		pFixedTexts[nIndex]->SetText(aFieldName);
+        		pFixedTexts[nIndex]->Show();
+        		pEdits[nIndex]->Show();
+        		
+        		nTop += LINE_HEIGHT;
+    	    }
+        	else
+        	{
+        	    pFixedTexts[nIndex] = NULL;
+        		pEdits[nIndex] = NULL;
+        	}
+		pEdits[nIndex]->SetModifyHdl( HDL(Impl_DataModifyHdl) );
+    	}
+    	
+    	Size nDialogSize = this->GetSizePixel();
+        if (nTop > nDialogSize.Height())
+        {
+            nDialogSize.setHeight(nTop);
+            this->SetSizePixel(nDialogSize);
+        }
+        Size nScrollSize = aSlider.GetSizePixel();
+        nScrollSize.setHeight(nDialogSize.Height()-20);
+        aSlider.SetSizePixel(nScrollSize);
+    }
+    
+    FillCtrls(aCurrentRow);
+    
+    aSlider.SetPageSize( 10 );
+    aSlider.SetVisibleSize( 1 );
+    aSlider.SetLineSize( 1 );
+    aSlider.SetRange( Range( 0, nEndRow - nStartRow + 1) );
+    aSlider.Show();
+    
+    aBtnNew.SetClickHdl 	( HDL(Impl_NewHdl)    );
+    aBtnLast.SetClickHdl 	( HDL(Impl_LastHdl)    );
+    aBtnNext.SetClickHdl 	( HDL(Impl_NextHdl)    );
+    
+    aBtnRestore.SetClickHdl 	( HDL(Impl_RestoreHdl)    );
+    aBtnDelete.SetClickHdl 	( HDL(Impl_DeleteHdl)    );
+    aBtnClose.SetClickHdl 	( HDL(Impl_CloseHdl)    );
+    
+    aSlider.SetEndScrollHdl( HDL( Impl_ScrollHdl ) );
+
+    SetButtonState();
+
+    //end
+	//FreeResource();
+}
+
+__EXPORT ScDataFormDlg::~ScDataFormDlg()
+{
+    for(sal_uInt16 i = 0; i < aColLength; i++)
+    {
+	    if (pEdits[i])
+    	    delete pEdits[i];
+	    if (pFixedTexts[i])
+    	    delete pFixedTexts[i];
+    }
+    if (pEdits)
+    	delete pEdits;
+	if (pFixedTexts)
+    	delete pFixedTexts;
+}
+
+void ScDataFormDlg::FillCtrls(SCROW nCurrentRow)
+{
+    //ScViewData*	pViewData = pTabViewShell->GetViewData();
+    
+    //pDoc = pViewData->GetDocument();
+    String	aFieldName;
+    int nRecordNum = nEndRow - nStartRow;
+    for(sal_uInt16 i = 0; i < aColLength; i++)
+    {
+	    if (pEdits[i])
+	    {
+    	    if (aCurrentRow<=nEndRow)
+    	    {
+    	        pDoc->GetString( i + nStartCol, aCurrentRow, nTab, aFieldName );
+    	        pEdits[i]->SetText(aFieldName);
+    	    }
+    	    else
+    	        pEdits[i]->SetText(String());
+	    }
+    }
+    char sRecordStr[256];
+	sprintf(sRecordStr, "%i / %i", aCurrentRow-nStartRow, nRecordNum);
+    if (aCurrentRow<=nEndRow)
+	    aFixedText.SetText(String::CreateFromAscii(sRecordStr));
+	else
+	    aFixedText.SetText(String::CreateFromAscii("New Record"));
+	    
+	aSlider.SetThumbPos(aCurrentRow-nStartRow-1);
+}
+
+IMPL_LINK( ScDataFormDlg, Impl_DataModifyHdl, Edit*, pEdit)
+{
+	if ( pEdit->IsModified() )
+		aBtnRestore.Enable( TRUE );
+	return 0;
+}
+
+IMPL_LINK( ScDataFormDlg, Impl_NewHdl, PushButton*, pBtn)
+{
+    ScViewData*	pViewData = pTabViewShell->GetViewData();
+    ScDocShell* pDocSh = pViewData->GetDocShell();
+    if ( pDoc )
+    {
+		sal_Bool bHasData = sal_False;
+		for(sal_uInt16 i = 0; i < aColLength; i++)
+			if (pEdits[i])
+				if ( pEdits[i]->GetText().Len() != 0 )
+				{
+					bHasData = sal_True;
+					break;
+				}
+
+		if ( bHasData )
+		{
+			pTabViewShell->DataFormPutData( aCurrentRow , nStartRow , nStartCol , nEndRow , nEndCol , pEdits , aColLength );
+			aCurrentRow++;
+			if (aCurrentRow >= nEndRow + 2)
+			{
+		    		nEndRow ++ ;
+		    		aSlider.SetRange( Range( 0, nEndRow - nStartRow + 1) );
+			}
+			SetButtonState();
+			FillCtrls(aCurrentRow);
+			pDocSh->SetDocumentModified();
+			pDocSh->PostPaintGridAll();
+    		}
+	}
+	return 0;
+}
+
+IMPL_LINK( ScDataFormDlg, Impl_LastHdl, PushButton*, pBtn)
+{   
+    if (pDoc)
+    {
+		if ( aCurrentRow > nStartRow +1 )
+		    aCurrentRow--;
+
+		SetButtonState();
+		FillCtrls(aCurrentRow);
+    }
+    return 0;
+}
+
+IMPL_LINK( ScDataFormDlg, Impl_NextHdl, PushButton*, pBtn)
+{   
+    if (pDoc)
+    {
+		if ( aCurrentRow <= nEndRow)
+		    aCurrentRow++;
+
+		SetButtonState();
+		FillCtrls(aCurrentRow);
+    }
+    return 0;
+}
+
+IMPL_LINK( ScDataFormDlg, Impl_RestoreHdl, PushButton*, pBtn)
+{   
+    if (pDoc)
+    {
+		FillCtrls(aCurrentRow);
+    }
+    return 0;
+}
+
+IMPL_LINK( ScDataFormDlg, Impl_DeleteHdl, PushButton*, pBtn)
+{   
+    ScViewData*	pViewData = pTabViewShell->GetViewData();
+    ScDocShell* pDocSh = pViewData->GetDocShell();
+    if (pDoc)
+    {
+		ScRange aRange(nStartCol, aCurrentRow, nTab, nEndCol, aCurrentRow, nTab);
+		pDoc->DeleteRow(aRange);
+		nEndRow--;
+		
+		SetButtonState();
+		pDocSh->GetUndoManager()->Clear();
+
+		FillCtrls(aCurrentRow);
+		pDocSh->SetDocumentModified();
+		pDocSh->PostPaintGridAll();
+    }
+    return 0;
+}
+
+IMPL_LINK( ScDataFormDlg, Impl_CloseHdl, PushButton*, pBtn)
+{   
+    EndDialog( );
+    return 0;
+}
+
+IMPL_LINK( ScDataFormDlg, Impl_ScrollHdl, ScrollBar*, EMPTYARG)
+{   
+    long nOffset = aSlider.GetThumbPos();
+    aCurrentRow = nStartRow + nOffset + 1;
+    SetButtonState();
+    FillCtrls(aCurrentRow);
+    return 0;
+}
+
+void ScDataFormDlg::SetButtonState()
+{
+    if ( aCurrentRow > nEndRow )
+    {
+        aBtnDelete.Enable( FALSE );
+        aBtnLast.Enable( TRUE );
+        aBtnNext.Enable( FALSE );
+    }
+    else
+    {
+        aBtnDelete.Enable( TRUE );
+        aBtnNext.Enable( TRUE );
+    }
+    if ( 1 == aCurrentRow )
+        aBtnLast.Enable( FALSE );
+
+    aBtnRestore.Enable( FALSE );
+    if ( pEdits )
+        pEdits[0]->GrabFocus();
+}
diff -uNr sc/source/ui/miscdlgs/makefile.mk sc/source/ui/miscdlgs/makefile.mk
--- sc/source/ui/miscdlgs/makefile.mk	2007-09-18 13:29:39.000000000 +0800
+++ sc/source/ui/miscdlgs/makefile.mk	2007-09-18 13:31:17.000000000 +0800
@@ -54,6 +54,7 @@
 # --- Files --------------------------------------------------------
 
 SLOFILES =  \
+	$(SLO)$/datafdlg.obj		\
 	$(SLO)$/delcldlg.obj		\
 	$(SLO)$/inscldlg.obj		\
 	$(SLO)$/delcodlg.obj		\
diff -uNr sc/source/ui/src/datafdlg.src sc/source/ui/src/datafdlg.src
--- sc/source/ui/src/datafdlg.src	1970-01-01 08:00:00.000000000 +0800
+++ sc/source/ui/src/datafdlg.src	2007-09-18 13:31:10.000000000 +0800
@@ -0,0 +1,108 @@
+/*************************************************************************
+ *
+ *  OpenOffice.org - a multi-platform office productivity suite
+ *
+ *  $RCSfile: datafdlg.src,v $
+ *
+ *  $Revision: 1.00 $
+ *
+ *  last change: $Author: hr $ $Date: 2005/09/23 15:07:30 $
+ *
+ *  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
+ *
+ ************************************************************************/
+
+#include "datafdlg.hrc"
+
+//zhangyun, dataform
+ModalDialog RID_SCDLG_DATAFORM
+{
+	OutputSize = TRUE ;
+	SVLook = TRUE ;
+    Size = MAP_APPFONT ( 191 , 180 ) ;
+	Text [ en-US ] = "Data Form" ;
+	Moveable = TRUE ;
+	Closeable = TRUE ;
+	FixedText LAB_DATAFORM_RECORDNO
+	{
+		Pos = MAP_APPFONT ( 136 , 6 ) ;
+        Size = MAP_APPFONT ( 50 , 12 ) ;
+		Text [ en-US ] = "/" ;
+	};
+	PushButton BTN_DATAFORM_NEW
+	{
+		Pos = MAP_APPFONT ( 135 , 23 ) ;
+		Size = MAP_APPFONT ( 50 , 14 ) ;
+		TabStop = TRUE ;
+		DefButton = TRUE ;
+		Text [ en-US ] = "New" ;
+	};
+	PushButton BTN_DATAFORM_DELETE
+	{
+		Pos = MAP_APPFONT ( 135 , 40 ) ;
+		Size = MAP_APPFONT ( 50 , 14 ) ;
+		TabStop = TRUE ;
+		Text [ en-US ] = "Delete" ;
+	};
+	PushButton BTN_DATAFORM_RESTORE
+	{
+		Pos = MAP_APPFONT ( 135 , 57 ) ;
+		Size = MAP_APPFONT ( 50 , 14 ) ;
+		TabStop = TRUE ;
+		Text [ en-US ] = "Restore" ;
+	};
+	PushButton BTN_DATAFORM_LAST
+	{
+		Pos = MAP_APPFONT ( 135 , 82 ) ;
+		Size = MAP_APPFONT ( 50 , 14 ) ;
+		TabStop = TRUE ;
+		Text [ en-US ] = "Last Record" ;
+	};
+	PushButton BTN_DATAFORM_NEXT
+	{
+		Pos = MAP_APPFONT ( 135 , 99 ) ;
+		Size = MAP_APPFONT ( 50 , 14 ) ;
+		TabStop = TRUE ;
+		Text [ en-US ] = "Next Record" ;
+	};
+	PushButton BTN_DATAFORM_CLOSE
+	{
+		Pos = MAP_APPFONT ( 135 , 116 ) ;
+		Size = MAP_APPFONT ( 50 , 14 ) ;
+		TabStop = TRUE ;
+		Text [ en-US ] = "Close" ;
+	};
+	ScrollBar WND_DATAFORM_SCROLLBAR
+    {
+        Pos = MAP_APPFONT ( 124 , 6 ) ;
+        Size = MAP_APPFONT ( 8 , 135 ) ;
+        HScroll = FALSE ;
+        TabStop = FALSE ;
+    };
+};
+//end
+
+
+
+
diff -uNr sc/source/ui/src/makefile.mk sc/source/ui/src/makefile.mk
--- sc/source/ui/src/makefile.mk	2007-09-18 13:29:34.000000000 +0800
+++ sc/source/ui/src/makefile.mk	2007-09-18 13:31:10.000000000 +0800
@@ -61,6 +61,7 @@
 	dbnamdlg.src \
 	subtdlg.src  \
 	miscdlgs.src \
+	datafdlg.src \
 	autofmt.src  \
 	solvrdlg.src \
 	tabopdlg.src \
diff -uNr sc/source/ui/undo/undodat.cxx sc/source/ui/undo/undodat.cxx
--- sc/source/ui/undo/undodat.cxx	2007-09-18 13:29:34.000000000 +0800
+++ sc/source/ui/undo/undodat.cxx	2007-09-18 13:31:11.000000000 +0800
@@ -63,6 +63,8 @@
 #include "dpobject.hxx"
 #include "attrib.hxx"
 #include "sc.hrc"
+#include "chgtrack.hxx"  // Amelia Wang
+#include "refundo.hxx"  // Amelia Wang
 
 // -----------------------------------------------------------------------
 
@@ -83,6 +85,7 @@
 TYPEINIT1(ScUndoDataPilot,			SfxUndoAction);
 TYPEINIT1(ScUndoConsolidate,		SfxUndoAction);
 TYPEINIT1(ScUndoChartData,			SfxUndoAction);
+TYPEINIT1(ScUndoDataForm, 			SfxUndoAction);    // amelia
 
 // -----------------------------------------------------------------------
 
@@ -2182,8 +2185,218 @@
 	return FALSE;
 }
 
+// Amelia Wang
+ScUndoDataForm::ScUndoDataForm( ScDocShell* pNewDocShell,
+                                SCCOL nStartX, SCROW nStartY, SCTAB nStartZ,
+                                SCCOL nEndX, SCROW nEndY, SCTAB nEndZ,
+                                const ScMarkData& rMark,
+                                ScDocument* pNewUndoDoc, ScDocument* pNewRedoDoc,
+                                USHORT nNewFlags,
+                                ScRefUndoData* pRefData,
+                                void* pFill1, void* pFill2, void* pFill3,
+                                BOOL bRedoIsFilled ) :
+        ScBlockUndo( pNewDocShell, ScRange( nStartX, nStartY, nStartZ, nEndX, nEndY, nEndZ ), SC_UNDO_SIMPLE ),
+        aMarkData( rMark ),
+        pUndoDoc( pNewUndoDoc ),
+        pRedoDoc( pNewRedoDoc ),
+        nFlags( nNewFlags ),
+        pRefUndoData( pRefData ),
+        pRefRedoData( NULL ),
+        bRedoFilled( bRedoIsFilled )
+{
+        //      pFill1,pFill2,pFill3 are there so the ctor calls for simple paste (without cutting)
+        //      don't have to be changed and branched for 641.
+        //      They can be removed later.
+
+        if ( !aMarkData.IsMarked() )                            // no cell marked:
+                aMarkData.SetMarkArea( aBlockRange );   //  mark paste block
+
+        if ( pRefUndoData )
+                pRefUndoData->DeleteUnchanged( pDocShell->GetDocument() );
+
+        SetChangeTrack();
+}
+
+__EXPORT ScUndoDataForm::~ScUndoDataForm()
+{
+        delete pUndoDoc;
+        delete pRedoDoc;
+        delete pRefUndoData;
+        delete pRefRedoData;
+}
+
+String __EXPORT ScUndoDataForm::GetComment() const
+{
+        return ScGlobal::GetRscString( STR_UNDO_PASTE ); 
+}
+
+void ScUndoDataForm::SetChangeTrack()
+{
+        ScChangeTrack* pChangeTrack = pDocShell->GetDocument()->GetChangeTrack();
+        if ( pChangeTrack && (nFlags & IDF_CONTENTS) )
+                pChangeTrack->AppendContentRange( aBlockRange, pUndoDoc,
+                        nStartChangeAction, nEndChangeAction, SC_CACM_PASTE );
+        else
+                nStartChangeAction = nEndChangeAction = 0;
+}
+
+
+void __EXPORT ScUndoDataForm::Undo()
+{
+        BeginUndo();
+        DoChange( TRUE );
+        ShowTable( aBlockRange );
+        EndUndo();
+        SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_AREALINKS_CHANGED ) );
+}
+
+void __EXPORT ScUndoDataForm::Redo()
+{
+        BeginRedo();
+        ScDocument* pDoc = pDocShell->GetDocument();
+        EnableDrawAdjust( pDoc, FALSE );                                //! include in ScBlockUndo?
+        DoChange( FALSE );
+        EnableDrawAdjust( pDoc, TRUE );                                 //! include in ScBlockUndo?
+        EndRedo();
+        SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_AREALINKS_CHANGED ) );
+}
+
+void __EXPORT ScUndoDataForm::Repeat(SfxRepeatTarget& rTarget)
+{
+        if (rTarget.ISA(ScTabViewTarget))
+        {
+                ScTabViewShell* pViewSh = ((ScTabViewTarget&)rTarget).GetViewShell();
+                //ScTransferObj* pOwnClip = ScTransferObj::GetOwnClipboard( pViewSh->GetActiveWin() );
+        }
+}
+
+BOOL __EXPORT ScUndoDataForm::CanRepeat(SfxRepeatTarget& rTarget) const
+{
+        return (rTarget.ISA(ScTabViewTarget));
+}
+
+void ScUndoDataForm::DoChange( const BOOL bUndo )
+{
+            ScDocument* pDoc = pDocShell->GetDocument();
+
+        //      RefUndoData for redo is created before first undo
+        //      (with DeleteUnchanged after the DoUndo call)
+        BOOL bCreateRedoData = ( bUndo && pRefUndoData && !pRefRedoData );
+        if ( bCreateRedoData )
+                pRefRedoData = new ScRefUndoData( pDoc );
+
+        ScRefUndoData* pWorkRefData = bUndo ? pRefUndoData : pRefRedoData;
 
+                //      fuer Undo immer alle oder keine Inhalte sichern
+        USHORT nUndoFlags = IDF_NONE;
+        if (nFlags & IDF_CONTENTS)
+                nUndoFlags |= IDF_CONTENTS;
+        if (nFlags & IDF_ATTRIB)
+                nUndoFlags |= IDF_ATTRIB;
 
+        BOOL bPaintAll = FALSE;
 
+        ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
 
+        // marking is in ScBlockUndo...
+        //ScUndoUtil::MarkSimpleBlock( pDocShell, aBlockRange );
 
+    SCTAB nTabCount = pDoc->GetTableCount();
+        if ( bUndo && !bRedoFilled )
+        {
+                if (!pRedoDoc)
+                {
+                        BOOL bColInfo = ( aBlockRange.aStart.Row()==0 && aBlockRange.aEnd.Row()==MAXROW );
+                        BOOL bRowInfo = ( aBlockRange.aStart.Col()==0 && aBlockRange.aEnd.Col()==MAXCOL );
+
+            SCTAB nStartTab = aBlockRange.aStart.Tab();
+                        pRedoDoc = new ScDocument( SCDOCMODE_UNDO );
+            pRedoDoc->InitUndoSelected( pDoc, aMarkData, bColInfo, bRowInfo );
+                }
+        //  read "redo" data from the document in the first undo
+                //  all sheets - CopyToDocument skips those that don't exist in pRedoDoc
+        ScRange aCopyRange = aBlockRange;
+        aCopyRange.aStart.SetTab(0);
+        aCopyRange.aEnd.SetTab(nTabCount-1);
+                pDoc->CopyToDocument( aCopyRange, 1, FALSE, pRedoDoc );
+                bRedoFilled = TRUE;
+        }
+
+        USHORT nExtFlags = 0;
+        pDocShell->UpdatePaintExt( nExtFlags, aBlockRange );
+
+        for ( sal_uInt16 i=0; i <= ( aBlockRange.aEnd.Col() - aBlockRange.aStart.Col() ); i++ )
+        {
+            String aOldString;
+            pUndoDoc->GetString( aBlockRange.aStart.Col()+i , aBlockRange.aStart.Row() , aBlockRange.aStart.Tab() , aOldString );
+            pDoc->SetString( aBlockRange.aStart.Col()+i , aBlockRange.aStart.Row() , aBlockRange.aStart.Tab() , aOldString );
+        }
+
+    SCTAB nFirstSelected = aMarkData.GetFirstSelected();
+    ScRange aTabSelectRange = aBlockRange;
+    SCTAB nTab;
+
+        if (pWorkRefData)
+        {
+                pWorkRefData->DoUndo( pDoc, TRUE );             // TRUE = bSetChartRangeLists for SetChartListenerCollection
+                if ( pDoc->RefreshAutoFilter( 0,0, MAXCOL,MAXROW, aBlockRange.aStart.Tab() ) )
+                        bPaintAll = TRUE;
+        }
+
+        if ( bCreateRedoData && pRefRedoData )
+                pRefRedoData->DeleteUnchanged( pDoc );
+       
+        if ( bUndo )
+        {
+                ScChangeTrack* pChangeTrack = pDoc->GetChangeTrack();
+                if ( pChangeTrack )
+                        pChangeTrack->Undo( nStartChangeAction, nEndChangeAction );
+        }
+        else
+                SetChangeTrack();
+
+        ScRange aDrawRange( aBlockRange );
+    pDoc->ExtendMerge( aDrawRange, TRUE );      // only needed for single sheet (text/rtf etc.)
+        USHORT nPaint = PAINT_GRID;
+        if (bPaintAll)
+        {
+                aDrawRange.aStart.SetCol(0);
+                aDrawRange.aStart.SetRow(0);
+                aDrawRange.aEnd.SetCol(MAXCOL);
+                aDrawRange.aEnd.SetRow(MAXROW);
+                nPaint |= PAINT_TOP | PAINT_LEFT;
+/*A*/   if (pViewShell)
+                        pViewShell->AdjustBlockHeight(FALSE);
+        }
+        else
+        {
+                if ( aBlockRange.aStart.Row() == 0 && aBlockRange.aEnd.Row() == MAXROW )        // ganze Spalte
+                {
+                        nPaint |= PAINT_TOP;
+                        aDrawRange.aEnd.SetCol(MAXCOL);
+                }
+                if ( aBlockRange.aStart.Col() == 0 && aBlockRange.aEnd.Col() == MAXCOL )        // ganze Zeile
+                {
+                        nPaint |= PAINT_LEFT;
+                        aDrawRange.aEnd.SetRow(MAXROW);
+                }
+/*A*/   if ((pViewShell) && pViewShell->AdjustBlockHeight(FALSE))
+                {
+                        aDrawRange.aStart.SetCol(0);
+                        aDrawRange.aStart.SetRow(0);
+                        aDrawRange.aEnd.SetCol(MAXCOL);
+                        aDrawRange.aEnd.SetRow(MAXROW);
+                        nPaint |= PAINT_LEFT;
+                }
+                pDocShell->UpdatePaintExt( nExtFlags, aDrawRange );
+        }
+
+    if ( !bUndo )                               //      draw redo after updating row heights
+                RedoSdrUndoAction( pDrawUndo );                 //!     include in ScBlockUndo?
+
+        pDocShell->PostPaint( aDrawRange, nPaint, nExtFlags );
+
+        pDocShell->PostDataChanged();
+        if (pViewShell)
+                pViewShell->CellContentChanged();
+}
diff -uNr sc/source/ui/view/cellsh2.cxx sc/source/ui/view/cellsh2.cxx
--- sc/source/ui/view/cellsh2.cxx	2007-09-18 13:29:34.000000000 +0800
+++ sc/source/ui/view/cellsh2.cxx	2007-09-18 13:31:11.000000000 +0800
@@ -228,6 +228,20 @@
 			}
 			break;
 
+		case SID_DATA_FORM:
+			{
+				ScAbstractDialogFactory* pFact = ScAbstractDialogFactory::Create();
+	            DBG_ASSERT(pFact, "ScAbstractFactory create fail!");//CHINA001
+
+	            AbstractScDataFormDlg* pDlg = pFact->CreateScDataFormDlg( pTabViewShell->GetDialogParent(),RID_SCDLG_DATAFORM, pTabViewShell);
+	            DBG_ASSERT(pDlg, "Dialog create fail!");//CHINA001
+
+	            pDlg->Execute();
+	            
+				rReq.Done();
+			}
+			break;
+			
 		case SID_SUBTOTALS:
 			{
 				const SfxItemSet* pArgs = rReq.GetArgs();
@@ -561,6 +575,15 @@
 			rReq.Done();
 			break;
 
+		// Amelia Wang
+		case SID_DATAFORM_NEW:
+		{
+			ScViewData * pViewData = pTabViewShell->GetViewData();
+			ScDocShell * pDocSh = pViewData->GetDocShell();
+			//pTabViewShell->DataFormPutData();
+		}
+		break;
+
 		case SID_PIVOT_TABLE:
 			{
 				const SfxPoolItem* pItem;
diff -uNr sc/source/ui/view/viewfun3.cxx sc/source/ui/view/viewfun3.cxx
--- sc/source/ui/view/viewfun3.cxx	2007-09-18 13:29:34.000000000 +0800
+++ sc/source/ui/view/viewfun3.cxx	2007-09-18 13:31:11.000000000 +0800
@@ -214,6 +214,7 @@
 #include "editable.hxx"
 #include "transobj.hxx"
 #include "drwtrans.hxx"
+#include "undodat.hxx"   // Amelia Wang
 
 using namespace com::sun::star;
 
@@ -1343,6 +1344,85 @@
 	return TRUE;
 }
 
+void ScViewFunc::DataFormPutData( SCROW nCurrentRow ,
+                                  SCROW nStartRow , SCCOL nStartCol ,
+                                  SCROW nEndRow , SCCOL nEndCol ,
+                                  Edit** pEdits ,
+                                  sal_uInt16 aColLength )
+{
+    ScDocument* pDoc = GetViewData()->GetDocument();
+    ScDocShell* pDocSh = GetViewData()->GetDocShell();
+    ScMarkData& rMark = GetViewData()->GetMarkData();
+    ScDocShellModificator aModificator( *pDocSh );
+    SfxUndoManager* pUndoMgr = pDocSh->GetUndoManager();
+    if ( pDoc )
+    {
+        const BOOL bRecord( pDoc->IsUndoEnabled());
+        ScDocument* pUndoDoc = NULL;
+        ScDocument* pRedoDoc = NULL;
+        ScDocument* pRefUndoDoc = NULL;
+        ScRefUndoData* pUndoData = NULL;
+        SCTAB nTab = GetViewData()->GetTabNo();
+        SCTAB nStartTab = nTab;
+        SCTAB nEndTab = nTab;
+        
+        {
+                ScChangeTrack* pChangeTrack = pDoc->GetChangeTrack();
+                if ( pChangeTrack )
+                        pChangeTrack->ResetLastCut();   // kein CutMode mehr
+        }
+        ScRange aUserRange( nStartCol, nCurrentRow, nStartTab, nEndCol, nCurrentRow, nEndTab );
+        BOOL bColInfo = ( nStartRow==0 && nEndRow==MAXROW );
+        BOOL bRowInfo = ( nStartCol==0 && nEndCol==MAXCOL );
+        SCCOL nUndoEndCol = nStartCol+aColLength-1;
+        SCROW nUndoEndRow = nCurrentRow;
+        USHORT nUndoFlags = IDF_NONE;
 
+        if ( bRecord )
+        {
+            pUndoDoc = new ScDocument( SCDOCMODE_UNDO );
+            pUndoDoc->InitUndoSelected( pDoc , rMark , bColInfo , bRowInfo );
+            pDoc->CopyToDocument( aUserRange , 1 , FALSE , pUndoDoc );
+        }
+        USHORT nExtFlags = 0;
+        pDocSh->UpdatePaintExt( nExtFlags, nStartCol, nStartRow, nStartTab , nEndCol, nEndRow, nEndTab ); // content before the change
+        //rMark.SetMarkArea( aUserRange );
+        pDoc->BeginDrawUndo();
+        
+        for(sal_uInt16 i = 0; i < aColLength; i++)
+        {
+            if (pEdits[i])
+            {
+                String  aFieldName=pEdits[i]->GetText();
+                pDoc->SetString( nStartCol + i, nCurrentRow, nTab, aFieldName );
+            }
+        }
+        //pDoc->ExtendMergeSel( nStartCol, nStartRow, nEndCol, nEndRow, rMark, TRUE );    // Refresh
+        pDocSh->UpdatePaintExt( nExtFlags, nStartCol, nCurrentRow, nStartTab, nEndCol, nCurrentRow, nEndTab );  // content after the change
+        SfxUndoAction* pUndo = new ScUndoDataForm( pDocSh,
+                                                                nStartCol, nCurrentRow, nStartTab,
+                                                                nUndoEndCol, nUndoEndRow, nEndTab, rMark,
+                                                                pUndoDoc, pRedoDoc, nUndoFlags,
+                                                                pUndoData, NULL, NULL, NULL,
+                                                                FALSE );           // FALSE = Redo data not yet copied
+        pUndoMgr->AddUndoAction( new ScUndoWrapper( pUndo ), TRUE );
+        
+        USHORT nPaint = PAINT_GRID;
+        if (bColInfo)
+        {
+                nPaint |= PAINT_TOP;
+                nUndoEndCol = MAXCOL;                           // nur zum Zeichnen !
+        }
+        if (bRowInfo)
+        {
+                nPaint |= PAINT_LEFT;
+                nUndoEndRow = MAXROW;                           // nur zum Zeichnen !
+        }
+
+        pDocSh->PostPaint( nStartCol, nCurrentRow, nStartTab,
+                                                nUndoEndCol, nUndoEndRow, nEndTab, nPaint, nExtFlags );
+        pDocSh->UpdateOle(GetViewData());
+    }
+}
 
 
diff -uNr sc/uiconfig/scalc/menubar/menubar.xml sc/uiconfig/scalc/menubar/menubar.xml
--- sc/uiconfig/scalc/menubar/menubar.xml	2007-09-18 13:29:34.000000000 +0800
+++ sc/uiconfig/scalc/menubar/menubar.xml	2007-09-18 13:31:08.000000000 +0800
@@ -397,6 +397,7 @@
 					<menu:menuitem menu:id=".uno:DataFilterHideAutoFilter"/>
 				</menu:menupopup>
 			</menu:menu>
+			<menu:menuitem menu:id=".uno:DataForm"/>
 			<menu:menuitem menu:id=".uno:DataSubTotals"/>
 			<menu:menuitem menu:id=".uno:Validation"/>
 			<menu:menuseparator/>
diff -uNr sc/util/makefile.mk sc/util/makefile.mk
--- sc/util/makefile.mk	2007-09-18 13:29:34.000000000 +0800
+++ sc/util/makefile.mk	2007-09-18 13:31:08.000000000 +0800
@@ -247,6 +247,7 @@
 		$(SLO)$/filldlg.obj			\
 		$(SLO)$/delcodlg.obj		\
 		$(SLO)$/delcldlg.obj		\
+		$(SLO)$/datafdlg.obj		\
 		$(SLO)$/dapitype.obj	\
 		$(SLO)$/dapidata.obj	\
 		$(SLO)$/crdlg.obj			\
