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
;
64 // TYPEINIT1(OTableEditorCtrl, DBView);
68 // default field widths
69 #define FIELDNAME_WIDTH 100
70 #define FIELDTYPE_WIDTH 150
71 #define FIELDDESCR_WIDTH 300
73 // Maximum length in description field
74 #define MAX_DESCR_LEN 256
76 OTableEditorCtrl::ClipboardInvalidator::ClipboardInvalidator(sal_uLong nTimeout
,OTableEditorCtrl
* _pOwner
)
80 m_aInvalidateTimer
.SetTimeout(nTimeout
);
81 m_aInvalidateTimer
.SetTimeoutHdl(LINK(this, OTableEditorCtrl::ClipboardInvalidator
, OnInvalidate
));
82 m_aInvalidateTimer
.Start();
85 OTableEditorCtrl::ClipboardInvalidator::~ClipboardInvalidator()
87 m_aInvalidateTimer
.Stop();
90 void OTableEditorCtrl::ClipboardInvalidator::Stop()
92 m_aInvalidateTimer
.Stop();
95 IMPL_LINK_NOARG_TYPED(OTableEditorCtrl::ClipboardInvalidator
, OnInvalidate
, Timer
*, void)
97 m_pOwner
->GetView()->getController().InvalidateFeature(SID_CUT
);
98 m_pOwner
->GetView()->getController().InvalidateFeature(SID_COPY
);
99 m_pOwner
->GetView()->getController().InvalidateFeature(SID_PASTE
);
102 void OTableEditorCtrl::Init()
104 OTableRowView::Init();
106 // Should it be opened ReadOnly?
107 bool bRead(GetView()->getController().isReadOnly());
109 SetReadOnly( bRead
);
111 // Insert the columns
112 OUString
aColumnName( ModuleRes(STR_TAB_FIELD_COLUMN_NAME
) );
113 InsertDataColumn( FIELD_NAME
, aColumnName
, FIELDNAME_WIDTH
);
115 aColumnName
= ModuleRes(STR_TAB_FIELD_COLUMN_DATATYPE
);
116 InsertDataColumn( FIELD_TYPE
, aColumnName
, FIELDTYPE_WIDTH
);
118 ::dbaccess::ODsnTypeCollection
aDsnTypes(GetView()->getController().getORB());
119 bool bShowColumnDescription
= aDsnTypes
.supportsColumnDescription(::comphelper::getString(GetView()->getController().getDataSource()->getPropertyValue(PROPERTY_URL
)));
120 aColumnName
= ModuleRes(STR_TAB_HELP_TEXT
);
121 InsertDataColumn( HELP_TEXT
, aColumnName
, bShowColumnDescription
? FIELDTYPE_WIDTH
: FIELDDESCR_WIDTH
);
123 if ( bShowColumnDescription
)
125 aColumnName
= ModuleRes(STR_COLUMN_DESCRIPTION
);
126 InsertDataColumn( COLUMN_DESCRIPTION
, aColumnName
, FIELDTYPE_WIDTH
);
129 InitCellController();
132 RowInserted(0, m_pRowList
->size(), true);
135 OTableEditorCtrl::OTableEditorCtrl(vcl::Window
* pWindow
)
136 :OTableRowView(pWindow
)
146 ,nInvalidateTypeEvent(0)
151 ,m_aInvalidate(500,this)
154 SetHelpId(HID_TABDESIGN_BACKGROUND
);
155 GetDataWindow().SetHelpId(HID_CTL_TABLEEDIT
);
157 m_pRowList
= &GetView()->getController().getRows();
161 SfxUndoManager
& OTableEditorCtrl::GetUndoManager() const
163 return GetView()->getController().GetUndoManager();
167 void OTableEditorCtrl::SetReadOnly( bool bRead
)
170 if (bRead
== IsReadOnly())
171 // This check is important, as the underlying Def may be unnecessarily locked or unlocked
172 // or worse, this action may not be reversed afterwards
177 // Disable active cells
178 long nRow(GetCurRow());
179 sal_uInt16
nCol(GetCurColumnId());
182 // Select the correct Browsers cursor
183 BrowserMode
nMode(BrowserMode::COLUMNSELECTION
| BrowserMode::MULTISELECTION
| BrowserMode::KEEPHIGHLIGHT
|
184 BrowserMode::HLINES
| BrowserMode::VLINES
|BrowserMode::AUTOSIZE_LASTCOL
);
186 nMode
|= BrowserMode::HIDECURSOR
;
190 ActivateCell( nRow
, nCol
);
193 void OTableEditorCtrl::InitCellController()
196 sal_Int32 nMaxTextLen
= EDIT_NOLIMIT
;
197 OUString sExtraNameChars
;
198 Reference
<XConnection
> xCon
;
201 xCon
= GetView()->getController().getConnection();
202 Reference
< XDatabaseMetaData
> xMetaData
= xCon
.is() ? xCon
->getMetaData() : Reference
< XDatabaseMetaData
>();
204 nMaxTextLen
= xMetaData
.is() ? xMetaData
->getMaxColumnNameLength() : 0;
206 if( nMaxTextLen
== 0 )
207 nMaxTextLen
= EDIT_NOLIMIT
;
208 sExtraNameChars
= xMetaData
.is() ? xMetaData
->getExtraNameCharacters() : OUString();
213 OSL_FAIL("getMaxColumnNameLength");
216 pNameCell
= VclPtr
<OSQLNameEdit
>::Create(&GetDataWindow(), WB_LEFT
, sExtraNameChars
);
217 pNameCell
->SetMaxTextLen( nMaxTextLen
);
218 pNameCell
->setCheck( isSQL92CheckEnabled(xCon
) );
221 pTypeCell
= VclPtr
<ListBoxControl
>::Create( &GetDataWindow() );
222 pTypeCell
->SetDropDownLineCount( 15 );
225 pDescrCell
= VclPtr
<Edit
>::Create( &GetDataWindow(), WB_LEFT
);
226 pDescrCell
->SetMaxTextLen( MAX_DESCR_LEN
);
228 pHelpTextCell
= VclPtr
<Edit
>::Create( &GetDataWindow(), WB_LEFT
);
229 pHelpTextCell
->SetMaxTextLen( MAX_DESCR_LEN
);
231 pNameCell
->SetHelpId(HID_TABDESIGN_NAMECELL
);
232 pTypeCell
->SetHelpId(HID_TABDESIGN_TYPECELL
);
233 pDescrCell
->SetHelpId(HID_TABDESIGN_COMMENTCELL
);
234 pHelpTextCell
->SetHelpId(HID_TABDESIGN_HELPTEXT
);
237 const Control
* pControls
[] = { pTypeCell
,pDescrCell
,pNameCell
,pHelpTextCell
};
238 for(sal_Size i
= 0; i
< sizeof(pControls
) / sizeof(pControls
[0]);++i
)
240 const Size
aTemp(pControls
[i
]->GetOptimalSize());
241 if ( aTemp
.Height() > aHeight
.Height() )
242 aHeight
.Height() = aTemp
.Height();
244 SetDataRowHeight(aHeight
.Height());
249 void OTableEditorCtrl::ClearModified()
251 pNameCell
->ClearModifyFlag();
252 pDescrCell
->ClearModifyFlag();
253 pHelpTextCell
->ClearModifyFlag();
254 pTypeCell
->SaveValue();
257 OTableEditorCtrl::~OTableEditorCtrl()
262 void OTableEditorCtrl::dispose()
264 // Reset the Undo-Manager
265 GetUndoManager().Clear();
267 m_aInvalidate
.Stop();
269 // Take possible Events from the queue
271 Application::RemoveUserEvent( nCutEvent
);
273 Application::RemoveUserEvent( nPasteEvent
);
275 Application::RemoveUserEvent( nDeleteEvent
);
276 if( nInsNewRowsEvent
)
277 Application::RemoveUserEvent( nInsNewRowsEvent
);
278 if( nInvalidateTypeEvent
)
279 Application::RemoveUserEvent( nInvalidateTypeEvent
);
281 // Delete the control types
282 pNameCell
.disposeAndClear();
283 pTypeCell
.disposeAndClear();
284 pDescrCell
.disposeAndClear();
285 pHelpTextCell
.disposeAndClear();
287 OTableRowView::dispose();
290 bool OTableEditorCtrl::SetDataPtr( long nRow
)
295 OSL_ENSURE(nRow
< (long)m_pRowList
->size(),"Row is greater than size!");
296 if(nRow
>= (long)m_pRowList
->size())
298 pActRow
= (*m_pRowList
)[nRow
];
302 bool OTableEditorCtrl::SeekRow(long _nRow
)
304 // Call the Base class to remember which row must be repainted
305 EditBrowseBox::SeekRow(_nRow
);
307 m_nCurrentPos
= _nRow
;
308 return SetDataPtr(_nRow
);
311 void OTableEditorCtrl::PaintCell(OutputDevice
& rDev
, const Rectangle
& rRect
,
312 sal_uInt16 nColumnId
) const
314 const OUString
aText( GetCellText( m_nCurrentPos
, nColumnId
));
316 rDev
.Push( PushFlags::CLIPREGION
);
317 rDev
.SetClipRegion(vcl::Region(rRect
));
318 rDev
.DrawText( rRect
, aText
, DrawTextFlags::Left
| DrawTextFlags::VCenter
);
322 CellController
* OTableEditorCtrl::GetController(long nRow
, sal_uInt16 nColumnId
)
324 // If EditorCtrl is ReadOnly, editing is forbidden
325 Reference
<XPropertySet
> xTable
= GetView()->getController().getTable();
326 if (IsReadOnly() || ( xTable
.is() &&
327 xTable
->getPropertySetInfo()->hasPropertyByName(PROPERTY_TYPE
) &&
328 ::comphelper::getString(xTable
->getPropertyValue(PROPERTY_TYPE
)) == "VIEW"))
331 // If the row is ReadOnly, editing is forbidden
333 if( pActRow
->IsReadOnly() )
336 OFieldDescription
* pActFieldDescr
= pActRow
->GetActFieldDescr();
340 return new EditCellController( pNameCell
);
342 if (pActFieldDescr
&& !pActFieldDescr
->GetName().isEmpty())
343 return new ListBoxCellController( pTypeCell
);
346 if (pActFieldDescr
&& !pActFieldDescr
->GetName().isEmpty())
347 return new EditCellController( pHelpTextCell
);
350 case COLUMN_DESCRIPTION
:
351 if (pActFieldDescr
&& !pActFieldDescr
->GetName().isEmpty())
352 return new EditCellController( pDescrCell
);
360 void OTableEditorCtrl::InitController(CellControllerRef
&, long nRow
, sal_uInt16 nColumnId
)
362 SeekRow( nRow
== -1 ? GetCurRow() : nRow
);
363 OFieldDescription
* pActFieldDescr
= pActRow
->GetActFieldDescr();
364 OUString aInitString
;
370 aInitString
= pActFieldDescr
->GetName();
371 pNameCell
->SetText( aInitString
);
372 pNameCell
->SaveValue();
376 if ( pActFieldDescr
&& pActFieldDescr
->getTypeInfo() )
377 aInitString
= pActFieldDescr
->getTypeInfo()->aUIName
;
379 // Set the ComboBox contents
381 if( !pActFieldDescr
)
384 const OTypeInfoMap
& rTypeInfo
= GetView()->getController().getTypeInfo();
385 OTypeInfoMap::const_iterator aIter
= rTypeInfo
.begin();
386 OTypeInfoMap::const_iterator aEnd
= rTypeInfo
.end();
387 for(;aIter
!= aEnd
;++aIter
)
388 pTypeCell
->InsertEntry( aIter
->second
->aUIName
);
389 pTypeCell
->SelectEntry( aInitString
);
395 aInitString
= pActFieldDescr
->GetHelpText();
396 pHelpTextCell
->SetText( aInitString
);
397 pHelpTextCell
->SaveValue();
399 case COLUMN_DESCRIPTION
:
401 aInitString
= pActFieldDescr
->GetDescription();
402 pDescrCell
->SetText( aInitString
);
403 pDescrCell
->SaveValue();
409 EditBrowseBox::RowStatus
OTableEditorCtrl::GetRowStatus(long nRow
) const
411 const_cast<OTableEditorCtrl
*>(this)->SetDataPtr( nRow
);
413 return EditBrowseBox::CLEAN
;
414 if (nRow
>= 0 && nRow
== m_nDataPos
)
416 if( pActRow
->IsPrimaryKey() )
417 return EditBrowseBox::CURRENT_PRIMARYKEY
;
418 return EditBrowseBox::CURRENT
;
422 if( pActRow
->IsPrimaryKey() )
423 return EditBrowseBox::PRIMARYKEY
;
424 return EditBrowseBox::CLEAN
;
428 bool OTableEditorCtrl::SaveCurRow()
430 if (GetFieldDescr(GetCurRow()) == NULL
)
431 // there is no data in the current row
436 SetDataPtr(GetCurRow());
437 pDescrWin
->SaveData( pActRow
->GetActFieldDescr() );
441 void OTableEditorCtrl::DisplayData(long nRow
, bool bGrabFocus
)
443 // go to the correct cell
446 // Disable Edit-Mode temporarily
447 bool bWasEditing
= IsEditing();
451 CellControllerRef aTemp
;
452 InitController(aTemp
, nRow
, FIELD_NAME
);
453 InitController(aTemp
, nRow
, FIELD_TYPE
);
454 InitController(aTemp
, nRow
, COLUMN_DESCRIPTION
);
455 InitController(aTemp
, nRow
, HELP_TEXT
);
458 // Update the Description-Window
459 GetView()->GetDescWin()->DisplayData(GetFieldDescr(nRow
));
463 // and re-enable edit mode
464 if (bWasEditing
|| bGrabFocus
)
465 ActivateCell(nRow
, GetCurColumnId(), bGrabFocus
);
468 void OTableEditorCtrl::CursorMoved()
471 m_nDataPos
= GetCurRow();
472 if( m_nDataPos
!= nOldDataPos
&& m_nDataPos
!= -1)
474 CellControllerRef aTemp
;
475 InitController(aTemp
,m_nDataPos
,FIELD_NAME
);
476 InitController(aTemp
,m_nDataPos
,FIELD_TYPE
);
477 InitController(aTemp
,m_nDataPos
,COLUMN_DESCRIPTION
);
478 InitController(aTemp
,m_nDataPos
,HELP_TEXT
);
481 OTableRowView::CursorMoved();
484 sal_Int32
OTableEditorCtrl::HasFieldName( const OUString
& rFieldName
)
487 Reference
<XConnection
> xCon
= GetView()->getController().getConnection();
488 Reference
< XDatabaseMetaData
> xMetaData
= xCon
.is() ? xCon
->getMetaData() : Reference
< XDatabaseMetaData
>();
490 ::comphelper::UStringMixEqual
bCase(!xMetaData
.is() || xMetaData
->supportsMixedCaseQuotedIdentifiers());
492 ::std::vector
< ::boost::shared_ptr
<OTableRow
> >::iterator aIter
= m_pRowList
->begin();
493 ::std::vector
< ::boost::shared_ptr
<OTableRow
> >::iterator aEnd
= m_pRowList
->end();
495 for(;aIter
!= aEnd
;++aIter
)
497 OFieldDescription
* pFieldDescr
= (*aIter
)->GetActFieldDescr();
498 if( pFieldDescr
&& bCase(rFieldName
,pFieldDescr
->GetName()))
504 bool OTableEditorCtrl::SaveData(long nRow
, sal_uInt16 nColId
)
506 // Store the cell content
507 SetDataPtr( nRow
== -1 ? GetCurRow() : nRow
);
508 OFieldDescription
* pActFieldDescr
= pActRow
->GetActFieldDescr();
515 // If there is no name, do nothing
516 OUString
aName(pNameCell
->GetText());
518 if( aName
.isEmpty() )
520 // If FieldDescr exists, the field is deleted and the old content restored
523 GetUndoManager().AddUndoAction(new OTableEditorTypeSelUndoAct(this, nRow
, FIELD_TYPE
, pActFieldDescr
->getTypeInfo()));
524 SwitchType(TOTypeInfoSP());
525 pActFieldDescr
= pActRow
->GetActFieldDescr();
531 pActFieldDescr
->SetName( aName
);
532 pNameCell
->ClearModifyFlag();
537 // Store the field type
544 // if the current field description is NULL, set Default
545 if( !pActFieldDescr
)
547 pHelpTextCell
->SetText(OUString());
548 pHelpTextCell
->ClearModifyFlag();
551 pActFieldDescr
->SetHelpText( pHelpTextCell
->GetText() );
554 case COLUMN_DESCRIPTION
:
556 // Set the default if the field description is null
557 if( !pActFieldDescr
)
559 pDescrCell
->SetText(OUString());
560 pDescrCell
->ClearModifyFlag();
563 pActFieldDescr
->SetDescription( pDescrCell
->GetText() );
566 case FIELD_PROPERTY_DEFAULT
:
567 case FIELD_PROPERTY_REQUIRED
:
568 case FIELD_PROPERTY_TEXTLEN
:
569 case FIELD_PROPERTY_NUMTYPE
:
570 case FIELD_PROPERTY_AUTOINC
:
571 case FIELD_PROPERTY_LENGTH
:
572 case FIELD_PROPERTY_SCALE
:
573 case FIELD_PROPERTY_BOOL_DEFAULT
:
574 pDescrWin
->SaveData(pActFieldDescr
);
576 if ( FIELD_PROPERTY_AUTOINC
== nColId
&& pActFieldDescr
->IsAutoIncrement() )
578 OTableController
& rController
= GetView()->getController();
579 if ( rController
.isAutoIncrementPrimaryKey() )
581 pActFieldDescr
->SetPrimaryKey( true );
582 InvalidateHandleColumn();
591 bool OTableEditorCtrl::SaveModified()
593 sal_uInt16 nColId
= GetCurColumnId();
608 bool OTableEditorCtrl::CursorMoving(long nNewRow
, sal_uInt16 nNewCol
)
611 if (!EditBrowseBox::CursorMoving(nNewRow
, nNewCol
))
614 // Called after SaveModified(), current row is still the old one
615 m_nDataPos
= nNewRow
;
616 nOldDataPos
= GetCurRow();
619 InvalidateStatusCell( nOldDataPos
);
620 InvalidateStatusCell( m_nDataPos
);
622 // Store the data from the Property window
623 if( SetDataPtr(nOldDataPos
) && pDescrWin
)
624 pDescrWin
->SaveData( pActRow
->GetActFieldDescr() );
626 // Show new data in the Property window
627 if( SetDataPtr(m_nDataPos
) && pDescrWin
)
628 pDescrWin
->DisplayData( pActRow
->GetActFieldDescr() );
633 IMPL_LINK_NOARG( OTableEditorCtrl
, InvalidateFieldType
)
635 nInvalidateTypeEvent
= 0;
636 Invalidate( GetFieldRectPixel(nOldDataPos
, FIELD_TYPE
) );
641 void OTableEditorCtrl::CellModified( long nRow
, sal_uInt16 nColId
)
644 // If the description is null, use the default
648 OFieldDescription
* pActFieldDescr
= pActRow
->GetActFieldDescr();
650 OUString sActionDescription
;
653 case FIELD_NAME
: sActionDescription
= ModuleRes( STR_CHANGE_COLUMN_NAME
); break;
654 case FIELD_TYPE
: sActionDescription
= ModuleRes( STR_CHANGE_COLUMN_TYPE
); break;
656 case COLUMN_DESCRIPTION
: sActionDescription
= ModuleRes( STR_CHANGE_COLUMN_DESCRIPTION
); break;
657 default: sActionDescription
= ModuleRes( STR_CHANGE_COLUMN_ATTRIBUTE
); break;
660 GetUndoManager().EnterListAction( sActionDescription
, OUString() );
663 const OTypeInfoMap
& rTypeInfoMap
= GetView()->getController().getTypeInfo();
664 if ( !rTypeInfoMap
.empty() )
666 OTypeInfoMap::const_iterator aTypeIter
= rTypeInfoMap
.find(DataType::VARCHAR
);
667 if ( aTypeIter
== rTypeInfoMap
.end() )
668 aTypeIter
= rTypeInfoMap
.begin();
669 pActRow
->SetFieldType( aTypeIter
->second
);
672 pActRow
->SetFieldType( GetView()->getController().getTypeInfoFallBack() );
674 nInvalidateTypeEvent
= Application::PostUserEvent( LINK(this, OTableEditorCtrl
, InvalidateFieldType
), NULL
, true );
675 pActFieldDescr
= pActRow
->GetActFieldDescr();
676 pDescrWin
->DisplayData( pActFieldDescr
);
677 GetUndoManager().AddUndoAction( new OTableEditorTypeSelUndoAct(this, nRow
, nColId
+1, TOTypeInfoSP()) );
680 if( nColId
!= FIELD_TYPE
)
681 GetUndoManager().AddUndoAction( new OTableDesignCellUndoAct(this, nRow
, nColId
) );
684 GetUndoManager().AddUndoAction(new OTableEditorTypeSelUndoAct(this, GetCurRow(), nColId
, GetFieldDescr(GetCurRow())->getTypeInfo()));
688 SaveData(nRow
,nColId
);
689 // SaveData could create a undo action as well
690 GetUndoManager().LeaveListAction();
692 CellControllerRef
xController(Controller());
694 xController
->SetModified();
696 // Set the Modify flag
697 GetView()->getController().setModified( sal_True
);
698 InvalidateFeatures();
701 void OTableEditorCtrl::resetType()
703 sal_Int32 nPos
= pTypeCell
->GetSelectEntryPos();
704 if(nPos
!= LISTBOX_ENTRY_NOTFOUND
)
705 SwitchType( GetView()->getController().getTypeInfo(nPos
) );
707 SwitchType(TOTypeInfoSP());
710 void OTableEditorCtrl::CellModified()
712 CellModified( GetCurRow(), GetCurColumnId() );
715 void OTableEditorCtrl::InvalidateFeatures()
717 GetView()->getController().InvalidateFeature(SID_UNDO
);
718 GetView()->getController().InvalidateFeature(SID_REDO
);
719 GetView()->getController().InvalidateFeature(SID_SAVEDOC
);
722 void OTableEditorCtrl::CopyRows()
724 // set to the right row and save it
725 if( SetDataPtr(m_nDataPos
) )
726 pDescrWin
->SaveData( pActRow
->GetActFieldDescr() );
728 // Copy selected rows to the ClipboardList
729 ::boost::shared_ptr
<OTableRow
> pClipboardRow
;
730 ::boost::shared_ptr
<OTableRow
> pRow
;
731 ::std::vector
< ::boost::shared_ptr
<OTableRow
> > vClipboardList
;
732 vClipboardList
.reserve(GetSelectRowCount());
734 for( long nIndex
=FirstSelectedRow(); nIndex
>= 0 && nIndex
< static_cast<long>(m_pRowList
->size()); nIndex
=NextSelectedRow() )
736 pRow
= (*m_pRowList
)[nIndex
];
737 OSL_ENSURE(pRow
,"OTableEditorCtrl::CopyRows: Row is NULL!");
738 if ( pRow
&& pRow
->GetActFieldDescr() )
740 pClipboardRow
.reset(new OTableRow( *pRow
));
741 vClipboardList
.push_back( pClipboardRow
);
744 if(!vClipboardList
.empty())
746 OTableRowExchange
* pData
= new OTableRowExchange(vClipboardList
);
747 Reference
< ::com::sun::star::datatransfer::XTransferable
> xRef
= pData
;
748 pData
->CopyToClipboard(GetParent());
752 OUString
OTableEditorCtrl::GenerateName( const OUString
& rName
)
754 // Create a base name for appending numbers to
756 Reference
<XConnection
> xCon
= GetView()->getController().getConnection();
757 Reference
< XDatabaseMetaData
> xMetaData
= xCon
.is() ? xCon
->getMetaData() : Reference
< XDatabaseMetaData
>();
759 sal_Int32
nMaxTextLen(xMetaData
.is() ? xMetaData
->getMaxColumnNameLength() : 0);
761 if( (rName
.getLength()+2) >nMaxTextLen
)
762 aBaseName
= rName
.copy( 0, nMaxTextLen
-2 );
766 // append a sequential number to the base name (up to 99)
767 OUString
aFieldName( rName
);
769 while( HasFieldName(aFieldName
) )
771 aFieldName
= aBaseName
+ OUString::number(i
);
778 void OTableEditorCtrl::InsertRows( long nRow
)
781 ::std::vector
< ::boost::shared_ptr
<OTableRow
> > vInsertedUndoRedoRows
; // need for undo/redo handling
782 // get rows from clipboard
783 TransferableDataHelper
aTransferData(TransferableDataHelper::CreateFromSystemClipboard(GetParent()));
784 if(aTransferData
.HasFormat(SotClipboardFormatId::SBA_TABED
))
786 ::tools::SvRef
<SotStorageStream
> aStreamRef
;
787 bool bOk
= aTransferData
.GetSotStorageStream(SotClipboardFormatId::SBA_TABED
,aStreamRef
);
788 if (bOk
&& aStreamRef
.Is())
790 aStreamRef
->Seek(STREAM_SEEK_TO_BEGIN
);
791 aStreamRef
->ResetError();
792 long nInsertRow
= nRow
;
794 ::boost::shared_ptr
<OTableRow
> pRow
;
796 (*aStreamRef
).ReadInt32( nSize
);
797 vInsertedUndoRedoRows
.reserve(nSize
);
798 for(sal_Int32 i
=0;i
< nSize
;++i
)
800 pRow
.reset(new OTableRow());
801 ReadOTableRow( *aStreamRef
, *pRow
);
802 pRow
->SetReadOnly( false );
803 sal_Int32 nType
= pRow
->GetActFieldDescr()->GetType();
804 if ( pRow
->GetActFieldDescr() )
805 pRow
->GetActFieldDescr()->SetType(GetView()->getController().getTypeInfoByType(nType
));
806 // Adjust the field names
807 aFieldName
= GenerateName( pRow
->GetActFieldDescr()->GetName() );
808 pRow
->GetActFieldDescr()->SetName( aFieldName
);
809 pRow
->SetPos(nInsertRow
);
810 m_pRowList
->insert( m_pRowList
->begin()+nInsertRow
,pRow
);
811 vInsertedUndoRedoRows
.push_back(::boost::shared_ptr
<OTableRow
>(new OTableRow(*pRow
)));
816 // RowInserted calls CursorMoved.
817 // The UI data should not be stored here.
819 RowInserted( nRow
,vInsertedUndoRedoRows
.size(), true );
822 // Create the Undo-Action
823 GetUndoManager().AddUndoAction( new OTableEditorInsUndoAct(this, nRow
,vInsertedUndoRedoRows
) );
824 GetView()->getController().setModified( sal_True
);
825 InvalidateFeatures();
828 void OTableEditorCtrl::DeleteRows()
830 OSL_ENSURE(GetView()->getController().isDropAllowed(),"Call of DeleteRows not valid here. Please check isDropAllowed!");
831 // Create the Undo-Action
832 GetUndoManager().AddUndoAction( new OTableEditorDelUndoAct(this) );
834 // Delete all marked rows
835 long nIndex
= FirstSelectedRow();
836 nOldDataPos
= nIndex
;
839 while( nIndex
>= 0 && nIndex
< static_cast<long>(m_pRowList
->size()) )
842 m_pRowList
->erase( m_pRowList
->begin()+nIndex
);
843 RowRemoved( nIndex
, 1, true );
845 // Insert the empty row at the end
846 m_pRowList
->push_back( ::boost::shared_ptr
<OTableRow
>(new OTableRow()));
847 RowInserted( GetRowCount()-1, 1, true );
849 nIndex
= FirstSelectedRow();
854 // Force the current record to be displayed
855 m_nDataPos
= GetCurRow();
856 InvalidateStatusCell( nOldDataPos
);
857 InvalidateStatusCell( m_nDataPos
);
858 SetDataPtr( m_nDataPos
);
860 pDescrWin
->DisplayData( pActRow
->GetActFieldDescr() );
861 GetView()->getController().setModified( sal_True
);
862 InvalidateFeatures();
865 void OTableEditorCtrl::InsertNewRows( long nRow
)
867 OSL_ENSURE(GetView()->getController().isAddAllowed(),"Call of InsertNewRows not valid here. Please check isAppendAllowed!");
868 // Create Undo-Action
869 long nInsertRows
= GetSelectRowCount();
872 GetUndoManager().AddUndoAction( new OTableEditorInsNewUndoAct(this, nRow
, nInsertRows
) );
873 // Insert the number of selected rows
874 for( long i
=nRow
; i
<(nRow
+nInsertRows
); i
++ )
875 m_pRowList
->insert( m_pRowList
->begin()+i
,::boost::shared_ptr
<OTableRow
>(new OTableRow()));
876 RowInserted( nRow
, nInsertRows
, true );
878 GetView()->getController().setModified( sal_True
);
879 InvalidateFeatures();
882 OUString
OTableEditorCtrl::GetControlText( long nRow
, sal_uInt16 nColId
)
884 // Read the Browser Controls
885 if( nColId
< FIELD_FIRST_VIRTUAL_COLUMN
)
888 GoToColumnId( nColId
);
889 CellControllerRef xController
= Controller();
891 return xController
->GetWindow().GetText();
893 return GetCellText(nRow
,nColId
);
896 // Read the Controls on the Tabpage
898 return pDescrWin
->GetControlText( nColId
);
901 void OTableEditorCtrl::SetControlText( long nRow
, sal_uInt16 nColId
, const OUString
& rText
)
903 // Set the Browser Controls
904 if( nColId
< FIELD_FIRST_VIRTUAL_COLUMN
)
907 GoToColumnId( nColId
);
908 CellControllerRef xController
= Controller();
910 xController
->GetWindow().SetText( rText
);
912 RowModified(nRow
,nColId
);
915 // Set the Tabpage controls
918 pDescrWin
->SetControlText( nColId
, rText
);
922 void OTableEditorCtrl::SetCellData( long nRow
, sal_uInt16 nColId
, const TOTypeInfoSP
& _pTypeInfo
)
924 // Relocate the current pointer
927 OFieldDescription
* pFieldDescr
= GetFieldDescr( nRow
);
928 if( !pFieldDescr
&& nColId
!= FIELD_TYPE
)
931 // Set individual fields
935 SwitchType( _pTypeInfo
);
938 OSL_FAIL("OTableEditorCtrl::SetCellData: invalid column!");
940 SetControlText(nRow
,nColId
,_pTypeInfo
.get() ? _pTypeInfo
->aUIName
: OUString());
943 void OTableEditorCtrl::SetCellData( long nRow
, sal_uInt16 nColId
, const ::com::sun::star::uno::Any
& _rNewData
)
945 // Relocate the current pointer
948 OFieldDescription
* pFieldDescr
= GetFieldDescr( nRow
);
949 if( !pFieldDescr
&& nColId
!= FIELD_TYPE
)
953 // Set indvidual fields
957 sValue
= ::comphelper::getString(_rNewData
);
958 pFieldDescr
->SetName( sValue
);
962 OSL_FAIL("OTableEditorCtrl::SetCellData: invalid column!");
965 case COLUMN_DESCRIPTION
:
966 pFieldDescr
->SetDescription( sValue
= ::comphelper::getString(_rNewData
) );
969 case FIELD_PROPERTY_DEFAULT
:
970 pFieldDescr
->SetControlDefault( _rNewData
);
971 sValue
= GetView()->GetDescWin()->getGenPage()->getFieldControl()->getControlDefault(pFieldDescr
);
974 case FIELD_PROPERTY_REQUIRED
:
976 sValue
= ::comphelper::getString(_rNewData
);
977 pFieldDescr
->SetIsNullable( sValue
.toInt32() );
981 case FIELD_PROPERTY_TEXTLEN
:
982 case FIELD_PROPERTY_LENGTH
:
984 sValue
= ::comphelper::getString(_rNewData
);
985 pFieldDescr
->SetPrecision( sValue
.toInt32() );
989 case FIELD_PROPERTY_NUMTYPE
:
990 OSL_FAIL("OTableEditorCtrl::SetCellData: invalid column!");
993 case FIELD_PROPERTY_AUTOINC
:
995 OUString
strYes(ModuleRes(STR_VALUE_YES
));
996 sValue
= ::comphelper::getString(_rNewData
);
997 pFieldDescr
->SetAutoIncrement(sValue
== strYes
);
1000 case FIELD_PROPERTY_SCALE
:
1002 sValue
= ::comphelper::getString(_rNewData
);
1003 pFieldDescr
->SetScale(sValue
.toInt32());
1007 case FIELD_PROPERTY_BOOL_DEFAULT
:
1008 sValue
= GetView()->GetDescWin()->BoolStringPersistent(::comphelper::getString(_rNewData
));
1009 pFieldDescr
->SetControlDefault(makeAny(OUString(sValue
)));
1012 case FIELD_PROPERTY_FORMAT
:
1014 sValue
= ::comphelper::getString(_rNewData
);
1015 pFieldDescr
->SetFormatKey(sValue
.toInt32());
1020 SetControlText(nRow
,nColId
,sValue
);
1023 Any
OTableEditorCtrl::GetCellData( long nRow
, sal_uInt16 nColId
)
1025 OFieldDescription
* pFieldDescr
= GetFieldDescr( nRow
);
1029 // Relocate the current pointer
1034 static const OUString
strYes(ModuleRes(STR_VALUE_YES
));
1035 static const OUString
strNo(ModuleRes(STR_VALUE_NO
));
1037 // Read out the fields
1041 sValue
= pFieldDescr
->GetName();
1045 if ( pFieldDescr
->getTypeInfo() )
1046 sValue
= pFieldDescr
->getTypeInfo()->aUIName
;
1049 case COLUMN_DESCRIPTION
:
1050 sValue
= pFieldDescr
->GetDescription();
1053 sValue
= pFieldDescr
->GetHelpText();
1056 case FIELD_PROPERTY_DEFAULT
:
1057 return pFieldDescr
->GetControlDefault();
1059 case FIELD_PROPERTY_REQUIRED
:
1060 sValue
= pFieldDescr
->GetIsNullable() == ColumnValue::NULLABLE
? strYes
: strNo
;
1063 case FIELD_PROPERTY_TEXTLEN
:
1064 case FIELD_PROPERTY_LENGTH
:
1065 sValue
= OUString::number(pFieldDescr
->GetPrecision());
1068 case FIELD_PROPERTY_NUMTYPE
:
1069 OSL_FAIL("OTableEditorCtrl::GetCellData: invalid column!");
1072 case FIELD_PROPERTY_AUTOINC
:
1073 sValue
= pFieldDescr
->IsAutoIncrement() ? strYes
: strNo
;
1076 case FIELD_PROPERTY_SCALE
:
1077 sValue
= OUString::number(pFieldDescr
->GetScale());
1080 case FIELD_PROPERTY_BOOL_DEFAULT
:
1081 sValue
= GetView()->GetDescWin()->BoolStringUI(::comphelper::getString(pFieldDescr
->GetControlDefault()));
1084 case FIELD_PROPERTY_FORMAT
:
1085 sValue
= OUString::number(pFieldDescr
->GetFormatKey());
1089 return makeAny(sValue
);
1092 OUString
OTableEditorCtrl::GetCellText( long nRow
, sal_uInt16 nColId
) const
1095 const_cast< OTableEditorCtrl
* >( this )->GetCellData( nRow
, nColId
) >>= sCellText
;
1099 sal_uInt32
OTableEditorCtrl::GetTotalCellWidth(long nRow
, sal_uInt16 nColId
)
1101 return GetTextWidth(GetCellText(nRow
, nColId
)) + 2 * GetTextWidth(OUString('0'));
1104 OFieldDescription
* OTableEditorCtrl::GetFieldDescr( long nRow
)
1106 std::vector
< ::boost::shared_ptr
<OTableRow
> >::size_type
nListCount(
1107 m_pRowList
->size());
1108 if( (nRow
<0) || (sal::static_int_cast
< unsigned long >(nRow
)>=nListCount
) )
1110 OSL_FAIL("(nRow<0) || (nRow>=nListCount)");
1113 ::boost::shared_ptr
<OTableRow
> pRow
= (*m_pRowList
)[ nRow
];
1116 return pRow
->GetActFieldDescr();
1119 bool OTableEditorCtrl::IsCutAllowed( long nRow
)
1121 bool bIsCutAllowed
= (GetView()->getController().isAddAllowed() && GetView()->getController().isDropAllowed()) ||
1122 GetView()->getController().isAlterAllowed();
1126 switch(m_eChildFocus
)
1129 bIsCutAllowed
= !pDescrCell
->GetSelected().isEmpty();
1132 bIsCutAllowed
= !pHelpTextCell
->GetSelected().isEmpty();
1135 bIsCutAllowed
= !pNameCell
->GetSelected().isEmpty();
1138 bIsCutAllowed
= IsCopyAllowed(nRow
);
1141 bIsCutAllowed
= false;
1146 return bIsCutAllowed
;
1149 bool OTableEditorCtrl::IsCopyAllowed( long /*nRow*/ )
1151 bool bIsCopyAllowed
= false;
1152 if(m_eChildFocus
== DESCRIPTION
)
1153 bIsCopyAllowed
= !pDescrCell
->GetSelected().isEmpty();
1154 else if(HELPTEXT
== m_eChildFocus
)
1155 bIsCopyAllowed
= !pHelpTextCell
->GetSelected().isEmpty();
1156 else if(m_eChildFocus
== NAME
)
1157 bIsCopyAllowed
= !pNameCell
->GetSelected().isEmpty();
1158 else if(m_eChildFocus
== ROW
)
1160 Reference
<XPropertySet
> xTable
= GetView()->getController().getTable();
1161 if( !GetSelectRowCount() || (xTable
.is() && ::comphelper::getString(xTable
->getPropertyValue(PROPERTY_TYPE
)) == "VIEW"))
1164 // If one of the selected rows is empty, Copy is not possible
1165 ::boost::shared_ptr
<OTableRow
> pRow
;
1166 long nIndex
= FirstSelectedRow();
1167 while( nIndex
>= 0 && nIndex
< static_cast<long>(m_pRowList
->size()) )
1169 pRow
= (*m_pRowList
)[nIndex
];
1170 if( !pRow
->GetActFieldDescr() )
1173 nIndex
= NextSelectedRow();
1176 bIsCopyAllowed
= true;
1179 return bIsCopyAllowed
;
1182 bool OTableEditorCtrl::IsPasteAllowed( long /*nRow*/ )
1184 bool bAllowed
= GetView()->getController().isAddAllowed();
1187 TransferableDataHelper
aTransferData(TransferableDataHelper::CreateFromSystemClipboard(GetParent()));
1188 bool bRowFormat
= aTransferData
.HasFormat(SotClipboardFormatId::SBA_TABED
);
1189 if ( m_eChildFocus
== ROW
)
1190 bAllowed
= bRowFormat
;
1192 bAllowed
= !bRowFormat
&& aTransferData
.HasFormat(SotClipboardFormatId::STRING
);
1198 void OTableEditorCtrl::cut()
1200 if(m_eChildFocus
== NAME
)
1202 if(GetView()->getController().isAlterAllowed())
1204 SaveData(-1,FIELD_NAME
);
1206 CellModified(-1,FIELD_NAME
);
1209 else if(m_eChildFocus
== DESCRIPTION
)
1211 if(GetView()->getController().isAlterAllowed())
1213 SaveData(-1,COLUMN_DESCRIPTION
);
1215 CellModified(-1,COLUMN_DESCRIPTION
);
1218 else if(HELPTEXT
== m_eChildFocus
)
1220 if(GetView()->getController().isAlterAllowed())
1222 SaveData(-1,HELP_TEXT
);
1223 pHelpTextCell
->Cut();
1224 CellModified(-1,HELP_TEXT
);
1227 else if(m_eChildFocus
== ROW
)
1230 Application::RemoveUserEvent(nCutEvent
);
1231 nCutEvent
= Application::PostUserEvent(LINK(this, OTableEditorCtrl
, DelayedCut
), NULL
, true);
1235 void OTableEditorCtrl::copy()
1237 if(GetSelectRowCount())
1238 OTableRowView::copy();
1239 else if(m_eChildFocus
== NAME
)
1241 else if(HELPTEXT
== m_eChildFocus
)
1242 pHelpTextCell
->Copy();
1243 else if(m_eChildFocus
== DESCRIPTION
)
1247 void OTableEditorCtrl::paste()
1249 TransferableDataHelper
aTransferData(TransferableDataHelper::CreateFromSystemClipboard(GetParent()));
1250 if(aTransferData
.HasFormat(SotClipboardFormatId::SBA_TABED
))
1253 Application::RemoveUserEvent( nPasteEvent
);
1254 nPasteEvent
= Application::PostUserEvent( LINK(this, OTableEditorCtrl
, DelayedPaste
), NULL
, true );
1256 else if(m_eChildFocus
== NAME
)
1258 if(GetView()->getController().isAlterAllowed())
1264 else if(HELPTEXT
== m_eChildFocus
)
1266 if(GetView()->getController().isAlterAllowed())
1268 pHelpTextCell
->Paste();
1272 else if(m_eChildFocus
== DESCRIPTION
)
1274 if(GetView()->getController().isAlterAllowed())
1276 pDescrCell
->Paste();
1282 bool OTableEditorCtrl::IsDeleteAllowed( long /*nRow*/ )
1285 return GetSelectRowCount() != 0 && GetView()->getController().isDropAllowed();
1288 bool OTableEditorCtrl::IsInsertNewAllowed( long nRow
)
1291 bool bInsertNewAllowed
= GetView()->getController().isAddAllowed();
1292 // If fields can be added, Paste in the new fields
1293 if (bInsertNewAllowed
&& !GetView()->getController().isDropAllowed())
1296 if( GetActRow()->IsReadOnly() )
1300 return bInsertNewAllowed
;
1303 bool OTableEditorCtrl::IsPrimaryKeyAllowed( long /*nRow*/ )
1305 if( !GetSelectRowCount() )
1308 OTableController
& rController
= GetView()->getController();
1309 if ( !rController
.getSdbMetaData().supportsPrimaryKeys() )
1312 Reference
<XPropertySet
> xTable
= rController
.getTable();
1313 // Key must not be changed
1314 // This applies only if the table is not new and not a ::com::sun::star::sdbcx::View. Otherwise no DROP is executed
1316 if(xTable
.is() && ::comphelper::getString(xTable
->getPropertyValue(PROPERTY_TYPE
)) == "VIEW")
1318 // If there is an empty field, no primary key
1319 // The entry is only permitted if
1320 // - there are no empty entries in the selection
1321 // - No Memo or Image entries
1322 // - DROP is not permitted (see above) and the column is not Required (not null flag is not set).
1323 long nIndex
= FirstSelectedRow();
1324 ::boost::shared_ptr
<OTableRow
> pRow
;
1325 while( nIndex
>= 0 && nIndex
< static_cast<long>(m_pRowList
->size()) )
1327 pRow
= (*m_pRowList
)[nIndex
];
1328 OFieldDescription
* pFieldDescr
= pRow
->GetActFieldDescr();
1333 // Memo and Image fields cannot be primary keys
1334 // or if the column cannot be dropped and the Required flag is not set
1335 // or if a ::com::sun::star::sdbcx::View is available and the Required flag is not set
1336 TOTypeInfoSP pTypeInfo
= pFieldDescr
->getTypeInfo();
1337 if( pTypeInfo
->nSearchType
== ColumnSearch::NONE
1338 || (pFieldDescr
->IsNullable() && pRow
->IsReadOnly())
1343 nIndex
= NextSelectedRow();
1349 void OTableEditorCtrl::Command(const CommandEvent
& rEvt
)
1351 switch (rEvt
.GetCommand())
1353 case CommandEventId::ContextMenu
:
1355 Point
aMenuPos( rEvt
.GetMousePosPixel() );
1356 if (!rEvt
.IsMouseEvent())
1358 if ( 1 == GetSelectColumnCount() )
1360 sal_uInt16 nSelId
= GetColumnId(
1361 sal::static_int_cast
< sal_uInt16
>(
1362 FirstSelectedColumn() ) );
1363 ::Rectangle
aColRect( GetFieldRectPixel( 0, nSelId
, false ) );
1365 aMenuPos
= aColRect
.TopCenter();
1367 else if ( GetSelectRowCount() > 0 )
1369 ::Rectangle
aColRect( GetFieldRectPixel( FirstSelectedRow(), HANDLE_ID
, true ) );
1371 aMenuPos
= aColRect
.TopCenter();
1375 OTableRowView::Command(rEvt
);
1380 // Show the Context menu
1383 sal_uInt16 nColId
= GetColumnAtXPosPixel(aMenuPos
.X());
1384 long nRow
= GetRowAtYPosPixel(aMenuPos
.Y());
1386 if ( HANDLE_ID
!= nColId
)
1388 if ( nRow
< 0 && nColId
!= BROWSER_INVALIDID
)
1391 { // 3 would mean the last column, and this last column is auto-sized
1392 if ( !IsColumnSelected( nColId
) )
1393 SelectColumnId( nColId
);
1395 PopupMenu
aContextMenu( ModuleRes( RID_QUERYCOLPOPUPMENU
) );
1396 aContextMenu
.EnableItem( SID_DELETE
, false );
1397 aContextMenu
.RemoveDisabledEntries(true, true);
1398 switch ( aContextMenu
.Execute( this, aMenuPos
) )
1400 case ID_BROWSER_COLWIDTH
:
1401 adjustBrowseBoxColumnWidth( this, nColId
);
1409 PopupMenu
aContextMenu(ModuleRes(RID_TABLEDESIGNROWPOPUPMENU
));
1411 aContextMenu
.EnableItem( SID_CUT
, IsCutAllowed(nRow
) );
1412 aContextMenu
.EnableItem( SID_COPY
, IsCopyAllowed(nRow
) );
1413 aContextMenu
.EnableItem( SID_PASTE
, IsPasteAllowed(nRow
) );
1414 aContextMenu
.EnableItem( SID_DELETE
, IsDeleteAllowed(nRow
) );
1415 aContextMenu
.EnableItem( SID_TABLEDESIGN_TABED_PRIMARYKEY
, IsPrimaryKeyAllowed(nRow
) );
1416 aContextMenu
.EnableItem( SID_TABLEDESIGN_INSERTROWS
, IsInsertNewAllowed(nRow
) );
1417 aContextMenu
.CheckItem( SID_TABLEDESIGN_TABED_PRIMARYKEY
, IsRowSelected(GetCurRow()) && IsPrimaryKey() );
1419 // remove all the disable entries
1420 aContextMenu
.RemoveDisabledEntries(true, true);
1422 if( SetDataPtr(m_nDataPos
) )
1423 pDescrWin
->SaveData( pActRow
->GetActFieldDescr() );
1425 // All actions which change the number of rows must be run asynchronously
1426 // otherwise there may be problems between the Context menu and the Browser
1427 m_nDataPos
= GetCurRow();
1428 switch (aContextMenu
.Execute(this, aMenuPos
))
1441 Application::RemoveUserEvent( nDeleteEvent
);
1442 nDeleteEvent
= Application::PostUserEvent( LINK(this, OTableEditorCtrl
, DelayedDelete
), NULL
, true );
1444 case SID_TABLEDESIGN_INSERTROWS
:
1445 if( nInsNewRowsEvent
)
1446 Application::RemoveUserEvent( nInsNewRowsEvent
);
1447 nInsNewRowsEvent
= Application::PostUserEvent( LINK(this, OTableEditorCtrl
, DelayedInsNewRows
), NULL
, true );
1449 case SID_TABLEDESIGN_TABED_PRIMARYKEY
:
1450 SetPrimaryKey( !IsPrimaryKey() );
1460 OTableRowView::Command(rEvt
);
1465 IMPL_LINK_NOARG( OTableEditorCtrl
, DelayedCut
)
1468 OTableRowView::cut();
1472 IMPL_LINK_NOARG( OTableEditorCtrl
, DelayedPaste
)
1476 sal_Int32 nPastePosition
= GetView()->getController().getFirstEmptyRowPosition();
1477 if ( !GetView()->getController().getTable().is() )
1478 nPastePosition
= GetSelectRowCount() ? FirstSelectedRow() : GetCurRow();
1480 if (!IsInsertNewAllowed(nPastePosition
))
1481 { // Insertion is not allowed, only appending, so test if there are full cells after the PastePosition
1483 sal_Int32 nFreeFromPos
; // from here on there are only empty rows
1484 ::std::vector
< ::boost::shared_ptr
<OTableRow
> >::reverse_iterator aIter
= m_pRowList
->rbegin();
1485 for(nFreeFromPos
= m_pRowList
->size();
1486 aIter
!= m_pRowList
->rend() && (!(*aIter
) || !(*aIter
)->GetActFieldDescr() || (*aIter
)->GetActFieldDescr()->GetName().isEmpty());
1487 --nFreeFromPos
, ++aIter
)
1489 if (nPastePosition
< nFreeFromPos
) // if at least one PastePosition is full, go right to the end
1490 nPastePosition
= nFreeFromPos
;
1493 OTableRowView::Paste( nPastePosition
);
1495 GoToRow( nPastePosition
);
1500 IMPL_LINK_NOARG( OTableEditorCtrl
, DelayedDelete
)
1507 IMPL_LINK_NOARG( OTableEditorCtrl
, DelayedInsNewRows
)
1509 nInsNewRowsEvent
= 0;
1510 sal_Int32 nPastePosition
= GetView()->getController().getFirstEmptyRowPosition();
1511 if ( !GetView()->getController().getTable().is() )
1512 nPastePosition
= GetSelectRowCount() ? FirstSelectedRow() : m_nDataPos
;
1514 InsertNewRows( nPastePosition
);
1516 GoToRow( nPastePosition
);
1521 void OTableEditorCtrl::AdjustFieldDescription(OFieldDescription
* _pFieldDesc
,
1522 MultiSelection
& _rMultiSel
,
1527 _pFieldDesc
->SetPrimaryKey( _bPrimaryKey
);
1528 if(!_bSet
&& _pFieldDesc
->getTypeInfo()->bNullable
)
1530 _pFieldDesc
->SetIsNullable(ColumnValue::NO_NULLS
);
1531 _pFieldDesc
->SetControlDefault(Any());
1533 if ( _pFieldDesc
->IsAutoIncrement() && !_bPrimaryKey
)
1535 OTableController
& rController
= GetView()->getController();
1536 if ( rController
.isAutoIncrementPrimaryKey() )
1538 _pFieldDesc
->SetAutoIncrement(false);
1541 // update field description
1542 pDescrWin
->DisplayData(_pFieldDesc
);
1544 _rMultiSel
.Insert( _nPos
);
1545 _rMultiSel
.Select( _nPos
);
1548 void OTableEditorCtrl::SetPrimaryKey( bool bSet
)
1550 // Delete any existing Primary Keys
1551 MultiSelection aDeletedPrimKeys
;
1552 aDeletedPrimKeys
.SetTotalRange( Range(0,GetRowCount()) );
1554 ::std::vector
< ::boost::shared_ptr
<OTableRow
> >::const_iterator aIter
= m_pRowList
->begin();
1555 ::std::vector
< ::boost::shared_ptr
<OTableRow
> >::const_iterator aEnd
= m_pRowList
->end();
1556 for(sal_Int32 nRow
= 0;aIter
!= aEnd
;++aIter
,++nRow
)
1558 OFieldDescription
* pFieldDescr
= (*aIter
)->GetActFieldDescr();
1559 if( pFieldDescr
&& (*aIter
)->IsPrimaryKey() && (!bSet
|| !IsRowSelected(nRow
)) )
1561 AdjustFieldDescription(pFieldDescr
,aDeletedPrimKeys
,nRow
,bSet
,false);
1565 // Set the primary keys of the marked rows
1566 MultiSelection aInsertedPrimKeys
;
1567 aInsertedPrimKeys
.SetTotalRange( Range(0,GetRowCount()) );
1570 long nIndex
= FirstSelectedRow();
1571 while( nIndex
>= 0 && nIndex
< static_cast<long>(m_pRowList
->size()) )
1574 ::boost::shared_ptr
<OTableRow
> pRow
= (*m_pRowList
)[nIndex
];
1575 OFieldDescription
* pFieldDescr
= pRow
->GetActFieldDescr();
1577 AdjustFieldDescription(pFieldDescr
,aInsertedPrimKeys
,nIndex
,false,true);
1579 nIndex
= NextSelectedRow();
1583 GetUndoManager().AddUndoAction( new OPrimKeyUndoAct(this, aDeletedPrimKeys
, aInsertedPrimKeys
) );
1585 // Invalidate the handle-columns
1586 InvalidateHandleColumn();
1588 // Set the TableDocSh's ModifyFlag
1589 GetView()->getController().setModified( sal_True
);
1590 InvalidateFeatures();
1593 bool OTableEditorCtrl::IsPrimaryKey()
1595 // Are all marked fields part of the Primary Key ?
1596 long nPrimaryKeys
= 0;
1597 ::std::vector
< ::boost::shared_ptr
<OTableRow
> >::const_iterator aIter
= m_pRowList
->begin();
1598 ::std::vector
< ::boost::shared_ptr
<OTableRow
> >::const_iterator aEnd
= m_pRowList
->end();
1599 for(sal_Int32 nRow
=0;aIter
!= aEnd
;++aIter
,++nRow
)
1601 if( IsRowSelected(nRow
) && !(*aIter
)->IsPrimaryKey() )
1603 if( (*aIter
)->IsPrimaryKey() )
1607 // Are there any unselected fields that are part of the Key ?
1608 return GetSelectRowCount() == nPrimaryKeys
;
1611 void OTableEditorCtrl::SwitchType( const TOTypeInfoSP
& _pType
)
1613 // if there is no assigned field name
1614 long nRow(GetCurRow());
1615 OFieldDescription
* pActFieldDescr
= GetFieldDescr( nRow
);
1616 if( pActFieldDescr
)
1617 // Store the old description
1618 pDescrWin
->SaveData( pActFieldDescr
);
1620 if ( nRow
< 0 || nRow
> static_cast<long>(m_pRowList
->size()) )
1622 // Show the new description
1623 ::boost::shared_ptr
<OTableRow
> pRow
= (*m_pRowList
)[nRow
];
1624 pRow
->SetFieldType( _pType
, true );
1627 const sal_Int32 nCurrentlySelected
= pTypeCell
->GetSelectEntryPos();
1629 if ( ( LISTBOX_ENTRY_NOTFOUND
== nCurrentlySelected
)
1630 || ( GetView()->getController().getTypeInfo( nCurrentlySelected
) != _pType
)
1633 sal_Int32 nEntryPos
= 0;
1634 const OTypeInfoMap
& rTypeInfo
= GetView()->getController().getTypeInfo();
1635 OTypeInfoMap::const_iterator aIter
= rTypeInfo
.begin();
1636 OTypeInfoMap::const_iterator aEnd
= rTypeInfo
.end();
1637 for(;aIter
!= aEnd
;++aIter
,++nEntryPos
)
1639 if(aIter
->second
== _pType
)
1642 if (nEntryPos
< pTypeCell
->GetEntryCount())
1643 pTypeCell
->SelectEntryPos( nEntryPos
);
1647 pActFieldDescr
= pRow
->GetActFieldDescr();
1648 if (pActFieldDescr
!= NULL
&& !pActFieldDescr
->GetFormatKey())
1650 sal_Int32 nFormatKey
= ::dbtools::getDefaultNumberFormat( pActFieldDescr
->GetType(),
1651 pActFieldDescr
->GetScale(),
1652 pActFieldDescr
->IsCurrency(),
1653 Reference
< XNumberFormatTypes
>(GetView()->getController().getNumberFormatter()->getNumberFormatsSupplier()->getNumberFormats(),UNO_QUERY
),
1654 GetView()->getLocale());
1656 pActFieldDescr
->SetFormatKey(nFormatKey
);
1659 pDescrWin
->DisplayData( pActFieldDescr
);
1662 OTableDesignView
* OTableEditorCtrl::GetView() const
1664 return static_cast<OTableDesignView
*>(GetParent()->GetParent());
1667 void OTableEditorCtrl::DeactivateCell(bool bUpdate
)
1669 OTableRowView::DeactivateCell(bUpdate
);
1670 // now we have to deactivate the field description
1671 long nRow(GetCurRow());
1673 pDescrWin
->SetReadOnly(bReadOnly
|| !SetDataPtr(nRow
) || GetActRow()->IsReadOnly());
1676 bool OTableEditorCtrl::PreNotify( NotifyEvent
& rNEvt
)
1678 if (rNEvt
.GetType() == MouseNotifyEvent::GETFOCUS
)
1680 if( pHelpTextCell
&& pHelpTextCell
->HasChildPathFocus() )
1681 m_eChildFocus
= HELPTEXT
;
1682 else if( pDescrCell
&& pDescrCell
->HasChildPathFocus() )
1683 m_eChildFocus
= DESCRIPTION
;
1684 else if(pNameCell
&& pNameCell
->HasChildPathFocus() )
1685 m_eChildFocus
= NAME
;
1687 m_eChildFocus
= ROW
;
1690 return OTableRowView::PreNotify(rNEvt
);
1693 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */