1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include "TEditControl.hxx"
21 #include <comphelper/processfactory.hxx>
22 #include <tools/debug.hxx>
23 #include <com/sun/star/sdbc/XDatabaseMetaData.hpp>
24 #include <com/sun/star/sdbcx/XColumnsSupplier.hpp>
25 #include <com/sun/star/sdbcx/XAlterTable.hpp>
26 #include <com/sun/star/sdbcx/XDrop.hpp>
27 #include <com/sun/star/sdbcx/XAppend.hpp>
28 #include <com/sun/star/beans/PropertyAttribute.hpp>
29 #include <com/sun/star/util/XNumberFormatTypes.hpp>
30 #include "dbu_tbl.hrc"
31 #include "dbustrings.hrc"
32 #include "browserids.hxx"
33 #include "dbaccess_helpid.hrc"
34 #include <comphelper/types.hxx>
35 #include "FieldDescControl.hxx"
36 #include "FieldDescriptions.hxx"
37 #include <vcl/msgbox.hxx>
38 #include "TableUndo.hxx"
39 #include "TableController.hxx"
40 #include <connectivity/dbtools.hxx>
41 #include "SqlNameEdit.hxx"
42 #include "TableRowExchange.hxx"
43 #include <sot/storage.hxx>
44 #include "UITools.hxx"
45 #include "TableFieldControl.hxx"
46 #include "dsntypes.hxx"
48 #include "dbaccess_slotid.hrc"
50 using namespace ::dbaui
;
51 using namespace ::comphelper
;
52 using namespace ::svt
;
53 using namespace ::com::sun::star::uno
;
54 using namespace ::com::sun::star::container
;
55 using namespace ::com::sun::star::io
;
56 using namespace ::com::sun::star::beans
;
57 using namespace ::com::sun::star::frame
;
58 using namespace ::com::sun::star::util
;
59 using namespace ::com::sun::star::lang
;
60 using namespace ::com::sun::star::sdbc
;
61 using namespace ::com::sun::star::sdbcx
;
62 using namespace ::com::sun::star::sdb
;
66 extern String
GetTypeString( sal_uInt16 nType
);
68 //==============================================================================
70 // TYPEINIT1(OTableEditorCtrl, DBView);
71 DBG_NAME(OTableEditorCtrl
)
73 //==============================================================================
77 // default field widths
78 #define FIELDNAME_WIDTH 100
79 #define FIELDTYPE_WIDTH 150
80 #define FIELDDESCR_WIDTH 300
82 // Maximum length in description field
83 #define MAX_DESCR_LEN 256
85 //==================================================================
86 DBG_NAME(ClipboardInvalidator
)
87 //------------------------------------------------------------------
88 OTableEditorCtrl::ClipboardInvalidator::ClipboardInvalidator(sal_uLong nTimeout
,OTableEditorCtrl
* _pOwner
)
91 DBG_CTOR(ClipboardInvalidator
,NULL
);
93 m_aInvalidateTimer
.SetTimeout(nTimeout
);
94 m_aInvalidateTimer
.SetTimeoutHdl(LINK(this, OTableEditorCtrl::ClipboardInvalidator
, OnInvalidate
));
95 m_aInvalidateTimer
.Start();
98 //------------------------------------------------------------------
99 OTableEditorCtrl::ClipboardInvalidator::~ClipboardInvalidator()
101 m_aInvalidateTimer
.Stop();
103 DBG_DTOR(ClipboardInvalidator
,NULL
);
106 //------------------------------------------------------------------
107 IMPL_LINK_NOARG(OTableEditorCtrl::ClipboardInvalidator
, OnInvalidate
)
109 m_pOwner
->GetView()->getController().InvalidateFeature(SID_CUT
);
110 m_pOwner
->GetView()->getController().InvalidateFeature(SID_COPY
);
111 m_pOwner
->GetView()->getController().InvalidateFeature(SID_PASTE
);
115 //==================================================================
116 void OTableEditorCtrl::Init()
118 DBG_CHKTHIS(OTableEditorCtrl
,NULL
);
119 OTableRowView::Init();
121 //////////////////////////////////////////////////////////////////////
122 // Should it be opened ReadOnly ?
123 sal_Bool
bRead(GetView()->getController().isReadOnly());
125 SetReadOnly( bRead
);
127 //////////////////////////////////////////////////////////////////////
128 // Insert the columns
129 String
aColumnName( ModuleRes(STR_TAB_FIELD_COLUMN_NAME
) );
130 InsertDataColumn( FIELD_NAME
, aColumnName
, FIELDNAME_WIDTH
);
132 aColumnName
= String( ModuleRes(STR_TAB_FIELD_COLUMN_DATATYPE
) );
133 InsertDataColumn( FIELD_TYPE
, aColumnName
, FIELDTYPE_WIDTH
);
135 ::dbaccess::ODsnTypeCollection
aDsnTypes(GetView()->getController().getORB());
136 sal_Bool bShowColumnDescription
= aDsnTypes
.supportsColumnDescription(::comphelper::getString(GetView()->getController().getDataSource()->getPropertyValue(PROPERTY_URL
)));
137 aColumnName
= String( ModuleRes(STR_TAB_HELP_TEXT
) );
138 InsertDataColumn( HELP_TEXT
, aColumnName
, bShowColumnDescription
? FIELDTYPE_WIDTH
: FIELDDESCR_WIDTH
);
140 if ( bShowColumnDescription
)
142 aColumnName
= String( ModuleRes(STR_COLUMN_DESCRIPTION
) );
143 InsertDataColumn( COLUMN_DESCRIPTION
, aColumnName
, FIELDTYPE_WIDTH
);
146 InitCellController();
148 //////////////////////////////////////////////////////////////////////
150 RowInserted(0, m_pRowList
->size(), sal_True
);
153 //==================================================================
154 void OTableEditorCtrl::UpdateAll()
156 DBG_CHKTHIS(OTableEditorCtrl
,NULL
);
157 RowRemoved(0, GetRowCount(), sal_False
);
160 InvalidateFeatures();
163 //==================================================================
164 OTableEditorCtrl::OTableEditorCtrl(Window
* pWindow
)
165 :OTableRowView(pWindow
)
176 ,nInvalidateTypeEvent(0)
179 ,bSaveOnMove(sal_True
)
181 ,m_aInvalidate(500,this)
183 DBG_CTOR(OTableEditorCtrl
,NULL
);
185 SetHelpId(HID_TABDESIGN_BACKGROUND
);
186 GetDataWindow().SetHelpId(HID_CTL_TABLEEDIT
);
188 m_pRowList
= GetView()->getController().getRows();
192 //------------------------------------------------------------------------------
193 SfxUndoManager
& OTableEditorCtrl::GetUndoManager() const
195 return GetView()->getController().GetUndoManager();
198 //------------------------------------------------------------------------------
199 sal_Bool
OTableEditorCtrl::IsReadOnly()
201 DBG_CHKTHIS(OTableEditorCtrl
,NULL
);
205 //------------------------------------------------------------------------------
206 void OTableEditorCtrl::SetReadOnly( sal_Bool bRead
)
209 if (bRead
== IsReadOnly())
210 // This check is important, as the underlying Def may be unnecessarily locked or unlocked
211 // or worse, this action may not be reversed afterwards
214 DBG_CHKTHIS(OTableEditorCtrl
,NULL
);
217 //////////////////////////////////////////////////////////////////////
218 // Disable active cells
219 long nRow(GetCurRow());
220 sal_uInt16
nCol(GetCurColumnId());
223 //////////////////////////////////////////////////////////////////////
224 // Select the correct Browsers cursor
225 BrowserMode
nMode(BROWSER_COLUMNSELECTION
| BROWSER_MULTISELECTION
| BROWSER_KEEPSELECTION
|
226 BROWSER_HLINESFULL
| BROWSER_VLINESFULL
|BROWSER_AUTOSIZE_LASTCOL
);
228 nMode
|= BROWSER_HIDECURSOR
;
232 ActivateCell( nRow
, nCol
);
235 //------------------------------------------------------------------------------
236 void OTableEditorCtrl::InitCellController()
238 DBG_CHKTHIS(OTableEditorCtrl
,NULL
);
239 //////////////////////////////////////////////////////////////////////
241 xub_StrLen nMaxTextLen
= EDIT_NOLIMIT
;
242 OUString sExtraNameChars
;
243 Reference
<XConnection
> xCon
;
246 xCon
= GetView()->getController().getConnection();
247 Reference
< XDatabaseMetaData
> xMetaData
= xCon
.is() ? xCon
->getMetaData() : Reference
< XDatabaseMetaData
>();
249 nMaxTextLen
= ((xub_StrLen
)xMetaData
.is() ? static_cast<xub_StrLen
>(xMetaData
->getMaxColumnNameLength()) : 0);
251 if( nMaxTextLen
== 0 )
252 nMaxTextLen
= EDIT_NOLIMIT
;
253 sExtraNameChars
= xMetaData
.is() ? xMetaData
->getExtraNameCharacters() : OUString();
258 OSL_FAIL("getMaxColumnNameLength");
261 pNameCell
= new OSQLNameEdit( &GetDataWindow(), sExtraNameChars
,WB_LEFT
);
262 pNameCell
->SetMaxTextLen( nMaxTextLen
);
263 pNameCell
->setCheck( isSQL92CheckEnabled(xCon
) );
266 //////////////////////////////////////////////////////////////////////
268 pTypeCell
= new ListBoxControl( &GetDataWindow() );
269 pTypeCell
->SetDropDownLineCount( 15 );
271 //////////////////////////////////////////////////////////////////////
273 pDescrCell
= new Edit( &GetDataWindow(), WB_LEFT
);
274 pDescrCell
->SetMaxTextLen( MAX_DESCR_LEN
);
276 pHelpTextCell
= new Edit( &GetDataWindow(), WB_LEFT
);
277 pHelpTextCell
->SetMaxTextLen( MAX_DESCR_LEN
);
279 pNameCell
->SetHelpId(HID_TABDESIGN_NAMECELL
);
280 pTypeCell
->SetHelpId(HID_TABDESIGN_TYPECELL
);
281 pDescrCell
->SetHelpId(HID_TABDESIGN_COMMENTCELL
);
282 pHelpTextCell
->SetHelpId(HID_TABDESIGN_HELPTEXT
);
285 const Control
* pControls
[] = { pTypeCell
,pDescrCell
,pNameCell
,pHelpTextCell
};
286 for(sal_Size i
= 0; i
< sizeof(pControls
) / sizeof(pControls
[0]);++i
)
288 const Size
aTemp(pControls
[i
]->GetOptimalSize());
289 if ( aTemp
.Height() > aHeight
.Height() )
290 aHeight
.Height() = aTemp
.Height();
292 SetDataRowHeight(aHeight
.Height());
297 //------------------------------------------------------------------------------
298 void OTableEditorCtrl::ClearModified()
300 DBG_CHKTHIS(OTableEditorCtrl
,NULL
);
301 pNameCell
->ClearModifyFlag();
302 pDescrCell
->ClearModifyFlag();
303 pHelpTextCell
->ClearModifyFlag();
304 pTypeCell
->SaveValue();
307 //------------------------------------------------------------------------------
308 OTableEditorCtrl::~OTableEditorCtrl()
310 DBG_DTOR(OTableEditorCtrl
,NULL
);
311 //////////////////////////////////////////////////////////////////////
312 // Reset the Undo-Manager
313 GetUndoManager().Clear();
315 //////////////////////////////////////////////////////////////////////
316 // Take possible Events from the queue
318 Application::RemoveUserEvent( nCutEvent
);
320 Application::RemoveUserEvent( nPasteEvent
);
322 Application::RemoveUserEvent( nDeleteEvent
);
323 if( nInsNewRowsEvent
)
324 Application::RemoveUserEvent( nInsNewRowsEvent
);
325 if( nInvalidateTypeEvent
)
326 Application::RemoveUserEvent( nInvalidateTypeEvent
);
328 //////////////////////////////////////////////////////////////////////
329 // Delete the control types
333 delete pHelpTextCell
;
336 //------------------------------------------------------------------------------
337 sal_Bool
OTableEditorCtrl::SetDataPtr( long nRow
)
339 DBG_CHKTHIS(OTableEditorCtrl
,NULL
);
343 OSL_ENSURE((xub_StrLen
)nRow
< m_pRowList
->size(),"Row is greater than size!");
344 if(nRow
>= (long)m_pRowList
->size())
346 pActRow
= (*m_pRowList
)[nRow
];
347 return pActRow
!= NULL
;
350 //------------------------------------------------------------------------------
351 sal_Bool
OTableEditorCtrl::SeekRow(long _nRow
)
353 // Call the Base class to remember which row must be repainted
354 EditBrowseBox::SeekRow(_nRow
);
356 DBG_CHKTHIS(OTableEditorCtrl
,NULL
);
357 m_nCurrentPos
= _nRow
;
358 return SetDataPtr(_nRow
);
361 //------------------------------------------------------------------------------
362 void OTableEditorCtrl::PaintCell(OutputDevice
& rDev
, const Rectangle
& rRect
,
363 sal_uInt16 nColumnId
) const
365 DBG_CHKTHIS(OTableEditorCtrl
,NULL
);
366 const String
aText( GetCellText( m_nCurrentPos
, nColumnId
));
368 rDev
.Push( PUSH_CLIPREGION
);
369 rDev
.SetClipRegion(Region(rRect
));
370 rDev
.DrawText( rRect
, aText
, TEXT_DRAW_LEFT
| TEXT_DRAW_VCENTER
);
374 //------------------------------------------------------------------------------
375 CellController
* OTableEditorCtrl::GetController(long nRow
, sal_uInt16 nColumnId
)
377 DBG_CHKTHIS(OTableEditorCtrl
,NULL
);
378 //////////////////////////////////////////////////////////////////////
379 // If EditorCtrl is ReadOnly, editing is forbidden
380 Reference
<XPropertySet
> xTable
= GetView()->getController().getTable();
381 if (IsReadOnly() || ( xTable
.is() &&
382 xTable
->getPropertySetInfo()->hasPropertyByName(PROPERTY_TYPE
) &&
383 ::comphelper::getString(xTable
->getPropertyValue(PROPERTY_TYPE
)) == OUString("VIEW")))
386 //////////////////////////////////////////////////////////////////////
387 // If the row is ReadOnly, editing is forbidden
389 if( pActRow
->IsReadOnly() )
392 OFieldDescription
* pActFieldDescr
= pActRow
->GetActFieldDescr();
396 return new EditCellController( pNameCell
);
398 if (pActFieldDescr
&& !pActFieldDescr
->GetName().isEmpty())
399 return new ListBoxCellController( pTypeCell
);
402 if (pActFieldDescr
&& !pActFieldDescr
->GetName().isEmpty())
403 return new EditCellController( pHelpTextCell
);
406 case COLUMN_DESCRIPTION
:
407 if (pActFieldDescr
&& !pActFieldDescr
->GetName().isEmpty())
408 return new EditCellController( pDescrCell
);
416 //------------------------------------------------------------------------------
417 void OTableEditorCtrl::InitController(CellControllerRef
&, long nRow
, sal_uInt16 nColumnId
)
419 DBG_CHKTHIS(OTableEditorCtrl
,NULL
);
420 SeekRow( nRow
== -1 ? GetCurRow() : nRow
);
421 OFieldDescription
* pActFieldDescr
= pActRow
->GetActFieldDescr();
428 aInitString
= pActFieldDescr
->GetName();
429 pNameCell
->SetText( aInitString
);
430 pNameCell
->SaveValue();
434 if ( pActFieldDescr
&& pActFieldDescr
->getTypeInfo() )
435 aInitString
= pActFieldDescr
->getTypeInfo()->aUIName
;
437 //////////////////////////////////////////////////////////////
438 // Set the ComboBox contents
440 if( !pActFieldDescr
)
443 const OTypeInfoMap
* pTypeInfo
= GetView()->getController().getTypeInfo();
444 OTypeInfoMap::const_iterator aIter
= pTypeInfo
->begin();
445 OTypeInfoMap::const_iterator aEnd
= pTypeInfo
->end();
446 for(;aIter
!= aEnd
;++aIter
)
447 pTypeCell
->InsertEntry( aIter
->second
->aUIName
);
448 pTypeCell
->SelectEntry( aInitString
);
454 aInitString
= pActFieldDescr
->GetHelpText();
455 pHelpTextCell
->SetText( aInitString
);
456 pHelpTextCell
->SaveValue();
458 case COLUMN_DESCRIPTION
:
460 aInitString
= pActFieldDescr
->GetDescription();
461 pDescrCell
->SetText( aInitString
);
462 pDescrCell
->SaveValue();
468 //------------------------------------------------------------------------------
469 EditBrowseBox::RowStatus
OTableEditorCtrl::GetRowStatus(long nRow
) const
471 DBG_CHKTHIS(OTableEditorCtrl
,NULL
);
472 const_cast<OTableEditorCtrl
*>(this)->SetDataPtr( nRow
);
474 return EditBrowseBox::CLEAN
;
475 if (nRow
>= 0 && nRow
== m_nDataPos
)
477 if( pActRow
->IsPrimaryKey() )
478 return EditBrowseBox::CURRENT_PRIMARYKEY
;
479 return EditBrowseBox::CURRENT
;
483 if( pActRow
->IsPrimaryKey() )
484 return EditBrowseBox::PRIMARYKEY
;
485 return EditBrowseBox::CLEAN
;
489 //------------------------------------------------------------------------------
490 sal_Bool
OTableEditorCtrl::SaveCurRow()
492 DBG_CHKTHIS(OTableEditorCtrl
,NULL
);
493 if (GetFieldDescr(GetCurRow()) == NULL
)
494 // there is no data in the current row
499 SetDataPtr(GetCurRow());
500 pDescrWin
->SaveData( pActRow
->GetActFieldDescr() );
504 //------------------------------------------------------------------------------
505 void OTableEditorCtrl::DisplayData(long nRow
, sal_Bool bGrabFocus
)
507 // go to the correct cell
510 // Disable Edit-Mode temporarily
511 sal_Bool bWasEditing
= IsEditing();
515 CellControllerRef aTemp
;
516 InitController(aTemp
, nRow
, FIELD_NAME
);
517 InitController(aTemp
, nRow
, FIELD_TYPE
);
518 InitController(aTemp
, nRow
, COLUMN_DESCRIPTION
);
519 InitController(aTemp
, nRow
, HELP_TEXT
);
522 // Update the Description-Window
523 GetView()->GetDescWin()->DisplayData(GetFieldDescr(nRow
));
527 // and re-enable edit mode
528 if (bWasEditing
|| bGrabFocus
)
529 ActivateCell(nRow
, GetCurColumnId(), bGrabFocus
);
532 //------------------------------------------------------------------------------
533 void OTableEditorCtrl::CursorMoved()
535 DBG_CHKTHIS(OTableEditorCtrl
,NULL
);
536 //////////////////////////////////////////////////////////////////////
538 m_nDataPos
= GetCurRow();
539 if( m_nDataPos
!= nOldDataPos
&& m_nDataPos
!= -1)
541 CellControllerRef aTemp
;
542 InitController(aTemp
,m_nDataPos
,FIELD_NAME
);
543 InitController(aTemp
,m_nDataPos
,FIELD_TYPE
);
544 InitController(aTemp
,m_nDataPos
,COLUMN_DESCRIPTION
);
545 InitController(aTemp
,m_nDataPos
,HELP_TEXT
);
548 OTableRowView::CursorMoved();
551 //------------------------------------------------------------------------------
552 sal_Int32
OTableEditorCtrl::HasFieldName( const String
& rFieldName
)
554 DBG_CHKTHIS(OTableEditorCtrl
,NULL
);
556 Reference
<XConnection
> xCon
= GetView()->getController().getConnection();
557 Reference
< XDatabaseMetaData
> xMetaData
= xCon
.is() ? xCon
->getMetaData() : Reference
< XDatabaseMetaData
>();
559 ::comphelper::UStringMixEqual
bCase(xMetaData
.is() ? xMetaData
->supportsMixedCaseQuotedIdentifiers() : sal_True
);
561 ::std::vector
< ::boost::shared_ptr
<OTableRow
> >::iterator aIter
= m_pRowList
->begin();
562 ::std::vector
< ::boost::shared_ptr
<OTableRow
> >::iterator aEnd
= m_pRowList
->end();
563 OFieldDescription
* pFieldDescr
;
565 for(;aIter
!= aEnd
;++aIter
)
567 pFieldDescr
= (*aIter
)->GetActFieldDescr();
568 if( pFieldDescr
&& bCase(rFieldName
,pFieldDescr
->GetName()))
573 // --------------------------------------------------------------------------------------
574 sal_Bool
OTableEditorCtrl::SaveData(long nRow
, sal_uInt16 nColId
)
576 DBG_CHKTHIS(OTableEditorCtrl
,NULL
);
577 //////////////////////////////////////////////////////////////
578 // Store the cell content
579 SetDataPtr( nRow
== -1 ? GetCurRow() : nRow
);
580 OFieldDescription
* pActFieldDescr
= pActRow
->GetActFieldDescr();
584 //////////////////////////////////////////////////////////////
588 //////////////////////////////////////////////////////////////
589 // If there is no name, do nothing
590 String
aName(pNameCell
->GetText());
594 //////////////////////////////////////////////////////////////
595 // If FieldDescr exists, the field is deleted and the old content restored
598 GetUndoManager().AddUndoAction(new OTableEditorTypeSelUndoAct(this, nRow
, FIELD_TYPE
, pActFieldDescr
->getTypeInfo()));
599 SwitchType(TOTypeInfoSP());
600 pActFieldDescr
= pActRow
->GetActFieldDescr();
606 pActFieldDescr
->SetName( aName
);
607 pNameCell
->ClearModifyFlag();
612 //////////////////////////////////////////////////////////////
613 // Store the field type
617 //////////////////////////////////////////////////////////////
621 //////////////////////////////////////////////////////////////
622 // Wenn aktuelle Feldbeschreibung NULL, Default setzen
623 if( !pActFieldDescr
)
625 pHelpTextCell
->SetText(String());
626 pHelpTextCell
->ClearModifyFlag();
629 pActFieldDescr
->SetHelpText( pHelpTextCell
->GetText() );
632 case COLUMN_DESCRIPTION
:
634 //////////////////////////////////////////////////////////////
635 // Set the default if the field description is null
636 if( !pActFieldDescr
)
638 pDescrCell
->SetText(String());
639 pDescrCell
->ClearModifyFlag();
642 pActFieldDescr
->SetDescription( pDescrCell
->GetText() );
645 case FIELD_PROPERTY_DEFAULT
:
646 case FIELD_PROPERTY_REQUIRED
:
647 case FIELD_PROPERTY_TEXTLEN
:
648 case FIELD_PROPERTY_NUMTYPE
:
649 case FIELD_PROPERTY_AUTOINC
:
650 case FIELD_PROPERTY_LENGTH
:
651 case FIELD_PROPERTY_SCALE
:
652 case FIELD_PROPERTY_BOOL_DEFAULT
:
653 pDescrWin
->SaveData(pActFieldDescr
);
655 if ( FIELD_PROPERTY_AUTOINC
== nColId
&& pActFieldDescr
->IsAutoIncrement() )
657 OTableController
& rController
= GetView()->getController();
658 if ( rController
.isAutoIncrementPrimaryKey() )
660 pActFieldDescr
->SetPrimaryKey( true );
661 InvalidateHandleColumn();
670 //------------------------------------------------------------------------------
671 sal_Bool
OTableEditorCtrl::SaveModified()
673 DBG_CHKTHIS(OTableEditorCtrl
,NULL
);
674 sal_uInt16 nColId
= GetCurColumnId();
678 //////////////////////////////////////////////////////////////
682 //////////////////////////////////////////////////////////////////////
691 //------------------------------------------------------------------------------
692 sal_Bool
OTableEditorCtrl::CursorMoving(long nNewRow
, sal_uInt16 nNewCol
)
694 DBG_CHKTHIS(OTableEditorCtrl
,NULL
);
696 if (!EditBrowseBox::CursorMoving(nNewRow
, nNewCol
))
699 //////////////////////////////////////////////////////////////////////
700 // Called after SaveModified(), current row is still the old one
701 m_nDataPos
= nNewRow
;
702 nOldDataPos
= GetCurRow();
704 //////////////////////////////////////////////////////////////////////
706 InvalidateStatusCell( nOldDataPos
);
707 InvalidateStatusCell( m_nDataPos
);
709 //////////////////////////////////////////////////////////////////////
710 // Store the data from the Property window
711 if( SetDataPtr(nOldDataPos
) && pDescrWin
)
712 pDescrWin
->SaveData( pActRow
->GetActFieldDescr() );
714 //////////////////////////////////////////////////////////////////////
715 // Show new data in the Property window
716 if( SetDataPtr(m_nDataPos
) && pDescrWin
)
717 pDescrWin
->DisplayData( pActRow
->GetActFieldDescr() );
722 //------------------------------------------------------------------------------
723 IMPL_LINK( OTableEditorCtrl
, InvalidateFieldType
, void*, /*EMPTYTAG*/ )
725 DBG_CHKTHIS(OTableEditorCtrl
,NULL
);
726 nInvalidateTypeEvent
= 0;
727 Invalidate( GetFieldRectPixel(nOldDataPos
, FIELD_TYPE
) );
732 //------------------------------------------------------------------------------
733 void OTableEditorCtrl::CellModified( long nRow
, sal_uInt16 nColId
)
735 DBG_CHKTHIS(OTableEditorCtrl
,NULL
);
737 //////////////////////////////////////////////////////////////
738 // If the description is null, use the default
742 OFieldDescription
* pActFieldDescr
= pActRow
->GetActFieldDescr();
744 String sActionDescription
;
747 case FIELD_NAME
: sActionDescription
= String( ModuleRes( STR_CHANGE_COLUMN_NAME
) ); break;
748 case FIELD_TYPE
: sActionDescription
= String( ModuleRes( STR_CHANGE_COLUMN_TYPE
) ); break;
750 case COLUMN_DESCRIPTION
: sActionDescription
= String( ModuleRes( STR_CHANGE_COLUMN_DESCRIPTION
) ); break;
751 default: sActionDescription
= String( ModuleRes( STR_CHANGE_COLUMN_ATTRIBUTE
) ); break;
754 GetUndoManager().EnterListAction( sActionDescription
, String() );
757 const OTypeInfoMap
* pTypeInfoMap
= GetView()->getController().getTypeInfo();
758 if ( !pTypeInfoMap
->empty() )
760 OTypeInfoMap::const_iterator aTypeIter
= pTypeInfoMap
->find(DataType::VARCHAR
);
761 if ( aTypeIter
== pTypeInfoMap
->end() )
762 aTypeIter
= pTypeInfoMap
->begin();
763 pActRow
->SetFieldType( aTypeIter
->second
);
766 pActRow
->SetFieldType( GetView()->getController().getTypeInfoFallBack() );
768 nInvalidateTypeEvent
= Application::PostUserEvent( LINK(this, OTableEditorCtrl
, InvalidateFieldType
) );
769 pActFieldDescr
= pActRow
->GetActFieldDescr();
770 pDescrWin
->DisplayData( pActFieldDescr
);
771 GetUndoManager().AddUndoAction( new OTableEditorTypeSelUndoAct(this, nRow
, nColId
+1, TOTypeInfoSP()) );
774 if( nColId
!= FIELD_TYPE
)
775 GetUndoManager().AddUndoAction( new OTableDesignCellUndoAct(this, nRow
, nColId
) );
778 GetUndoManager().AddUndoAction(new OTableEditorTypeSelUndoAct(this, GetCurRow(), nColId
, GetFieldDescr(GetCurRow())->getTypeInfo()));
782 SaveData(nRow
,nColId
);
783 // SaveData could create a undo action as well
784 GetUndoManager().LeaveListAction();
786 CellControllerRef
xController(Controller());
788 xController
->SetModified();
790 //////////////////////////////////////////////////////////////////////
791 // Set the Modify flag
792 GetView()->getController().setModified( sal_True
);
793 InvalidateFeatures();
795 // -----------------------------------------------------------------------------
796 void OTableEditorCtrl::resetType()
798 sal_uInt16 nPos
= pTypeCell
->GetSelectEntryPos();
799 if(nPos
!= LISTBOX_ENTRY_NOTFOUND
)
800 SwitchType( GetView()->getController().getTypeInfo(nPos
) );
802 SwitchType(TOTypeInfoSP());
804 //------------------------------------------------------------------------------
805 void OTableEditorCtrl::CellModified()
807 DBG_CHKTHIS(OTableEditorCtrl
,NULL
);
808 CellModified( GetCurRow(), GetCurColumnId() );
810 // -----------------------------------------------------------------------------
811 void OTableEditorCtrl::InvalidateFeatures()
813 GetView()->getController().InvalidateFeature(SID_UNDO
);
814 GetView()->getController().InvalidateFeature(SID_REDO
);
815 GetView()->getController().InvalidateFeature(SID_SAVEDOC
);
817 //------------------------------------------------------------------------------
818 void OTableEditorCtrl::Undo()
820 DBG_CHKTHIS(OTableEditorCtrl
,NULL
);
822 InvalidateFeatures();
824 //------------------------------------------------------------------------------
825 void OTableEditorCtrl::Redo()
827 DBG_CHKTHIS(OTableEditorCtrl
,NULL
);
828 InvalidateFeatures();
831 //------------------------------------------------------------------------------
832 void OTableEditorCtrl::CopyRows()
834 DBG_CHKTHIS(OTableEditorCtrl
,NULL
);
835 //////////////////////////////////////////////////////////////////////
836 // set to the right row and save it
837 if( SetDataPtr(m_nDataPos
) )
838 pDescrWin
->SaveData( pActRow
->GetActFieldDescr() );
840 //////////////////////////////////////////////////////////////////////
841 // Copy selected rows to the ClipboardList
842 ::boost::shared_ptr
<OTableRow
> pClipboardRow
;
843 ::boost::shared_ptr
<OTableRow
> pRow
;
844 ::std::vector
< ::boost::shared_ptr
<OTableRow
> > vClipboardList
;
845 vClipboardList
.reserve(GetSelectRowCount());
847 for( long nIndex
=FirstSelectedRow(); nIndex
>= 0 && nIndex
< static_cast<long>(m_pRowList
->size()); nIndex
=NextSelectedRow() )
849 pRow
= (*m_pRowList
)[nIndex
];
850 OSL_ENSURE(pRow
,"OTableEditorCtrl::CopyRows: Row is NULL!");
851 if ( pRow
&& pRow
->GetActFieldDescr() )
853 pClipboardRow
.reset(new OTableRow( *pRow
));
854 vClipboardList
.push_back( pClipboardRow
);
857 if(!vClipboardList
.empty())
859 OTableRowExchange
* pData
= new OTableRowExchange(vClipboardList
);
860 Reference
< ::com::sun::star::datatransfer::XTransferable
> xRef
= pData
;
861 pData
->CopyToClipboard(GetParent());
865 //------------------------------------------------------------------------------
866 String
OTableEditorCtrl::GenerateName( const String
& rName
)
868 DBG_CHKTHIS(OTableEditorCtrl
,NULL
);
869 //////////////////////////////////////////////////////////////////////
870 // Create a base name for appending numbers to
872 Reference
<XConnection
> xCon
= GetView()->getController().getConnection();
873 Reference
< XDatabaseMetaData
> xMetaData
= xCon
.is() ? xCon
->getMetaData() : Reference
< XDatabaseMetaData
>();
875 xub_StrLen
nMaxTextLen((xub_StrLen
)( xMetaData
.is() ? xMetaData
->getMaxColumnNameLength() : 0));
877 if( (rName
.Len()+2) >nMaxTextLen
)
878 aBaseName
= rName
.Copy( 0, nMaxTextLen
-2 );
882 //////////////////////////////////////////////////////////////////////
883 // append a sequential number to the base name (up to 99)
884 String
aFieldName( rName
);
886 while( HasFieldName(aFieldName
) )
888 aFieldName
= aBaseName
+ OUString::number(i
);
895 //------------------------------------------------------------------------------
896 void OTableEditorCtrl::InsertRows( long nRow
)
898 DBG_CHKTHIS(OTableEditorCtrl
,NULL
);
900 ::std::vector
< ::boost::shared_ptr
<OTableRow
> > vInsertedUndoRedoRows
; // need for undo/redo handling
901 //////////////////////////////////////////////////////////////////////
902 // get rows from clipboard
903 TransferableDataHelper
aTransferData(TransferableDataHelper::CreateFromSystemClipboard(GetParent()));
904 if(aTransferData
.HasFormat(SOT_FORMATSTR_ID_SBA_TABED
))
906 SotStorageStreamRef aStreamRef
;
907 aTransferData
.GetSotStorageStream(SOT_FORMATSTR_ID_SBA_TABED
,aStreamRef
);
910 aStreamRef
->Seek(STREAM_SEEK_TO_BEGIN
);
911 aStreamRef
->ResetError();
912 long nInsertRow
= nRow
;
914 ::boost::shared_ptr
<OTableRow
> pRow
;
916 (*aStreamRef
) >> nSize
;
917 vInsertedUndoRedoRows
.reserve(nSize
);
918 for(sal_Int32 i
=0;i
< nSize
;++i
)
920 pRow
.reset(new OTableRow());
921 (*aStreamRef
) >> *pRow
;
922 pRow
->SetReadOnly( sal_False
);
923 sal_Int32 nType
= pRow
->GetActFieldDescr()->GetType();
924 if ( pRow
->GetActFieldDescr() )
925 pRow
->GetActFieldDescr()->SetType(GetView()->getController().getTypeInfoByType(nType
));
926 //////////////////////////////////////////////////////////////////////
927 // Adjust the field names
928 aFieldName
= GenerateName( pRow
->GetActFieldDescr()->GetName() );
929 pRow
->GetActFieldDescr()->SetName( aFieldName
);
930 pRow
->SetPos(nInsertRow
);
931 m_pRowList
->insert( m_pRowList
->begin()+nInsertRow
,pRow
);
932 vInsertedUndoRedoRows
.push_back(::boost::shared_ptr
<OTableRow
>(new OTableRow(*pRow
)));
937 //////////////////////////////////////////////////////////////////////
938 // RowInserted calls CursorMoved.
939 // The UI data should not be stored here.
940 bSaveOnMove
= sal_False
;
941 RowInserted( nRow
,vInsertedUndoRedoRows
.size(),sal_True
);
942 bSaveOnMove
= sal_True
;
944 //////////////////////////////////////////////////////////////////////
945 // Create the Undo-Action
946 GetUndoManager().AddUndoAction( new OTableEditorInsUndoAct(this, nRow
,vInsertedUndoRedoRows
) );
947 GetView()->getController().setModified( sal_True
);
948 InvalidateFeatures();
951 //------------------------------------------------------------------------------
952 void OTableEditorCtrl::DeleteRows()
954 DBG_CHKTHIS(OTableEditorCtrl
,NULL
);
955 OSL_ENSURE(GetView()->getController().isDropAllowed(),"Call of DeleteRows not valid here. Please check isDropAllowed!");
956 //////////////////////////////////////////////////////////////////////
957 // Create the Undo-Action
958 GetUndoManager().AddUndoAction( new OTableEditorDelUndoAct(this) );
961 //////////////////////////////////////////////////////////////////////
962 // Delete all marked rows
963 long nIndex
= FirstSelectedRow();
964 nOldDataPos
= nIndex
;
965 bSaveOnMove
= sal_False
;
967 while( nIndex
>= 0 && nIndex
< static_cast<long>(m_pRowList
->size()) )
969 //////////////////////////////////////////////////////////////////////
971 m_pRowList
->erase( m_pRowList
->begin()+nIndex
);
972 RowRemoved( nIndex
, 1, sal_True
);
974 //////////////////////////////////////////////////////////////////////
975 // Insert the empty row at the end
976 m_pRowList
->push_back( ::boost::shared_ptr
<OTableRow
>(new OTableRow()));
977 RowInserted( GetRowCount()-1, 1, sal_True
);
979 nIndex
= FirstSelectedRow();
982 bSaveOnMove
= sal_True
;
984 //////////////////////////////////////////////////////////////////////
985 // Force the current record to be displayed
986 m_nDataPos
= GetCurRow();
987 InvalidateStatusCell( nOldDataPos
);
988 InvalidateStatusCell( m_nDataPos
);
989 SetDataPtr( m_nDataPos
);
991 pDescrWin
->DisplayData( pActRow
->GetActFieldDescr() );
992 GetView()->getController().setModified( sal_True
);
993 InvalidateFeatures();
996 //------------------------------------------------------------------------------
997 void OTableEditorCtrl::InsertNewRows( long nRow
)
999 DBG_CHKTHIS(OTableEditorCtrl
,NULL
);
1000 OSL_ENSURE(GetView()->getController().isAddAllowed(),"Call of InsertNewRows not valid here. Please check isAppendAllowed!");
1001 //////////////////////////////////////////////////////////////////////
1002 // Create Undo-Action
1003 long nInsertRows
= GetSelectRowCount();
1006 GetUndoManager().AddUndoAction( new OTableEditorInsNewUndoAct(this, nRow
, nInsertRows
) );
1007 //////////////////////////////////////////////////////////////////////
1008 // Insert the number of of selected rows
1009 for( long i
=nRow
; i
<(nRow
+nInsertRows
); i
++ )
1010 m_pRowList
->insert( m_pRowList
->begin()+i
,::boost::shared_ptr
<OTableRow
>(new OTableRow()));
1011 RowInserted( nRow
, nInsertRows
, sal_True
);
1013 GetView()->getController().setModified( sal_True
);
1014 InvalidateFeatures();
1017 //------------------------------------------------------------------------------
1018 String
OTableEditorCtrl::GetControlText( long nRow
, sal_uInt16 nColId
)
1020 DBG_CHKTHIS(OTableEditorCtrl
,NULL
);
1021 //////////////////////////////////////////////////////////////////////
1022 // Read the Browser Controls
1023 if( nColId
< FIELD_FIRST_VIRTUAL_COLUMN
)
1026 GoToColumnId( nColId
);
1027 CellControllerRef xController
= Controller();
1028 if(xController
.Is())
1029 return xController
->GetWindow().GetText();
1031 return GetCellText(nRow
,nColId
);
1034 //////////////////////////////////////////////////////////////////////
1035 // Read the Controls on the Tabpage
1037 return pDescrWin
->GetControlText( nColId
);
1040 //------------------------------------------------------------------------------
1041 void OTableEditorCtrl::SetControlText( long nRow
, sal_uInt16 nColId
, const String
& rText
)
1043 DBG_CHKTHIS(OTableEditorCtrl
,NULL
);
1044 //////////////////////////////////////////////////////////////////////
1045 // Set the Browser Controls
1046 if( nColId
< FIELD_FIRST_VIRTUAL_COLUMN
)
1049 GoToColumnId( nColId
);
1050 CellControllerRef xController
= Controller();
1051 if(xController
.Is())
1052 xController
->GetWindow().SetText( rText
);
1054 RowModified(nRow
,nColId
);
1057 //////////////////////////////////////////////////////////////////////
1058 // Set the Tabpage controls
1061 pDescrWin
->SetControlText( nColId
, rText
);
1064 //------------------------------------------------------------------------------
1065 void OTableEditorCtrl::SetCellData( long nRow
, sal_uInt16 nColId
, const TOTypeInfoSP
& _pTypeInfo
)
1067 DBG_CHKTHIS(OTableEditorCtrl
,NULL
);
1068 //////////////////////////////////////////////////////////////////////
1069 // Relocate the current pointer
1072 OFieldDescription
* pFieldDescr
= GetFieldDescr( nRow
);
1073 if( !pFieldDescr
&& nColId
!= FIELD_TYPE
)
1076 //////////////////////////////////////////////////////////////////////
1077 // Set individual fields
1081 SwitchType( _pTypeInfo
);
1084 OSL_FAIL("OTableEditorCtrl::SetCellData: invalid column!");
1086 SetControlText(nRow
,nColId
,_pTypeInfo
.get() ? _pTypeInfo
->aUIName
: OUString());
1088 //------------------------------------------------------------------------------
1089 void OTableEditorCtrl::SetCellData( long nRow
, sal_uInt16 nColId
, const ::com::sun::star::uno::Any
& _rNewData
)
1091 DBG_CHKTHIS(OTableEditorCtrl
,NULL
);
1092 //////////////////////////////////////////////////////////////////////
1093 // Relocate the current pointer
1096 OFieldDescription
* pFieldDescr
= GetFieldDescr( nRow
);
1097 if( !pFieldDescr
&& nColId
!= FIELD_TYPE
)
1101 //////////////////////////////////////////////////////////////////////
1102 // Set indvidual fields
1106 sValue
= ::comphelper::getString(_rNewData
);
1107 pFieldDescr
->SetName( sValue
);
1111 OSL_FAIL("OTableEditorCtrl::SetCellData: invalid column!");
1114 case COLUMN_DESCRIPTION
:
1115 pFieldDescr
->SetDescription( sValue
= ::comphelper::getString(_rNewData
) );
1118 case FIELD_PROPERTY_DEFAULT
:
1119 pFieldDescr
->SetControlDefault( _rNewData
);
1120 sValue
= GetView()->GetDescWin()->getGenPage()->getFieldControl()->getControlDefault(pFieldDescr
);
1123 case FIELD_PROPERTY_REQUIRED
:
1125 sValue
= ::comphelper::getString(_rNewData
);
1126 pFieldDescr
->SetIsNullable( sValue
.ToInt32() );
1130 case FIELD_PROPERTY_TEXTLEN
:
1131 case FIELD_PROPERTY_LENGTH
:
1133 sValue
= ::comphelper::getString(_rNewData
);
1134 pFieldDescr
->SetPrecision( sValue
.ToInt32() );
1138 case FIELD_PROPERTY_NUMTYPE
:
1139 OSL_FAIL("OTableEditorCtrl::SetCellData: invalid column!");
1142 case FIELD_PROPERTY_AUTOINC
:
1144 String
strYes(ModuleRes(STR_VALUE_YES
));
1145 sValue
= ::comphelper::getString(_rNewData
);
1146 pFieldDescr
->SetAutoIncrement(sValue
.Equals(strYes
));
1149 case FIELD_PROPERTY_SCALE
:
1151 sValue
= ::comphelper::getString(_rNewData
);
1152 pFieldDescr
->SetScale(sValue
.ToInt32());
1156 case FIELD_PROPERTY_BOOL_DEFAULT
:
1157 sValue
= GetView()->GetDescWin()->BoolStringPersistent(::comphelper::getString(_rNewData
));
1158 pFieldDescr
->SetControlDefault(makeAny(OUString(sValue
)));
1161 case FIELD_PROPERTY_FORMAT
:
1163 sValue
= ::comphelper::getString(_rNewData
);
1164 pFieldDescr
->SetFormatKey(sValue
.ToInt32());
1169 SetControlText(nRow
,nColId
,sValue
);
1172 //------------------------------------------------------------------------------
1173 Any
OTableEditorCtrl::GetCellData( long nRow
, sal_uInt16 nColId
)
1175 DBG_CHKTHIS(OTableEditorCtrl
,NULL
);
1176 OFieldDescription
* pFieldDescr
= GetFieldDescr( nRow
);
1180 //////////////////////////////////////////////////////////////////////
1181 // Relocate the current pointer
1186 static const String
strYes(ModuleRes(STR_VALUE_YES
));
1187 static const String
strNo(ModuleRes(STR_VALUE_NO
));
1189 //////////////////////////////////////////////////////////////////////
1190 // Read out the fields
1194 sValue
= pFieldDescr
->GetName();
1198 if ( pFieldDescr
->getTypeInfo() )
1199 sValue
= pFieldDescr
->getTypeInfo()->aUIName
;
1202 case COLUMN_DESCRIPTION
:
1203 sValue
= pFieldDescr
->GetDescription();
1206 sValue
= pFieldDescr
->GetHelpText();
1209 case FIELD_PROPERTY_DEFAULT
:
1210 return pFieldDescr
->GetControlDefault();
1212 case FIELD_PROPERTY_REQUIRED
:
1213 sValue
= pFieldDescr
->GetIsNullable() == ColumnValue::NULLABLE
? strYes
: strNo
;
1216 case FIELD_PROPERTY_TEXTLEN
:
1217 case FIELD_PROPERTY_LENGTH
:
1218 sValue
= OUString::number(pFieldDescr
->GetPrecision());
1221 case FIELD_PROPERTY_NUMTYPE
:
1222 OSL_FAIL("OTableEditorCtrl::GetCellData: invalid column!");
1225 case FIELD_PROPERTY_AUTOINC
:
1226 sValue
= pFieldDescr
->IsAutoIncrement() ? strYes
: strNo
;
1229 case FIELD_PROPERTY_SCALE
:
1230 sValue
= OUString::number(pFieldDescr
->GetScale());
1233 case FIELD_PROPERTY_BOOL_DEFAULT
:
1234 sValue
= GetView()->GetDescWin()->BoolStringUI(::comphelper::getString(pFieldDescr
->GetControlDefault()));
1237 case FIELD_PROPERTY_FORMAT
:
1238 sValue
= OUString::number(pFieldDescr
->GetFormatKey());
1242 return makeAny(sValue
);
1245 //------------------------------------------------------------------------------
1246 String
OTableEditorCtrl::GetCellText( long nRow
, sal_uInt16 nColId
) const
1248 DBG_CHKTHIS(OTableEditorCtrl
,NULL
);
1250 const_cast< OTableEditorCtrl
* >( this )->GetCellData( nRow
, nColId
) >>= sCellText
;
1254 //------------------------------------------------------------------------------
1255 sal_uInt32
OTableEditorCtrl::GetTotalCellWidth(long nRow
, sal_uInt16 nColId
)
1257 DBG_CHKTHIS(OTableEditorCtrl
,NULL
);
1258 return GetTextWidth(GetCellText(nRow
, nColId
)) + 2 * GetTextWidth(OUString('0'));
1261 //------------------------------------------------------------------------------
1262 OFieldDescription
* OTableEditorCtrl::GetFieldDescr( long nRow
)
1264 DBG_CHKTHIS(OTableEditorCtrl
,NULL
);
1265 std::vector
< ::boost::shared_ptr
<OTableRow
> >::size_type
nListCount(
1266 m_pRowList
->size());
1267 if( (nRow
<0) || (sal::static_int_cast
< unsigned long >(nRow
)>=nListCount
) )
1269 OSL_FAIL("(nRow<0) || (nRow>=nListCount)");
1272 ::boost::shared_ptr
<OTableRow
> pRow
= (*m_pRowList
)[ nRow
];
1275 return pRow
->GetActFieldDescr();
1278 //------------------------------------------------------------------------------
1279 sal_Bool
OTableEditorCtrl::IsCutAllowed( long nRow
)
1281 DBG_CHKTHIS(OTableEditorCtrl
,NULL
);
1282 sal_Bool bIsCutAllowed
= (GetView()->getController().isAddAllowed() && GetView()->getController().isDropAllowed()) ||
1283 GetView()->getController().isAlterAllowed();
1287 switch(m_eChildFocus
)
1290 bIsCutAllowed
= !pDescrCell
->GetSelected().isEmpty();
1293 bIsCutAllowed
= !pHelpTextCell
->GetSelected().isEmpty();
1296 bIsCutAllowed
= !pNameCell
->GetSelected().isEmpty();
1299 bIsCutAllowed
= IsCopyAllowed(nRow
);
1302 bIsCutAllowed
= sal_False
;
1307 return bIsCutAllowed
;
1310 //------------------------------------------------------------------------------
1311 sal_Bool
OTableEditorCtrl::IsCopyAllowed( long /*nRow*/ )
1313 DBG_CHKTHIS(OTableEditorCtrl
,NULL
);
1314 sal_Bool bIsCopyAllowed
= sal_False
;
1315 if(m_eChildFocus
== DESCRIPTION
)
1316 bIsCopyAllowed
= !pDescrCell
->GetSelected().isEmpty();
1317 else if(HELPTEXT
== m_eChildFocus
)
1318 bIsCopyAllowed
= !pHelpTextCell
->GetSelected().isEmpty();
1319 else if(m_eChildFocus
== NAME
)
1320 bIsCopyAllowed
= !pNameCell
->GetSelected().isEmpty();
1321 else if(m_eChildFocus
== ROW
)
1323 Reference
<XPropertySet
> xTable
= GetView()->getController().getTable();
1324 if( !GetSelectRowCount() || (xTable
.is() && ::comphelper::getString(xTable
->getPropertyValue(PROPERTY_TYPE
)) == "VIEW"))
1327 //////////////////////////////////////////////////////////////////////
1328 // If one of the selected rows is empty, Copy is not possible
1329 ::boost::shared_ptr
<OTableRow
> pRow
;
1330 long nIndex
= FirstSelectedRow();
1331 while( nIndex
>= 0 && nIndex
< static_cast<long>(m_pRowList
->size()) )
1333 pRow
= (*m_pRowList
)[nIndex
];
1334 if( !pRow
->GetActFieldDescr() )
1337 nIndex
= NextSelectedRow();
1340 bIsCopyAllowed
= sal_True
;
1343 return bIsCopyAllowed
;
1346 //------------------------------------------------------------------------------
1347 sal_Bool
OTableEditorCtrl::IsPasteAllowed( long /*nRow*/ )
1349 DBG_CHKTHIS(OTableEditorCtrl
,NULL
);
1350 sal_Bool bAllowed
= GetView()->getController().isAddAllowed();
1353 TransferableDataHelper
aTransferData(TransferableDataHelper::CreateFromSystemClipboard(GetParent()));
1354 sal_Bool bRowFormat
= aTransferData
.HasFormat(SOT_FORMATSTR_ID_SBA_TABED
);
1355 if ( m_eChildFocus
== ROW
)
1356 bAllowed
= bRowFormat
;
1358 bAllowed
= !bRowFormat
&& aTransferData
.HasFormat(SOT_FORMAT_STRING
);
1364 //------------------------------------------------------------------------------
1365 void OTableEditorCtrl::cut()
1367 if(m_eChildFocus
== NAME
)
1369 if(GetView()->getController().isAlterAllowed())
1371 SaveData(-1,FIELD_NAME
);
1373 CellModified(-1,FIELD_NAME
);
1376 else if(m_eChildFocus
== DESCRIPTION
)
1378 if(GetView()->getController().isAlterAllowed())
1380 SaveData(-1,COLUMN_DESCRIPTION
);
1382 CellModified(-1,COLUMN_DESCRIPTION
);
1385 else if(HELPTEXT
== m_eChildFocus
)
1387 if(GetView()->getController().isAlterAllowed())
1389 SaveData(-1,HELP_TEXT
);
1390 pHelpTextCell
->Cut();
1391 CellModified(-1,HELP_TEXT
);
1394 else if(m_eChildFocus
== ROW
)
1397 Application::RemoveUserEvent(nCutEvent
);
1398 nCutEvent
= Application::PostUserEvent(LINK(this, OTableEditorCtrl
, DelayedCut
));
1402 //------------------------------------------------------------------------------
1403 void OTableEditorCtrl::copy()
1405 if(GetSelectRowCount())
1406 OTableRowView::copy();
1407 else if(m_eChildFocus
== NAME
)
1409 else if(HELPTEXT
== m_eChildFocus
)
1410 pHelpTextCell
->Copy();
1411 else if(m_eChildFocus
== DESCRIPTION
)
1415 //------------------------------------------------------------------------------
1416 void OTableEditorCtrl::paste()
1418 TransferableDataHelper
aTransferData(TransferableDataHelper::CreateFromSystemClipboard(GetParent()));
1419 if(aTransferData
.HasFormat(SOT_FORMATSTR_ID_SBA_TABED
))
1422 Application::RemoveUserEvent( nPasteEvent
);
1423 nPasteEvent
= Application::PostUserEvent( LINK(this, OTableEditorCtrl
, DelayedPaste
) );
1425 else if(m_eChildFocus
== NAME
)
1427 if(GetView()->getController().isAlterAllowed())
1433 else if(HELPTEXT
== m_eChildFocus
)
1435 if(GetView()->getController().isAlterAllowed())
1437 pHelpTextCell
->Paste();
1441 else if(m_eChildFocus
== DESCRIPTION
)
1443 if(GetView()->getController().isAlterAllowed())
1445 pDescrCell
->Paste();
1451 //------------------------------------------------------------------------------
1452 sal_Bool
OTableEditorCtrl::IsDeleteAllowed( long /*nRow*/ )
1454 DBG_CHKTHIS(OTableEditorCtrl
,NULL
);
1456 return GetSelectRowCount() != 0 && GetView()->getController().isDropAllowed();
1459 //------------------------------------------------------------------------------
1460 sal_Bool
OTableEditorCtrl::IsInsertNewAllowed( long nRow
)
1462 DBG_CHKTHIS(OTableEditorCtrl
,NULL
);
1464 sal_Bool bInsertNewAllowed
= GetView()->getController().isAddAllowed();
1465 //////////////////////////////////////////////////////////////
1466 // If fields can be added, Paste in the new fields
1467 if (bInsertNewAllowed
&& !GetView()->getController().isDropAllowed())
1470 if( GetActRow()->IsReadOnly() )
1474 return bInsertNewAllowed
;
1477 //------------------------------------------------------------------------------
1478 sal_Bool
OTableEditorCtrl::IsPrimaryKeyAllowed( long /*nRow*/ )
1480 DBG_CHKTHIS(OTableEditorCtrl
,NULL
);
1481 if( !GetSelectRowCount() )
1484 OTableController
& rController
= GetView()->getController();
1485 if ( !rController
.getSdbMetaData().supportsPrimaryKeys() )
1488 Reference
<XPropertySet
> xTable
= rController
.getTable();
1489 //////////////////////////////////////////////////////////////
1490 // Key must not be changed
1491 // This applies only if the table is not new and not a ::com::sun::star::sdbcx::View. Otherwise no DROP is executed
1493 if(xTable
.is() && ::comphelper::getString(xTable
->getPropertyValue(PROPERTY_TYPE
)) == "VIEW")
1495 //////////////////////////////////////////////////////////////
1496 // If there is an empty field, no primary key
1497 // The entry is only permitted if
1498 // - there are no empty entries in the selection
1499 // - No Memo or Image entries
1500 // - DROP is not permitted (see above) and the column is not Required (not null flag is not set).
1501 long nIndex
= FirstSelectedRow();
1502 ::boost::shared_ptr
<OTableRow
> pRow
;
1503 while( nIndex
>= 0 && nIndex
< static_cast<long>(m_pRowList
->size()) )
1505 pRow
= (*m_pRowList
)[nIndex
];
1506 OFieldDescription
* pFieldDescr
= pRow
->GetActFieldDescr();
1511 //////////////////////////////////////////////////////////////
1512 // Memo and Image fields cannot be primary keys
1513 // or if the columne cannot be dropped and the Required flag is not set
1514 // or if a ::com::sun::star::sdbcx::View is avalable and the Required flag is not set
1515 TOTypeInfoSP pTypeInfo
= pFieldDescr
->getTypeInfo();
1516 if( pTypeInfo
->nSearchType
== ColumnSearch::NONE
1517 || (pFieldDescr
->IsNullable() && pRow
->IsReadOnly())
1522 nIndex
= NextSelectedRow();
1528 //------------------------------------------------------------------------------
1529 void OTableEditorCtrl::Command(const CommandEvent
& rEvt
)
1531 DBG_CHKTHIS(OTableEditorCtrl
,NULL
);
1532 switch (rEvt
.GetCommand())
1534 case COMMAND_CONTEXTMENU
:
1536 Point
aMenuPos( rEvt
.GetMousePosPixel() );
1537 if (!rEvt
.IsMouseEvent())
1539 if ( 1 == GetSelectColumnCount() )
1541 sal_uInt16 nSelId
= GetColumnId(
1542 sal::static_int_cast
< sal_uInt16
>(
1543 FirstSelectedColumn() ) );
1544 ::Rectangle
aColRect( GetFieldRectPixel( 0, nSelId
, sal_False
) );
1546 aMenuPos
= aColRect
.TopCenter();
1548 else if ( GetSelectRowCount() > 0 )
1550 ::Rectangle
aColRect( GetFieldRectPixel( FirstSelectedRow(), HANDLE_ID
, sal_True
) );
1552 aMenuPos
= aColRect
.TopCenter();
1556 OTableRowView::Command(rEvt
);
1561 //////////////////////////////////////////////////////////////
1562 // Show the Context menu
1565 sal_uInt16 nColId
= GetColumnAtXPosPixel(aMenuPos
.X());
1566 long nRow
= GetRowAtYPosPixel(aMenuPos
.Y());
1568 if ( HANDLE_ID
!= nColId
)
1570 if ( nRow
< 0 && nColId
!= BROWSER_INVALIDID
)
1573 { // 3 would mean the last column, and this last column is auto-sized
1574 if ( !IsColumnSelected( nColId
) )
1575 SelectColumnId( nColId
);
1577 PopupMenu
aContextMenu( ModuleRes( RID_QUERYCOLPOPUPMENU
) );
1578 aContextMenu
.EnableItem( SID_DELETE
, sal_False
);
1579 aContextMenu
.RemoveDisabledEntries(sal_True
, sal_True
);
1580 switch ( aContextMenu
.Execute( this, aMenuPos
) )
1582 case ID_BROWSER_COLWIDTH
:
1583 adjustBrowseBoxColumnWidth( this, nColId
);
1591 PopupMenu
aContextMenu(ModuleRes(RID_TABLEDESIGNROWPOPUPMENU
));
1593 aContextMenu
.EnableItem( SID_CUT
, IsCutAllowed(nRow
) );
1594 aContextMenu
.EnableItem( SID_COPY
, IsCopyAllowed(nRow
) );
1595 aContextMenu
.EnableItem( SID_PASTE
, IsPasteAllowed(nRow
) );
1596 aContextMenu
.EnableItem( SID_DELETE
, IsDeleteAllowed(nRow
) );
1597 aContextMenu
.EnableItem( SID_TABLEDESIGN_TABED_PRIMARYKEY
, IsPrimaryKeyAllowed(nRow
) );
1598 aContextMenu
.EnableItem( SID_TABLEDESIGN_INSERTROWS
, IsInsertNewAllowed(nRow
) );
1599 aContextMenu
.CheckItem( SID_TABLEDESIGN_TABED_PRIMARYKEY
, IsRowSelected(GetCurRow()) && IsPrimaryKey() );
1601 // remove all the disable entries
1602 aContextMenu
.RemoveDisabledEntries(sal_True
, sal_True
);
1604 if( SetDataPtr(m_nDataPos
) )
1605 pDescrWin
->SaveData( pActRow
->GetActFieldDescr() );
1607 //////////////////////////////////////////////////////////////
1608 // All actions which change the number of rows must be run asynchronously
1609 // otherwise there may be problems between the Context menu and the Browser
1610 m_nDataPos
= GetCurRow();
1611 switch (aContextMenu
.Execute(this, aMenuPos
))
1624 Application::RemoveUserEvent( nDeleteEvent
);
1625 nDeleteEvent
= Application::PostUserEvent( LINK(this, OTableEditorCtrl
, DelayedDelete
) );
1627 case SID_TABLEDESIGN_INSERTROWS
:
1628 if( nInsNewRowsEvent
)
1629 Application::RemoveUserEvent( nInsNewRowsEvent
);
1630 nInsNewRowsEvent
= Application::PostUserEvent( LINK(this, OTableEditorCtrl
, DelayedInsNewRows
) );
1632 case SID_TABLEDESIGN_TABED_PRIMARYKEY
:
1633 SetPrimaryKey( !IsPrimaryKey() );
1643 OTableRowView::Command(rEvt
);
1648 //------------------------------------------------------------------------------
1649 IMPL_LINK( OTableEditorCtrl
, DelayedCut
, void*, /*EMPTYTAG*/ )
1652 OTableRowView::cut();
1656 //------------------------------------------------------------------------------
1657 IMPL_LINK( OTableEditorCtrl
, DelayedPaste
, void*, /*EMPTYTAG*/ )
1661 sal_Int32 nPastePosition
= GetView()->getController().getFirstEmptyRowPosition();
1662 if ( !GetView()->getController().getTable().is() )
1663 nPastePosition
= GetSelectRowCount() ? FirstSelectedRow() : GetCurRow();
1665 if (!IsInsertNewAllowed(nPastePosition
))
1666 { // Insertion is not allowed, only appending, so test if there are full cells after the PastePosition
1668 sal_Int32 nFreeFromPos
; // from here on there are only empty rows
1669 ::std::vector
< ::boost::shared_ptr
<OTableRow
> >::reverse_iterator aIter
= m_pRowList
->rbegin();
1670 for(nFreeFromPos
= m_pRowList
->size();
1671 aIter
!= m_pRowList
->rend() && (!(*aIter
) || !(*aIter
)->GetActFieldDescr() || (*aIter
)->GetActFieldDescr()->GetName().isEmpty());
1672 --nFreeFromPos
, ++aIter
)
1674 if (nPastePosition
< nFreeFromPos
) // if at least one PastePosition is full, go right to the end
1675 nPastePosition
= nFreeFromPos
;
1678 OTableRowView::Paste( nPastePosition
);
1680 GoToRow( nPastePosition
);
1685 //------------------------------------------------------------------------------
1686 IMPL_LINK( OTableEditorCtrl
, DelayedDelete
, void*, /*EMPTYTAG*/ )
1693 //------------------------------------------------------------------------------
1694 IMPL_LINK( OTableEditorCtrl
, DelayedInsNewRows
, void*, /*EMPTYTAG*/ )
1696 DBG_CHKTHIS(OTableEditorCtrl
,NULL
);
1697 nInsNewRowsEvent
= 0;
1698 sal_Int32 nPastePosition
= GetView()->getController().getFirstEmptyRowPosition();
1699 if ( !GetView()->getController().getTable().is() )
1700 nPastePosition
= GetSelectRowCount() ? FirstSelectedRow() : m_nDataPos
;
1702 InsertNewRows( nPastePosition
);
1704 GoToRow( nPastePosition
);
1708 // -----------------------------------------------------------------------------
1709 void OTableEditorCtrl::AdjustFieldDescription(OFieldDescription
* _pFieldDesc
,
1710 MultiSelection
& _rMultiSel
,
1713 sal_Bool _bPrimaryKey
)
1715 _pFieldDesc
->SetPrimaryKey( _bPrimaryKey
);
1716 if(!_bSet
&& _pFieldDesc
->getTypeInfo()->bNullable
)
1718 _pFieldDesc
->SetIsNullable(ColumnValue::NO_NULLS
);
1719 _pFieldDesc
->SetControlDefault(Any());
1721 if ( _pFieldDesc
->IsAutoIncrement() && !_bPrimaryKey
)
1723 OTableController
& rController
= GetView()->getController();
1724 if ( rController
.isAutoIncrementPrimaryKey() )
1726 _pFieldDesc
->SetAutoIncrement(false);
1729 //////////////////////////////////////////////////////////////////////
1730 // update field description
1731 pDescrWin
->DisplayData(_pFieldDesc
);
1733 _rMultiSel
.Insert( _nPos
);
1734 _rMultiSel
.Select( _nPos
);
1736 //------------------------------------------------------------------------------
1737 void OTableEditorCtrl::SetPrimaryKey( sal_Bool bSet
)
1739 DBG_CHKTHIS(OTableEditorCtrl
,NULL
);
1740 //////////////////////////////////////////////////////////////////////
1741 // Delete any existing Primary Keys
1742 MultiSelection aDeletedPrimKeys
;
1743 aDeletedPrimKeys
.SetTotalRange( Range(0,GetRowCount()) );
1745 ::std::vector
< ::boost::shared_ptr
<OTableRow
> >::const_iterator aIter
= m_pRowList
->begin();
1746 ::std::vector
< ::boost::shared_ptr
<OTableRow
> >::const_iterator aEnd
= m_pRowList
->end();
1747 for(sal_Int32 nRow
= 0;aIter
!= aEnd
;++aIter
,++nRow
)
1749 OFieldDescription
* pFieldDescr
= (*aIter
)->GetActFieldDescr();
1750 if( pFieldDescr
&& (*aIter
)->IsPrimaryKey() && (!bSet
|| !IsRowSelected(nRow
)) )
1752 AdjustFieldDescription(pFieldDescr
,aDeletedPrimKeys
,nRow
,bSet
,sal_False
);
1756 //////////////////////////////////////////////////////////////////////
1757 // Set the primary keys of the marked rows
1758 MultiSelection aInsertedPrimKeys
;
1759 aInsertedPrimKeys
.SetTotalRange( Range(0,GetRowCount()) );
1762 long nIndex
= FirstSelectedRow();
1763 while( nIndex
>= 0 && nIndex
< static_cast<long>(m_pRowList
->size()) )
1765 //////////////////////////////////////////////////////////////////////
1767 ::boost::shared_ptr
<OTableRow
> pRow
= (*m_pRowList
)[nIndex
];
1768 OFieldDescription
* pFieldDescr
= pRow
->GetActFieldDescr();
1770 AdjustFieldDescription(pFieldDescr
,aInsertedPrimKeys
,nIndex
,sal_False
,sal_True
);
1772 nIndex
= NextSelectedRow();
1776 GetUndoManager().AddUndoAction( new OPrimKeyUndoAct(this, aDeletedPrimKeys
, aInsertedPrimKeys
) );
1778 //////////////////////////////////////////////////////////////////////
1779 // Invalidate the handle-columns
1780 InvalidateHandleColumn();
1783 //////////////////////////////////////////////////////////////////////
1784 // Set the TableDocSh's ModifyFlag
1785 GetView()->getController().setModified( sal_True
);
1786 InvalidateFeatures();
1789 //------------------------------------------------------------------------------
1790 sal_Bool
OTableEditorCtrl::IsPrimaryKey()
1792 DBG_CHKTHIS(OTableEditorCtrl
,NULL
);
1793 //////////////////////////////////////////////////////////////////////
1794 // Are all marked fields part of the Primary Key ?
1795 long nPrimaryKeys
= 0;
1796 ::std::vector
< ::boost::shared_ptr
<OTableRow
> >::const_iterator aIter
= m_pRowList
->begin();
1797 ::std::vector
< ::boost::shared_ptr
<OTableRow
> >::const_iterator aEnd
= m_pRowList
->end();
1798 for(sal_Int32 nRow
=0;aIter
!= aEnd
;++aIter
,++nRow
)
1800 if( IsRowSelected(nRow
) && !(*aIter
)->IsPrimaryKey() )
1802 if( (*aIter
)->IsPrimaryKey() )
1806 //////////////////////////////////////////////////////////////////////
1807 // Are there any unselected fields that are part of the Key ?
1808 return GetSelectRowCount() == nPrimaryKeys
;
1811 //------------------------------------------------------------------------------
1812 void OTableEditorCtrl::SwitchType( const TOTypeInfoSP
& _pType
)
1814 DBG_CHKTHIS(OTableEditorCtrl
,NULL
);
1815 //////////////////////////////////////////////////////////////////////
1816 // if there is no assigned field name
1817 long nRow(GetCurRow());
1818 OFieldDescription
* pActFieldDescr
= GetFieldDescr( nRow
);
1819 if( pActFieldDescr
)
1820 //////////////////////////////////////////////////////////////////////
1821 // Store the old description
1822 pDescrWin
->SaveData( pActFieldDescr
);
1824 if ( nRow
< 0 || nRow
> static_cast<long>(m_pRowList
->size()) )
1826 //////////////////////////////////////////////////////////////////////
1827 // Show the new description
1828 ::boost::shared_ptr
<OTableRow
> pRow
= (*m_pRowList
)[nRow
];
1829 pRow
->SetFieldType( _pType
, sal_True
);
1832 const sal_uInt16 nCurrentlySelected
= pTypeCell
->GetSelectEntryPos();
1834 if ( ( LISTBOX_ENTRY_NOTFOUND
== nCurrentlySelected
)
1835 || ( GetView()->getController().getTypeInfo( nCurrentlySelected
) != _pType
)
1838 sal_uInt16 nEntryPos
= 0;
1839 const OTypeInfoMap
* pTypeInfo
= GetView()->getController().getTypeInfo();
1840 OTypeInfoMap::const_iterator aIter
= pTypeInfo
->begin();
1841 OTypeInfoMap::const_iterator aEnd
= pTypeInfo
->end();
1842 for(;aIter
!= aEnd
;++aIter
,++nEntryPos
)
1844 if(aIter
->second
== _pType
)
1847 if (nEntryPos
< pTypeCell
->GetEntryCount())
1848 pTypeCell
->SelectEntryPos( nEntryPos
);
1852 pActFieldDescr
= pRow
->GetActFieldDescr();
1853 if (pActFieldDescr
!= NULL
&& !pActFieldDescr
->GetFormatKey())
1855 sal_Int32 nFormatKey
= ::dbtools::getDefaultNumberFormat( pActFieldDescr
->GetType(),
1856 pActFieldDescr
->GetScale(),
1857 pActFieldDescr
->IsCurrency(),
1858 Reference
< XNumberFormatTypes
>(GetView()->getController().getNumberFormatter()->getNumberFormatsSupplier()->getNumberFormats(),UNO_QUERY
),
1859 GetView()->getLocale());
1861 pActFieldDescr
->SetFormatKey(nFormatKey
);
1864 pDescrWin
->DisplayData( pActFieldDescr
);
1866 // -----------------------------------------------------------------------------
1867 OTableDesignView
* OTableEditorCtrl::GetView() const
1869 return static_cast<OTableDesignView
*>(GetParent()->GetParent());
1871 // -----------------------------------------------------------------------------
1872 void OTableEditorCtrl::DeactivateCell(sal_Bool bUpdate
)
1874 OTableRowView::DeactivateCell(bUpdate
);
1875 // now we have to deactivate the field description
1876 long nRow(GetCurRow());
1878 pDescrWin
->SetReadOnly(bReadOnly
|| !SetDataPtr(nRow
) || GetActRow()->IsReadOnly());
1880 //------------------------------------------------------------------------------
1881 long OTableEditorCtrl::PreNotify( NotifyEvent
& rNEvt
)
1883 if (rNEvt
.GetType() == EVENT_GETFOCUS
)
1885 if( pHelpTextCell
&& pHelpTextCell
->HasChildPathFocus() )
1886 m_eChildFocus
= HELPTEXT
;
1887 else if( pDescrCell
&& pDescrCell
->HasChildPathFocus() )
1888 m_eChildFocus
= DESCRIPTION
;
1889 else if(pNameCell
&& pNameCell
->HasChildPathFocus() )
1890 m_eChildFocus
= NAME
;
1892 m_eChildFocus
= ROW
;
1895 return OTableRowView::PreNotify(rNEvt
);
1897 // -----------------------------------------------------------------------------
1902 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */