update dev300-m58
[ooovba.git] / dbaccess / source / ui / tabledesign / TEditControl.cxx
blob53022b5ad094c684de4edd5139dc3a49ccfb60cf
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: TEditControl.cxx,v $
10 * $Revision: 1.60.26.1 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_dbaccess.hxx"
33 #ifndef DBAUI_TABLEEDITORCONTROL_HXX
34 #include "TEditControl.hxx"
35 #endif
36 #ifndef _TOOLS_DEBUG_HXX
37 #include <tools/debug.hxx>
38 #endif
39 #ifndef _COM_SUN_STAR_SDBC_XDATABASEMETADATA_HPP_
40 #include <com/sun/star/sdbc/XDatabaseMetaData.hpp>
41 #endif
42 #ifndef _COM_SUN_STAR_SDBCX_XCOLUMNSSUPPLIER_HPP_
43 #include <com/sun/star/sdbcx/XColumnsSupplier.hpp>
44 #endif
45 #ifndef _COM_SUN_STAR_SDBCX_XALTERTABLE_HPP_
46 #include <com/sun/star/sdbcx/XAlterTable.hpp>
47 #endif
48 #ifndef _COM_SUN_STAR_SDBCX_XDROP_HPP_
49 #include <com/sun/star/sdbcx/XDrop.hpp>
50 #endif
51 #ifndef _COM_SUN_STAR_SDBCX_XAPPEND_HPP_
52 #include <com/sun/star/sdbcx/XAppend.hpp>
53 #endif
54 #ifndef _COM_SUN_STAR_BEANS_PROPERTYATTRIBUTE_HPP_
55 #include <com/sun/star/beans/PropertyAttribute.hpp>
56 #endif
57 #ifndef _COM_SUN_STAR_UTIL_XNUMBERFORMATTYPES_HPP_
58 #include <com/sun/star/util/XNumberFormatTypes.hpp>
59 #endif
60 #ifndef _DBU_TBL_HRC_
61 #include "dbu_tbl.hrc"
62 #endif
63 #ifndef DBACCESS_SHARED_DBUSTRINGS_HRC
64 #include "dbustrings.hrc"
65 #endif
66 #ifndef DBACCESS_UI_BROWSER_ID_HXX
67 #include "browserids.hxx"
68 #endif
69 #ifndef _DBA_DBACCESS_HELPID_HRC_
70 #include "dbaccess_helpid.hrc"
71 #endif
72 #ifndef _COMPHELPER_TYPES_HXX_
73 #include <comphelper/types.hxx>
74 #endif
75 #ifndef DBAUI_FIELDDESCRIPTIONCONTROL_HXX
76 #include "FieldDescControl.hxx"
77 #endif
78 #ifndef DBAUI_FIELDDESCRIPTIONS_HXX
79 #include "FieldDescriptions.hxx"
80 #endif
81 #ifndef _SV_MSGBOX_HXX
82 #include <vcl/msgbox.hxx>
83 #endif
84 #ifndef DBAUI_TABLEUNDO_HXX
85 #include "TableUndo.hxx"
86 #endif
87 #ifndef DBUI_TABLECONTROLLER_HXX
88 #include "TableController.hxx"
89 #endif
90 #ifndef _CONNECTIVITY_DBTOOLS_HXX_
91 #include <connectivity/dbtools.hxx>
92 #endif
93 #ifndef DBAUI_SQLNAMEEDIT_HXX
94 #include "SqlNameEdit.hxx"
95 #endif
96 #ifndef DBAUI_TABLEROW_EXCHANGE_HXX
97 #include "TableRowExchange.hxx"
98 #endif
99 #ifndef _SOT_STORAGE_HXX
100 #include <sot/storage.hxx>
101 #endif
102 #ifndef DBAUI_TOOLS_HXX
103 #include "UITools.hxx"
104 #endif
105 #ifndef DBAUI_FIELDDESCRIPTIONCONTROL_HXX
106 #include "FieldDescControl.hxx"
107 #endif
108 #ifndef DBAUI_TABLEFIELDCONTROL_HXX
109 #include "TableFieldControl.hxx"
110 #endif
112 using namespace ::dbaui;
113 using namespace ::comphelper;
114 using namespace ::svt;
115 using namespace ::com::sun::star::uno;
116 using namespace ::com::sun::star::container;
117 using namespace ::com::sun::star::io;
118 using namespace ::com::sun::star::beans;
119 using namespace ::com::sun::star::frame;
120 using namespace ::com::sun::star::util;
121 using namespace ::com::sun::star::lang;
122 using namespace ::com::sun::star::sdbc;
123 using namespace ::com::sun::star::sdbcx;
124 using namespace ::com::sun::star::sdb;
126 namespace dbaui
128 extern String GetTypeString( sal_uInt16 nType );
130 //==============================================================================
132 // TYPEINIT1(OTableEditorCtrl, DBView);
133 DBG_NAME(OTableEditorCtrl)
135 //==============================================================================
137 #define HANDLE_ID 0
139 // Anzahl Spalten beim Neuanlegen
140 #define NEWCOLS 128
142 // default Spaltenbreiten
143 #define FIELDNAME_WIDTH 100
144 #define FIELDTYPE_WIDTH 150
145 #define FIELDDESCR_WIDTH 300
147 // Maximale Eingabelaenge im Beschreibungsfeld
148 #define MAX_DESCR_LEN 256
151 #define CONTROL_SPACING_X 18 // 6
152 #define CONTROL_SPACING_Y 5
153 #define CONTROL_HEIGHT 20
154 #define CONTROL_WIDTH_1 140 // 100
155 #define CONTROL_WIDTH_2 100 // 60
156 #define CONTROL_WIDTH_3 250
157 #define CONTROL_WIDTH_4 (CONTROL_WIDTH_3 - CONTROL_HEIGHT - 5)
160 //==================================================================
161 DBG_NAME(ClipboardInvalidator)
162 //------------------------------------------------------------------
163 OTableEditorCtrl::ClipboardInvalidator::ClipboardInvalidator(ULONG nTimeout,OTableEditorCtrl* _pOwner)
164 : m_pOwner(_pOwner)
166 DBG_CTOR(ClipboardInvalidator,NULL);
168 m_aInvalidateTimer.SetTimeout(nTimeout);
169 m_aInvalidateTimer.SetTimeoutHdl(LINK(this, OTableEditorCtrl::ClipboardInvalidator, OnInvalidate));
170 m_aInvalidateTimer.Start();
173 //------------------------------------------------------------------
174 OTableEditorCtrl::ClipboardInvalidator::~ClipboardInvalidator()
176 m_aInvalidateTimer.Stop();
178 DBG_DTOR(ClipboardInvalidator,NULL);
181 //------------------------------------------------------------------
182 IMPL_LINK(OTableEditorCtrl::ClipboardInvalidator, OnInvalidate, void*, EMPTYARG)
184 m_pOwner->GetView()->getController().InvalidateFeature(SID_CUT);
185 m_pOwner->GetView()->getController().InvalidateFeature(SID_COPY);
186 m_pOwner->GetView()->getController().InvalidateFeature(SID_PASTE);
187 return 0L;
190 //==================================================================
191 void OTableEditorCtrl::Init()
193 DBG_CHKTHIS(OTableEditorCtrl,NULL);
194 OTableRowView::Init();
196 //////////////////////////////////////////////////////////////////////
197 // Soll der Entwurf ReadOnly geoeffnet werden ?
198 sal_Bool bRead(GetView()->getController().isReadOnly());
200 SetReadOnly( bRead );
202 //////////////////////////////////////////////////////////////////////
203 // Spalten einfuegen
204 String aColumnName( ModuleRes(STR_TAB_FIELD_COLUMN_NAME) );
205 InsertDataColumn( 1, aColumnName, FIELDNAME_WIDTH );
207 aColumnName = String( ModuleRes(STR_TAB_FIELD_COLUMN_DATATYPE) );
208 InsertDataColumn( 2, aColumnName, FIELDTYPE_WIDTH );
210 aColumnName = String( ModuleRes(STR_TAB_FIELD_DESCR) );
211 InsertDataColumn( 3, aColumnName, FIELDDESCR_WIDTH );
213 InitCellController();
215 //////////////////////////////////////////////////////////////////////
216 // Zeilen einfuegen
217 RowInserted(0, m_pRowList->size(), sal_True);
220 //==================================================================
221 void OTableEditorCtrl::UpdateAll()
223 DBG_CHKTHIS(OTableEditorCtrl,NULL);
224 RowRemoved(0, GetRowCount(), sal_False);
225 m_nDataPos = 0;
227 InvalidateFeatures();
228 Invalidate();
230 //==================================================================
231 OTableEditorCtrl::OTableEditorCtrl(Window* pWindow)
232 :OTableRowView(pWindow)
233 ,pNameCell(NULL)
234 ,pTypeCell(NULL)
235 ,pDescrCell(NULL)
236 ,pDescrWin(NULL)
237 ,nIndexEvent(0)
238 ,nCutEvent(0)
239 ,nPasteEvent(0)
240 ,nDeleteEvent(0)
241 ,nInsNewRowsEvent(0)
242 ,nInvalidateTypeEvent(0)
243 ,nEntryNotFoundEvent(0)
244 ,m_eChildFocus(NONE)
245 ,nOldDataPos(-1)
246 ,bSaveOnMove(sal_True)
247 ,bReadOnly(sal_True)
248 ,m_aInvalidate(500,this)
250 DBG_CTOR(OTableEditorCtrl,NULL);
252 SetHelpId(HID_TABDESIGN_BACKGROUND);
253 GetDataWindow().SetHelpId(HID_CTL_TABLEEDIT);
255 m_pRowList = GetView()->getController().getRows();
256 m_nDataPos = 0;
259 //------------------------------------------------------------------------------
260 SfxUndoManager* OTableEditorCtrl::GetUndoManager() const
262 return GetView()->getController().getUndoMgr();
265 //------------------------------------------------------------------------------
266 BOOL OTableEditorCtrl::IsReadOnly()
268 DBG_CHKTHIS(OTableEditorCtrl,NULL);
269 return bReadOnly;
272 //------------------------------------------------------------------------------
273 void OTableEditorCtrl::SetReadOnly( sal_Bool bRead )
275 // nix zu tun ?
276 if (bRead == IsReadOnly())
277 // diese Abfrage ist wichtig, da die zugrundeliegende Def sonst im folgenden gelockt oder ge-unlocked wird, obwohl es
278 // nicht notwendig waere (und was schlimmer ist, das wuerde dann auch nicht wieder rueckgaengig gemacht)
279 return;
281 DBG_CHKTHIS(OTableEditorCtrl,NULL);
282 bReadOnly = bRead;
284 //////////////////////////////////////////////////////////////////////
285 // Aktive Zelle disablen
286 long nRow(GetCurRow());
287 sal_uInt16 nCol(GetCurColumnId());
288 DeactivateCell();
290 //////////////////////////////////////////////////////////////////////
291 // ::com::sun::star::beans::Property Controls disablen
292 // if (pDescrWin)
293 // pDescrWin->SetReadOnly(bReadOnly || !SetDataPtr(nRow) || GetActRow()->IsReadOnly());
295 //////////////////////////////////////////////////////////////////////
296 // Cursor des Browsers anpassen
297 BrowserMode nMode(BROWSER_COLUMNSELECTION | BROWSER_MULTISELECTION | BROWSER_KEEPSELECTION |
298 BROWSER_HLINESFULL | BROWSER_VLINESFULL|BROWSER_AUTOSIZE_LASTCOL);
299 if( !bReadOnly )
300 nMode |= BROWSER_HIDECURSOR;
301 SetMode(nMode);
303 if( !bReadOnly )
304 ActivateCell( nRow, nCol );
307 //------------------------------------------------------------------------------
308 void OTableEditorCtrl::InitCellController()
310 DBG_CHKTHIS(OTableEditorCtrl,NULL);
311 //////////////////////////////////////////////////////////////////////
312 // Zelle Feldname
313 xub_StrLen nMaxTextLen = EDIT_NOLIMIT;
314 ::rtl::OUString sExtraNameChars;
315 Reference<XConnection> xCon;
318 xCon = GetView()->getController().getConnection();
319 Reference< XDatabaseMetaData> xMetaData = xCon.is() ? xCon->getMetaData() : Reference< XDatabaseMetaData>();
321 nMaxTextLen = ((xub_StrLen)xMetaData.is() ? static_cast<xub_StrLen>(xMetaData->getMaxColumnNameLength()) : 0);
323 if( nMaxTextLen == 0 )
324 nMaxTextLen = EDIT_NOLIMIT;
325 sExtraNameChars = xMetaData.is() ? xMetaData->getExtraNameCharacters() : ::rtl::OUString();
328 catch(SQLException&)
330 OSL_ASSERT(!"getMaxColumnNameLength");
333 pNameCell = new OSQLNameEdit( &GetDataWindow(), sExtraNameChars,WB_LEFT );
334 pNameCell->SetMaxTextLen( nMaxTextLen );
335 pNameCell->setCheck( isSQL92CheckEnabled(xCon) );
338 //////////////////////////////////////////////////////////////////////
339 // Zelle Typ
340 pTypeCell = new ListBoxControl( &GetDataWindow() );
341 pTypeCell->SetDropDownLineCount( 15 );
343 //////////////////////////////////////////////////////////////////////
344 // Zelle Beschreibung
345 pDescrCell = new Edit( &GetDataWindow(), WB_LEFT );
346 pDescrCell->SetMaxTextLen( MAX_DESCR_LEN );
348 pNameCell->SetHelpId(HID_TABDESIGN_NAMECELL);
349 pTypeCell->SetHelpId(HID_TABDESIGN_TYPECELL);
350 pDescrCell->SetHelpId(HID_TABDESIGN_COMMENTCELL);
352 Size aHeight;
353 const Control* pControls[] = { pTypeCell,pDescrCell,pNameCell};
354 for(sal_Size i= 0; i < sizeof(pControls)/sizeof(pControls[0]);++i)
356 const Size aTemp( pControls[i]->GetOptimalSize(WINDOWSIZE_PREFERRED) );
357 if ( aTemp.Height() > aHeight.Height() )
358 aHeight.Height() = aTemp.Height();
359 } // for(int i= 0; i < sizeof(pControls)/sizeof(pControls[0]);++i
360 SetDataRowHeight(aHeight.Height());
362 ClearModified();
365 //------------------------------------------------------------------------------
366 void OTableEditorCtrl::ClearModified()
368 DBG_CHKTHIS(OTableEditorCtrl,NULL);
369 pNameCell->ClearModifyFlag();
370 pDescrCell->ClearModifyFlag();
371 pTypeCell->SaveValue();
374 //------------------------------------------------------------------------------
375 OTableEditorCtrl::~OTableEditorCtrl()
377 DBG_DTOR(OTableEditorCtrl,NULL);
378 //////////////////////////////////////////////////////////////////////
379 // Undo-Manager zuruecksetzen
380 GetUndoManager()->Clear();
382 //////////////////////////////////////////////////////////////////////
383 // Moegliche Events aus Queue entfernen
384 if( nCutEvent )
385 Application::RemoveUserEvent( nCutEvent );
386 if( nPasteEvent )
387 Application::RemoveUserEvent( nPasteEvent );
388 if( nDeleteEvent )
389 Application::RemoveUserEvent( nDeleteEvent );
390 if( nInsNewRowsEvent )
391 Application::RemoveUserEvent( nInsNewRowsEvent );
392 if( nInvalidateTypeEvent )
393 Application::RemoveUserEvent( nInvalidateTypeEvent );
394 if( nEntryNotFoundEvent )
395 Application::RemoveUserEvent( nEntryNotFoundEvent );
397 //////////////////////////////////////////////////////////////////////
398 // Controltypen zerstoeren
399 delete pNameCell;
400 delete pTypeCell;
401 delete pDescrCell;
404 //------------------------------------------------------------------------------
405 sal_Bool OTableEditorCtrl::SetDataPtr( long nRow )
407 DBG_CHKTHIS(OTableEditorCtrl,NULL);
408 if(nRow == -1)
409 return sal_False;
411 OSL_ENSURE((xub_StrLen)nRow < m_pRowList->size(),"Row is greater than size!");
412 if(nRow >= (long)m_pRowList->size())
413 return sal_False;
414 pActRow = (*m_pRowList)[nRow];
415 return pActRow != NULL;
418 //------------------------------------------------------------------------------
419 sal_Bool OTableEditorCtrl::SeekRow(long _nRow)
421 // die Basisklasse braucht den Aufruf, da sie sich dort merkt, welche Zeile gepainted wird
422 EditBrowseBox::SeekRow(_nRow);
424 DBG_CHKTHIS(OTableEditorCtrl,NULL);
425 m_nCurrentPos = _nRow;
426 return SetDataPtr(_nRow);
429 //------------------------------------------------------------------------------
430 void OTableEditorCtrl::PaintCell(OutputDevice& rDev, const Rectangle& rRect,
431 sal_uInt16 nColumnId ) const
433 DBG_CHKTHIS(OTableEditorCtrl,NULL);
434 String aText( GetCellText( m_nCurrentPos, nColumnId ));
435 Point aPos(rRect.TopLeft());
436 Size TxtSize(GetDataWindow().GetTextWidth(aText), GetDataWindow().GetTextHeight());
438 if (aPos.X() < rRect.Right() || aPos.X() + TxtSize.Width() > rRect.Right() ||
439 aPos.Y() < rRect.Top() || aPos.Y() + TxtSize.Height() > rRect.Bottom())
440 rDev.SetClipRegion( rRect );
442 rDev.DrawText(aPos, aText);
444 if (rDev.IsClipRegion())
445 rDev.SetClipRegion();
446 // rDev.DrawText(rRect.TopLeft(), aText);
447 // rDev.SetClipRegion( );
450 //------------------------------------------------------------------------------
451 CellController* OTableEditorCtrl::GetController(long nRow, sal_uInt16 nColumnId)
453 DBG_CHKTHIS(OTableEditorCtrl,NULL);
454 //////////////////////////////////////////////////////////////////////
455 // Wenn EditorCtrl ReadOnly ist, darf nicht editiert werden
456 Reference<XPropertySet> xTable = GetView()->getController().getTable();
457 if (IsReadOnly() || ( xTable.is() &&
458 xTable->getPropertySetInfo()->hasPropertyByName(PROPERTY_TYPE) &&
459 ::comphelper::getString(xTable->getPropertyValue(PROPERTY_TYPE)) == ::rtl::OUString::createFromAscii("VIEW")))
460 return NULL;
462 //////////////////////////////////////////////////////////////////////
463 // Wenn Zeile ReadOnly ist, darf sie nicht editiert werden
464 SetDataPtr( nRow );
465 if( pActRow->IsReadOnly() )
466 return NULL;
468 OFieldDescription* pActFieldDescr = pActRow->GetActFieldDescr();
469 switch (nColumnId)
471 case FIELD_NAME:
472 return new EditCellController( pNameCell );
473 case FIELD_TYPE:
474 if (pActFieldDescr && (pActFieldDescr->GetName().getLength() != 0))
475 return new ListBoxCellController( pTypeCell );
476 else return NULL;
477 case FIELD_DESCR:
478 if (pActFieldDescr && (pActFieldDescr->GetName().getLength() != 0))
479 return new EditCellController( pDescrCell );
480 else return NULL;
481 default:
482 return NULL;
486 //------------------------------------------------------------------------------
487 void OTableEditorCtrl::InitController(CellControllerRef&, long nRow, sal_uInt16 nColumnId)
489 DBG_CHKTHIS(OTableEditorCtrl,NULL);
490 SeekRow( nRow == -1 ? GetCurRow() : nRow);
491 OFieldDescription* pActFieldDescr = pActRow->GetActFieldDescr();
492 String aInitString;
494 switch (nColumnId)
496 case FIELD_NAME:
497 if( pActFieldDescr )
498 aInitString = pActFieldDescr->GetName();
499 pNameCell->SetText( aInitString );
500 pNameCell->SaveValue();
501 break;
502 case FIELD_TYPE:
504 if ( pActFieldDescr && pActFieldDescr->getTypeInfo() )
505 aInitString = pActFieldDescr->getTypeInfo()->aUIName;
507 //////////////////////////////////////////////////////////////
508 // Anpassen des ComboBoxInhalts
509 pTypeCell->Clear();
510 if( !pActFieldDescr )
511 break;
513 const OTypeInfoMap* pTypeInfo = GetView()->getController().getTypeInfo();
514 OTypeInfoMap::const_iterator aIter = pTypeInfo->begin();
515 OTypeInfoMap::const_iterator aEnd = pTypeInfo->end();
516 for(;aIter != aEnd;++aIter)
517 pTypeCell->InsertEntry( aIter->second->aUIName );
518 pTypeCell->SelectEntry( aInitString );
521 break;
522 case FIELD_DESCR:
523 if( pActFieldDescr )
524 aInitString = pActFieldDescr->GetDescription();
525 pDescrCell->SetText( aInitString );
526 pDescrCell->SaveValue();
527 break;
532 //------------------------------------------------------------------------------
533 EditBrowseBox::RowStatus OTableEditorCtrl::GetRowStatus(long nRow) const
535 DBG_CHKTHIS(OTableEditorCtrl,NULL);
536 ( (OTableEditorCtrl*)this )->SetDataPtr( nRow );
537 if( !pActRow )
538 return EditBrowseBox::CLEAN;
539 if (nRow >= 0 && nRow == m_nDataPos)
541 if( pActRow->IsPrimaryKey() )
542 return EditBrowseBox::CURRENT_PRIMARYKEY;
543 return EditBrowseBox::CURRENT;
545 else
547 if( pActRow->IsPrimaryKey() )
548 return EditBrowseBox::PRIMARYKEY;
549 return EditBrowseBox::CLEAN;
553 //------------------------------------------------------------------------------
554 sal_Bool OTableEditorCtrl::SaveCurRow()
556 DBG_CHKTHIS(OTableEditorCtrl,NULL);
557 if (GetFieldDescr(GetCurRow()) == NULL)
558 // in der Zeile, in der ich mich i.A. befinde, stehen keine Daten
559 return sal_True;
560 if (!SaveModified())
561 return sal_False;
563 SetDataPtr(GetCurRow());
564 pDescrWin->SaveData( pActRow->GetActFieldDescr() );
565 return sal_True;
568 //------------------------------------------------------------------------------
569 void OTableEditorCtrl::DisplayData(long nRow, sal_Bool bGrabFocus)
571 // zur richtigen Zelle fahren
572 SetDataPtr(nRow);
574 // Editier-Modus temporaer aus
575 sal_Bool bWasEditing = IsEditing();
576 if (bWasEditing)
577 DeactivateCell();
579 CellControllerRef aTemp;
580 InitController(aTemp, nRow, FIELD_NAME);
581 InitController(aTemp, nRow, FIELD_TYPE);
582 InitController(aTemp, nRow, FIELD_DESCR);
584 GoToRow(nRow);
585 // das Description-Window aktualisieren
586 GetView()->GetDescWin()->DisplayData(GetFieldDescr(nRow));
587 // neu zeichnen
588 RowModified(nRow);
590 // wieder an
591 if (bWasEditing || bGrabFocus)
592 ActivateCell(nRow, GetCurColumnId(), bGrabFocus);
595 //------------------------------------------------------------------------------
596 void OTableEditorCtrl::CursorMoved()
598 DBG_CHKTHIS(OTableEditorCtrl,NULL);
599 //////////////////////////////////////////////////////////////////////
600 // Zeilenwechsel ?
601 m_nDataPos = GetCurRow();
602 if( m_nDataPos != nOldDataPos && m_nDataPos != -1)
604 CellControllerRef aTemp;
605 InitController(aTemp,m_nDataPos,FIELD_NAME);
606 InitController(aTemp,m_nDataPos,FIELD_TYPE);
607 InitController(aTemp,m_nDataPos,FIELD_DESCR);
610 OTableRowView::CursorMoved();
613 //------------------------------------------------------------------------------
614 sal_Int32 OTableEditorCtrl::HasFieldName( const String& rFieldName )
616 DBG_CHKTHIS(OTableEditorCtrl,NULL);
618 Reference<XConnection> xCon = GetView()->getController().getConnection();
619 Reference< XDatabaseMetaData> xMetaData = xCon.is() ? xCon->getMetaData() : Reference< XDatabaseMetaData>();
621 ::comphelper::UStringMixEqual bCase(xMetaData.is() ? xMetaData->supportsMixedCaseQuotedIdentifiers() : sal_True);
623 ::std::vector< ::boost::shared_ptr<OTableRow> >::iterator aIter = m_pRowList->begin();
624 ::std::vector< ::boost::shared_ptr<OTableRow> >::iterator aEnd = m_pRowList->end();
625 OFieldDescription* pFieldDescr;
626 sal_Int32 nCount(0);
627 for(;aIter != aEnd;++aIter)
629 pFieldDescr = (*aIter)->GetActFieldDescr();
630 if( pFieldDescr && bCase(rFieldName,pFieldDescr->GetName()))
631 nCount++;
633 return nCount;
635 // --------------------------------------------------------------------------------------
636 sal_Bool OTableEditorCtrl::SaveData(long nRow, sal_uInt16 nColId)
638 DBG_CHKTHIS(OTableEditorCtrl,NULL);
639 //////////////////////////////////////////////////////////////
640 // Zellinhalte in Datenstruktur speichern
641 SetDataPtr( nRow == -1 ? GetCurRow() : nRow);
642 OFieldDescription* pActFieldDescr = pActRow->GetActFieldDescr();
644 switch( nColId)
646 //////////////////////////////////////////////////////////////
647 // Speichern Inhalt NameCell
648 case FIELD_NAME:
650 //////////////////////////////////////////////////////////////
651 // Wenn kein Name, nichts machen
652 String aName(pNameCell->GetText());
654 if( !aName.Len() )
656 //////////////////////////////////////////////////////////////
657 // Wenn FieldDescr existiert, wurde Feld geloescht und alter Inhalt wird wiederhergestellt
658 if (pActFieldDescr)
660 GetUndoManager()->AddUndoAction(new OTableEditorTypeSelUndoAct(this, nRow, FIELD_TYPE, pActFieldDescr->getTypeInfo()));
661 SwitchType(TOTypeInfoSP());
662 pActFieldDescr = pActRow->GetActFieldDescr();
664 else
665 return sal_True;
667 if(pActFieldDescr)
668 pActFieldDescr->SetName( aName );
669 pNameCell->ClearModifyFlag();
671 break;
674 //////////////////////////////////////////////////////////////
675 // Speichern Inhalt TypeCell
676 case FIELD_TYPE:
677 break;
679 //////////////////////////////////////////////////////////////
680 // Speichern Inhalt DescrCell
681 case FIELD_DESCR:
683 //////////////////////////////////////////////////////////////
684 // Wenn aktuelle Feldbeschreibung NULL, Default setzen
685 if( !pActFieldDescr )
687 pDescrCell->SetText(String());
688 pDescrCell->ClearModifyFlag();
690 else
691 pActFieldDescr->SetDescription( pDescrCell->GetText() );
692 break;
694 case FIELD_PROPERTY_DEFAULT:
695 case FIELD_PROPERTY_REQUIRED:
696 case FIELD_PROPERTY_TEXTLEN:
697 case FIELD_PROPERTY_NUMTYPE:
698 case FIELD_PROPERTY_AUTOINC:
699 case FIELD_PROPERTY_LENGTH:
700 case FIELD_PROPERTY_SCALE:
701 case FIELD_PROPERTY_BOOL_DEFAULT:
702 pDescrWin->SaveData(pActFieldDescr);
704 if ( FIELD_PROPERTY_AUTOINC == nColId && pActFieldDescr->IsAutoIncrement() )
706 OTableController& rController = GetView()->getController();
707 if ( rController.isAutoIncrementPrimaryKey() )
709 pActFieldDescr->SetPrimaryKey( true );
710 InvalidateHandleColumn();
711 Invalidate();
714 break;
716 return sal_True;
719 //------------------------------------------------------------------------------
720 sal_Bool OTableEditorCtrl::SaveModified()
722 DBG_CHKTHIS(OTableEditorCtrl,NULL);
723 sal_uInt16 nColId = GetCurColumnId();
725 switch( nColId )
727 //////////////////////////////////////////////////////////////
728 // NameCell
729 case FIELD_NAME:
731 // removed the former duplicate-check. this is done in OTableDocShell::CheckDefConsistency now.
732 // FS - 07.12.99 - 69575
734 } break;
736 //////////////////////////////////////////////////////////////
737 // TypeCell
738 case FIELD_TYPE:
740 //////////////////////////////////////////////////////////////////////
741 // Type umstellen
742 resetType();
743 } break;
746 return sal_True;
749 //------------------------------------------------------------------------------
750 sal_Bool OTableEditorCtrl::CursorMoving(long nNewRow, sal_uInt16 nNewCol)
752 DBG_CHKTHIS(OTableEditorCtrl,NULL);
754 if (!EditBrowseBox::CursorMoving(nNewRow, nNewCol))
755 return sal_False;
757 //////////////////////////////////////////////////////////////////////
758 // Wird nach SaveModified() gerufen, aktuelle Zeile ist noch die alte
759 m_nDataPos = nNewRow;
760 nOldDataPos = GetCurRow();
762 //////////////////////////////////////////////////////////////////////
763 // Marker umsetzen
764 InvalidateStatusCell( nOldDataPos );
765 InvalidateStatusCell( m_nDataPos );
767 //////////////////////////////////////////////////////////////////////
768 // Daten des Propertyfensters speichern
769 if( SetDataPtr(nOldDataPos) && pDescrWin)
770 pDescrWin->SaveData( pActRow->GetActFieldDescr() );
772 //////////////////////////////////////////////////////////////////////
773 // Neue Daten im Propertyfenster anzeigen
774 if( SetDataPtr(m_nDataPos) && pDescrWin)
775 pDescrWin->DisplayData( pActRow->GetActFieldDescr() );
777 return sal_True;
780 //------------------------------------------------------------------------------
781 IMPL_LINK( OTableEditorCtrl, InvalidateFieldType, void*, /*EMPTYTAG*/ )
783 DBG_CHKTHIS(OTableEditorCtrl,NULL);
784 nInvalidateTypeEvent = 0;
785 Invalidate( GetFieldRectPixel(nOldDataPos, FIELD_TYPE) );
787 return 0;
790 //------------------------------------------------------------------------------
791 IMPL_LINK( OTableEditorCtrl, EntryNotFound, void*, /*EMPTYTAG*/ )
793 DBG_CHKTHIS(OTableEditorCtrl,NULL);
794 nEntryNotFoundEvent = 0;
795 ErrorBox( this, ModuleRes(ERR_INVALID_LISTBOX_ENTRY) ).Execute();
797 return 0;
800 //------------------------------------------------------------------------------
801 void OTableEditorCtrl::CellModified( long nRow, sal_uInt16 nColId )
803 DBG_CHKTHIS(OTableEditorCtrl,NULL);
805 //////////////////////////////////////////////////////////////
806 // Wenn aktuelle Feldbeschreibung NULL, Default setzen
807 if(nRow == -1)
808 nRow = GetCurRow();
809 SetDataPtr( nRow );
810 OFieldDescription* pActFieldDescr = pActRow->GetActFieldDescr();
812 String sActionDescription;
813 switch ( nColId )
815 case FIELD_NAME: sActionDescription = String( ModuleRes( STR_CHANGE_COLUMN_NAME ) ); break;
816 case FIELD_TYPE: sActionDescription = String( ModuleRes( STR_CHANGE_COLUMN_TYPE ) ); break;
817 case FIELD_DESCR: sActionDescription = String( ModuleRes( STR_CHANGE_COLUMN_DESCRIPTION ) ); break;
818 default: sActionDescription = String( ModuleRes( STR_CHANGE_COLUMN_ATTRIBUTE ) ); break;
821 GetUndoManager()->EnterListAction( sActionDescription, String() );
822 if (!pActFieldDescr)
824 const OTypeInfoMap* pTypeInfoMap = GetView()->getController().getTypeInfo();
825 if ( !pTypeInfoMap->empty() )
827 OTypeInfoMap::const_iterator aTypeIter = pTypeInfoMap->find(DataType::VARCHAR);
828 if ( aTypeIter == pTypeInfoMap->end() )
829 aTypeIter = pTypeInfoMap->begin();
830 pActRow->SetFieldType( aTypeIter->second );
832 else
833 pActRow->SetFieldType( GetView()->getController().getTypeInfoFallBack() );
835 nInvalidateTypeEvent = Application::PostUserEvent( LINK(this, OTableEditorCtrl, InvalidateFieldType) );
836 pActFieldDescr = pActRow->GetActFieldDescr();
837 pDescrWin->DisplayData( pActFieldDescr );
838 GetUndoManager()->AddUndoAction( new OTableEditorTypeSelUndoAct(this, nRow, nColId+1, TOTypeInfoSP()) );
841 if( nColId != FIELD_TYPE )
842 GetUndoManager()->AddUndoAction( new OTableDesignCellUndoAct(this, nRow, nColId) );
843 else
845 GetUndoManager()->AddUndoAction(new OTableEditorTypeSelUndoAct(this, GetCurRow(), nColId, GetFieldDescr(GetCurRow())->getTypeInfo()));
846 resetType();
849 SaveData(nRow,nColId);
850 // SaveData could create a undo action as well
851 GetUndoManager()->LeaveListAction();
852 RowModified(nRow);
853 CellControllerRef xController(Controller());
854 if(xController.Is())
855 xController->SetModified();
857 //////////////////////////////////////////////////////////////////////
858 // Das ModifyFlag setzen
859 GetView()->getController().setModified( sal_True );
860 InvalidateFeatures();
862 // -----------------------------------------------------------------------------
863 void OTableEditorCtrl::resetType()
865 USHORT nPos = pTypeCell->GetSelectEntryPos();
866 if(nPos != LISTBOX_ENTRY_NOTFOUND)
867 SwitchType( GetView()->getController().getTypeInfo(nPos) );
868 else
869 SwitchType(TOTypeInfoSP());
871 //------------------------------------------------------------------------------
872 void OTableEditorCtrl::CellModified()
874 DBG_CHKTHIS(OTableEditorCtrl,NULL);
875 CellModified( GetCurRow(), GetCurColumnId() );
877 // -----------------------------------------------------------------------------
878 void OTableEditorCtrl::InvalidateFeatures()
880 GetView()->getController().InvalidateFeature(SID_UNDO);
881 GetView()->getController().InvalidateFeature(SID_REDO);
882 GetView()->getController().InvalidateFeature(SID_SAVEDOC);
884 //------------------------------------------------------------------------------
885 void OTableEditorCtrl::Undo()
887 DBG_CHKTHIS(OTableEditorCtrl,NULL);
889 InvalidateFeatures();
891 //------------------------------------------------------------------------------
892 void OTableEditorCtrl::Redo()
894 DBG_CHKTHIS(OTableEditorCtrl,NULL);
895 InvalidateFeatures();
898 //------------------------------------------------------------------------------
899 void OTableEditorCtrl::CopyRows()
901 DBG_CHKTHIS(OTableEditorCtrl,NULL);
902 //////////////////////////////////////////////////////////////////////
903 // set to the right row and save it
904 if( SetDataPtr(m_nDataPos) )
905 pDescrWin->SaveData( pActRow->GetActFieldDescr() );
907 //////////////////////////////////////////////////////////////////////
908 // Selektierte Zeilen in die ClipboardListe kopieren
909 ::boost::shared_ptr<OTableRow> pClipboardRow;
910 ::boost::shared_ptr<OTableRow> pRow;
911 ::std::vector< ::boost::shared_ptr<OTableRow> > vClipboardList;
912 vClipboardList.reserve(GetSelectRowCount());
914 for( long nIndex=FirstSelectedRow(); nIndex >= 0 && nIndex < static_cast<long>(m_pRowList->size()); nIndex=NextSelectedRow() )
916 pRow = (*m_pRowList)[nIndex];
917 OSL_ENSURE(pRow,"OTableEditorCtrl::CopyRows: Row is NULL!");
918 if ( pRow && pRow->GetActFieldDescr() )
920 pClipboardRow.reset(new OTableRow( *pRow ));
921 vClipboardList.push_back( pClipboardRow);
924 if(!vClipboardList.empty())
926 OTableRowExchange* pData = new OTableRowExchange(vClipboardList);
927 Reference< ::com::sun::star::datatransfer::XTransferable> xRef = pData;
928 pData->CopyToClipboard(GetParent());
932 //------------------------------------------------------------------------------
933 String OTableEditorCtrl::GenerateName( const String& rName )
935 DBG_CHKTHIS(OTableEditorCtrl,NULL);
936 //////////////////////////////////////////////////////////////////////
937 // Basisnamen zum Anhaengen einer Numerierung erstellen
938 String aBaseName;
939 Reference<XConnection> xCon = GetView()->getController().getConnection();
940 Reference< XDatabaseMetaData> xMetaData = xCon.is() ? xCon->getMetaData() : Reference< XDatabaseMetaData>();
942 xub_StrLen nMaxTextLen((xub_StrLen)( xMetaData.is() ? xMetaData->getMaxColumnNameLength() : 0));
944 if( (rName.Len()+2) >nMaxTextLen )
945 aBaseName = rName.Copy( 0, nMaxTextLen-2 );
946 else
947 aBaseName = rName;
949 //////////////////////////////////////////////////////////////////////
950 // Namen durchnumerieren (bis 99)
951 String aFieldName( rName);
952 sal_Int32 i=1;
953 while( HasFieldName(aFieldName) )
955 aFieldName = aBaseName;
956 aFieldName += String::CreateFromInt32(i);
957 i++;
960 return aFieldName;
963 //------------------------------------------------------------------------------
964 void OTableEditorCtrl::InsertRows( long nRow )
966 DBG_CHKTHIS(OTableEditorCtrl,NULL);
968 ::std::vector< ::boost::shared_ptr<OTableRow> > vInsertedUndoRedoRows; // need for undo/redo handling
969 //////////////////////////////////////////////////////////////////////
970 // get rows from clipboard
971 TransferableDataHelper aTransferData(TransferableDataHelper::CreateFromSystemClipboard(GetParent()));
972 if(aTransferData.HasFormat(SOT_FORMATSTR_ID_SBA_TABED))
974 SotStorageStreamRef aStreamRef;
975 aTransferData.GetSotStorageStream(SOT_FORMATSTR_ID_SBA_TABED,aStreamRef);
976 if(aStreamRef.Is())
978 aStreamRef->Seek(STREAM_SEEK_TO_BEGIN);
979 aStreamRef->ResetError();
980 long nInsertRow = nRow;
981 String aFieldName;
982 ::boost::shared_ptr<OTableRow> pRow;
983 sal_Int32 nSize = 0;
984 (*aStreamRef) >> nSize;
985 vInsertedUndoRedoRows.reserve(nSize);
986 for(sal_Int32 i=0;i < nSize;++i)
988 pRow.reset(new OTableRow());
989 (*aStreamRef) >> *pRow;
990 pRow->SetReadOnly( sal_False );
991 sal_Int32 nType = pRow->GetActFieldDescr()->GetType();
992 if ( pRow->GetActFieldDescr() )
993 pRow->GetActFieldDescr()->SetType(GetView()->getController().getTypeInfoByType(nType));
994 //////////////////////////////////////////////////////////////////////
995 // Anpassen des Feldnamens
996 aFieldName = GenerateName( pRow->GetActFieldDescr()->GetName() );
997 pRow->GetActFieldDescr()->SetName( aFieldName );
998 pRow->SetPos(nInsertRow);
999 m_pRowList->insert( m_pRowList->begin()+nInsertRow,pRow );
1000 vInsertedUndoRedoRows.push_back(::boost::shared_ptr<OTableRow>(new OTableRow(*pRow)));
1001 nInsertRow++;
1005 //////////////////////////////////////////////////////////////////////
1006 // Beim RowInserted wird CursorMoved gerufen.
1007 // Die UI-Daten duerfen hier beim CursorMoved nicht gespeichert werden.
1008 bSaveOnMove = sal_False;
1009 RowInserted( nRow,vInsertedUndoRedoRows.size(),sal_True );
1010 bSaveOnMove = sal_True;
1012 //////////////////////////////////////////////////////////////////////
1013 // Undo-Action erzeugen
1014 GetUndoManager()->AddUndoAction( new OTableEditorInsUndoAct(this, nRow,vInsertedUndoRedoRows) );
1015 GetView()->getController().setModified( sal_True );
1016 InvalidateFeatures();
1019 //------------------------------------------------------------------------------
1020 void OTableEditorCtrl::DeleteRows()
1022 DBG_CHKTHIS(OTableEditorCtrl,NULL);
1023 OSL_ENSURE(GetView()->getController().isDropAllowed(),"Call of DeleteRows not valid here. Please check isDropAllowed!");
1024 //////////////////////////////////////////////////////////////////////
1025 // Undo-Action erzeugen
1026 GetUndoManager()->AddUndoAction( new OTableEditorDelUndoAct(this) );
1029 //////////////////////////////////////////////////////////////////////
1030 // Alle markierten Zeilen loeschen
1031 long nIndex = FirstSelectedRow();
1032 nOldDataPos = nIndex;
1033 bSaveOnMove = sal_False;
1035 while( nIndex >= 0 && nIndex < static_cast<long>(m_pRowList->size()) )
1037 //////////////////////////////////////////////////////////////////////
1038 // Zeile entfernen
1039 m_pRowList->erase( m_pRowList->begin()+nIndex );
1040 RowRemoved( nIndex, 1, sal_True );
1042 //////////////////////////////////////////////////////////////////////
1043 // Leerzeile am Ende wieder einfuegen
1044 m_pRowList->push_back( ::boost::shared_ptr<OTableRow>(new OTableRow()));
1045 RowInserted( GetRowCount()-1, 1, sal_True );
1047 nIndex = FirstSelectedRow();
1050 bSaveOnMove = sal_True;
1052 //////////////////////////////////////////////////////////////////////
1053 // Erzwingen, dass der aktuelle Datensatz angezeigt wird
1054 m_nDataPos = GetCurRow();
1055 InvalidateStatusCell( nOldDataPos );
1056 InvalidateStatusCell( m_nDataPos );
1057 SetDataPtr( m_nDataPos );
1058 ActivateCell();
1059 pDescrWin->DisplayData( pActRow->GetActFieldDescr() );
1060 GetView()->getController().setModified( sal_True );
1061 InvalidateFeatures();
1064 //------------------------------------------------------------------------------
1065 void OTableEditorCtrl::InsertNewRows( long nRow )
1067 DBG_CHKTHIS(OTableEditorCtrl,NULL);
1068 OSL_ENSURE(GetView()->getController().isAddAllowed(),"Call of InsertNewRows not valid here. Please check isAppendAllowed!");
1069 //////////////////////////////////////////////////////////////////////
1070 // Undo-Action erzeugen
1071 long nInsertRows = GetSelectRowCount();
1072 if( !nInsertRows )
1073 nInsertRows = 1;
1074 GetUndoManager()->AddUndoAction( new OTableEditorInsNewUndoAct(this, nRow, nInsertRows) );
1075 //////////////////////////////////////////////////////////////////////
1076 // Zahl der selektierten Zeilen werden neu eingefuegt
1077 for( long i=nRow; i<(nRow+nInsertRows); i++ )
1078 m_pRowList->insert( m_pRowList->begin()+i ,::boost::shared_ptr<OTableRow>(new OTableRow()));
1079 RowInserted( nRow, nInsertRows, sal_True );
1081 GetView()->getController().setModified( sal_True );
1082 InvalidateFeatures();
1085 //------------------------------------------------------------------------------
1086 String OTableEditorCtrl::GetControlText( long nRow, sal_uInt16 nColId )
1088 DBG_CHKTHIS(OTableEditorCtrl,NULL);
1089 //////////////////////////////////////////////////////////////////////
1090 // Controls des Browsers auslesen
1091 if( nColId < FIELD_FIRST_VIRTUAL_COLUMN )
1093 GoToRow( nRow );
1094 GoToColumnId( nColId );
1095 CellControllerRef xController = Controller();
1096 if(xController.Is())
1097 return xController->GetWindow().GetText();
1098 else
1099 return GetCellText(nRow,nColId);
1102 //////////////////////////////////////////////////////////////////////
1103 // Controls der Tabpage Auslesen
1104 else
1105 return pDescrWin->GetControlText( nColId );
1108 //------------------------------------------------------------------------------
1109 void OTableEditorCtrl::SetControlText( long nRow, sal_uInt16 nColId, const String& rText )
1111 DBG_CHKTHIS(OTableEditorCtrl,NULL);
1112 //////////////////////////////////////////////////////////////////////
1113 // Controls des Browsers setzen
1114 if( nColId < FIELD_FIRST_VIRTUAL_COLUMN )
1116 GoToRow( nRow );
1117 GoToColumnId( nColId );
1118 CellControllerRef xController = Controller();
1119 if(xController.Is())
1120 xController->GetWindow().SetText( rText );
1121 else
1122 RowModified(nRow,nColId);
1125 //////////////////////////////////////////////////////////////////////
1126 // Controls der Tabpage setzen
1127 else
1129 pDescrWin->SetControlText( nColId, rText );
1132 //------------------------------------------------------------------------------
1133 void OTableEditorCtrl::SetCellData( long nRow, sal_uInt16 nColId, const TOTypeInfoSP& _pTypeInfo )
1135 DBG_CHKTHIS(OTableEditorCtrl,NULL);
1136 //////////////////////////////////////////////////////////////////////
1137 // Aktuellen Datenzeiger umsetzen
1138 if( nRow == -1 )
1139 nRow = GetCurRow();
1140 OFieldDescription* pFieldDescr = GetFieldDescr( nRow );
1141 if( !pFieldDescr && nColId != FIELD_TYPE)
1142 return;
1144 //////////////////////////////////////////////////////////////////////
1145 // Einzelne Felder setzen
1146 switch( nColId )
1148 case FIELD_TYPE:
1149 SwitchType( _pTypeInfo );
1150 break;
1151 default:
1152 OSL_ENSURE(sal_False, "OTableEditorCtrl::SetCellData: invalid column!");
1154 SetControlText(nRow,nColId,_pTypeInfo.get() ? _pTypeInfo->aUIName : ::rtl::OUString());
1156 //------------------------------------------------------------------------------
1157 void OTableEditorCtrl::SetCellData( long nRow, sal_uInt16 nColId, const ::com::sun::star::uno::Any& _rNewData )
1159 DBG_CHKTHIS(OTableEditorCtrl,NULL);
1160 //////////////////////////////////////////////////////////////////////
1161 // Aktuellen Datenzeiger umsetzen
1162 if( nRow == -1 )
1163 nRow = GetCurRow();
1164 OFieldDescription* pFieldDescr = GetFieldDescr( nRow );
1165 if( !pFieldDescr && nColId != FIELD_TYPE)
1166 return;
1168 String sValue;
1169 //////////////////////////////////////////////////////////////////////
1170 // Einzelne Felder setzen
1171 switch( nColId )
1173 case FIELD_NAME:
1174 sValue = ::comphelper::getString(_rNewData);
1175 pFieldDescr->SetName( sValue );
1176 break;
1178 case FIELD_TYPE:
1179 OSL_ENSURE(sal_False, "OTableEditorCtrl::SetCellData: invalid column!");
1180 break;
1182 case FIELD_DESCR:
1183 pFieldDescr->SetDescription( sValue = ::comphelper::getString(_rNewData) );
1184 break;
1186 case FIELD_PROPERTY_DEFAULT:
1187 pFieldDescr->SetControlDefault( _rNewData );
1188 sValue = GetView()->GetDescWin()->getGenPage()->getFieldControl()->getControlDefault(pFieldDescr);
1189 break;
1191 case FIELD_PROPERTY_REQUIRED:
1193 sValue = ::comphelper::getString(_rNewData);
1194 pFieldDescr->SetIsNullable( sValue.ToInt32() );
1196 break;
1198 case FIELD_PROPERTY_TEXTLEN:
1199 case FIELD_PROPERTY_LENGTH:
1201 sValue = ::comphelper::getString(_rNewData);
1202 pFieldDescr->SetPrecision( sValue.ToInt32() );
1204 break;
1206 case FIELD_PROPERTY_NUMTYPE:
1207 // pFieldDescr->SetNumType( _rNewData );
1208 OSL_ENSURE(sal_False, "OTableEditorCtrl::SetCellData: invalid column!");
1209 break;
1211 case FIELD_PROPERTY_AUTOINC:
1213 String strYes(ModuleRes(STR_VALUE_YES));
1214 sValue = ::comphelper::getString(_rNewData);
1215 pFieldDescr->SetAutoIncrement(sValue.Equals(strYes));
1217 break;
1218 case FIELD_PROPERTY_SCALE:
1220 sValue = ::comphelper::getString(_rNewData);
1221 pFieldDescr->SetScale(sValue.ToInt32());
1223 break;
1225 case FIELD_PROPERTY_BOOL_DEFAULT:
1226 sValue = GetView()->GetDescWin()->BoolStringPersistent(::comphelper::getString(_rNewData));
1227 pFieldDescr->SetControlDefault(makeAny(::rtl::OUString(sValue)));
1228 break;
1230 case FIELD_PROPERTY_FORMAT:
1232 sValue = ::comphelper::getString(_rNewData);
1233 pFieldDescr->SetFormatKey(sValue.ToInt32());
1235 break;
1238 SetControlText(nRow,nColId,sValue);
1241 //------------------------------------------------------------------------------
1242 Any OTableEditorCtrl::GetCellData( long nRow, sal_uInt16 nColId )
1244 DBG_CHKTHIS(OTableEditorCtrl,NULL);
1245 OFieldDescription* pFieldDescr = GetFieldDescr( nRow );
1246 if( !pFieldDescr )
1247 return Any();
1249 //////////////////////////////////////////////////////////////////////
1250 // Aktuellen Datenzeiger umsetzen
1251 if( nRow==-1 )
1252 nRow = GetCurRow();
1253 SetDataPtr( nRow );
1255 static const String strYes(ModuleRes(STR_VALUE_YES));
1256 static const String strNo(ModuleRes(STR_VALUE_NO));
1257 ::rtl::OUString sValue;
1258 //////////////////////////////////////////////////////////////////////
1259 // Einzelne Felder auslesen
1260 switch( nColId )
1262 case FIELD_NAME:
1263 sValue = pFieldDescr->GetName();
1264 break;
1266 case FIELD_TYPE:
1267 if ( pFieldDescr->getTypeInfo() )
1268 sValue = pFieldDescr->getTypeInfo()->aUIName;
1269 break;
1271 case FIELD_DESCR:
1272 sValue = pFieldDescr->GetDescription();
1273 break;
1275 case FIELD_PROPERTY_DEFAULT:
1276 return pFieldDescr->GetControlDefault();
1278 case FIELD_PROPERTY_REQUIRED:
1279 sValue = pFieldDescr->GetIsNullable() == ColumnValue::NULLABLE ? strYes : strNo;
1280 break;
1282 case FIELD_PROPERTY_TEXTLEN:
1283 case FIELD_PROPERTY_LENGTH:
1284 sValue = String::CreateFromInt32(pFieldDescr->GetPrecision());
1285 break;
1287 case FIELD_PROPERTY_NUMTYPE:
1288 OSL_ENSURE(sal_False, "OTableEditorCtrl::GetCellData: invalid column!");
1289 // return pFieldDescr->GetNumType();
1291 case FIELD_PROPERTY_AUTOINC:
1292 sValue = pFieldDescr->IsAutoIncrement() ? strYes : strNo;
1293 break;
1295 case FIELD_PROPERTY_SCALE:
1296 sValue = String::CreateFromInt32(pFieldDescr->GetScale());
1297 break;
1299 case FIELD_PROPERTY_BOOL_DEFAULT:
1300 sValue = GetView()->GetDescWin()->BoolStringUI(::comphelper::getString(pFieldDescr->GetControlDefault()));
1301 break;
1303 case FIELD_PROPERTY_FORMAT:
1304 sValue = String::CreateFromInt32(pFieldDescr->GetFormatKey());
1305 break;
1308 return makeAny(sValue);
1311 //------------------------------------------------------------------------------
1312 String OTableEditorCtrl::GetCellText( long nRow, sal_uInt16 nColId ) const
1314 DBG_CHKTHIS(OTableEditorCtrl,NULL);
1315 ::rtl::OUString sCellText;
1316 const_cast< OTableEditorCtrl* >( this )->GetCellData( nRow, nColId ) >>= sCellText;
1317 return sCellText;
1320 //------------------------------------------------------------------------------
1321 sal_uInt32 OTableEditorCtrl::GetTotalCellWidth(long nRow, sal_uInt16 nColId)
1323 DBG_CHKTHIS(OTableEditorCtrl,NULL);
1324 return GetTextWidth(GetCellText(nRow, nColId)) + 2 * GetTextWidth('0');
1327 //------------------------------------------------------------------------------
1328 OFieldDescription* OTableEditorCtrl::GetFieldDescr( long nRow )
1330 DBG_CHKTHIS(OTableEditorCtrl,NULL);
1331 std::vector< ::boost::shared_ptr<OTableRow> >::size_type nListCount(
1332 m_pRowList->size());
1333 if( (nRow<0) || (sal::static_int_cast< unsigned long >(nRow)>=nListCount) )
1335 OSL_ENSURE(0,"(nRow<0) || (nRow>=nListCount)");
1336 return NULL;
1338 ::boost::shared_ptr<OTableRow> pRow = (*m_pRowList)[ nRow ];
1339 if( !pRow )
1340 return NULL;
1341 return pRow->GetActFieldDescr();
1344 //------------------------------------------------------------------------------
1345 sal_Bool OTableEditorCtrl::IsCutAllowed( long nRow )
1347 DBG_CHKTHIS(OTableEditorCtrl,NULL);
1348 sal_Bool bIsCutAllowed = (GetView()->getController().isAddAllowed() && GetView()->getController().isDropAllowed()) ||
1349 GetView()->getController().isAlterAllowed();
1351 if(bIsCutAllowed)
1353 if(m_eChildFocus == DESCRIPTION)
1354 bIsCutAllowed = pDescrCell->GetSelected().Len() != 0;
1355 else if(m_eChildFocus == NAME)
1356 bIsCutAllowed = pNameCell->GetSelected().Len() != 0;
1357 else if(m_eChildFocus == ROW)
1358 // only rows are selected for cutting so we look if all rows are valid
1359 // wwe don't waant to copy empty rows here
1360 bIsCutAllowed = IsCopyAllowed(nRow);
1361 else
1362 bIsCutAllowed = sal_False;
1365 // Reference<XPropertySet> xTable = GetView()->getController().getTable();
1366 // if( !IsCopyAllowed(nRow) || (xTable.is() && ::comphelper::getString(xTable->getPropertyValue(PROPERTY_TYPE)) == ::rtl::OUString::createFromAscii("VIEW")))
1367 // return sal_False;
1369 // return bCutAllowed && IsDeleteAllowed( nRow );
1370 return bIsCutAllowed;
1373 //------------------------------------------------------------------------------
1374 sal_Bool OTableEditorCtrl::IsCopyAllowed( long /*nRow*/ )
1376 DBG_CHKTHIS(OTableEditorCtrl,NULL);
1377 sal_Bool bIsCopyAllowed = sal_False;
1378 if(m_eChildFocus == DESCRIPTION)
1379 bIsCopyAllowed = pDescrCell->GetSelected().Len() != 0;
1380 else if(m_eChildFocus == NAME)
1381 bIsCopyAllowed = pNameCell->GetSelected().Len() != 0;
1382 else if(m_eChildFocus == ROW)
1384 Reference<XPropertySet> xTable = GetView()->getController().getTable();
1385 if( !GetSelectRowCount() || (xTable.is() && ::comphelper::getString(xTable->getPropertyValue(PROPERTY_TYPE)) == ::rtl::OUString::createFromAscii("VIEW")))
1386 return sal_False;
1388 //////////////////////////////////////////////////////////////////////
1389 // Wenn eine der markierten Zeilen leer ist, kein Copy moeglich
1390 ::boost::shared_ptr<OTableRow> pRow;
1391 long nIndex = FirstSelectedRow();
1392 while( nIndex >= 0 && nIndex < static_cast<long>(m_pRowList->size()) )
1394 pRow = (*m_pRowList)[nIndex];
1395 if( !pRow->GetActFieldDescr() )
1396 return sal_False;
1398 nIndex = NextSelectedRow();
1401 bIsCopyAllowed = sal_True;
1404 return bIsCopyAllowed;
1407 //------------------------------------------------------------------------------
1408 sal_Bool OTableEditorCtrl::IsPasteAllowed( long /*nRow*/ )
1410 DBG_CHKTHIS(OTableEditorCtrl,NULL);
1411 sal_Bool bAllowed = GetView()->getController().isAddAllowed();
1412 if ( bAllowed )
1414 TransferableDataHelper aTransferData(TransferableDataHelper::CreateFromSystemClipboard(GetParent()));
1415 sal_Bool bRowFormat = aTransferData.HasFormat(SOT_FORMATSTR_ID_SBA_TABED);
1416 if ( m_eChildFocus == ROW )
1417 bAllowed = bRowFormat;
1418 else
1419 bAllowed = !bRowFormat && aTransferData.HasFormat(SOT_FORMAT_STRING);
1422 return bAllowed;
1425 //------------------------------------------------------------------------------
1426 void OTableEditorCtrl::cut()
1428 if(m_eChildFocus == NAME)
1430 if(GetView()->getController().isAlterAllowed())
1432 SaveData(-1,FIELD_NAME);
1433 pNameCell->Cut();
1434 CellModified(-1,FIELD_NAME);
1437 else if(m_eChildFocus == DESCRIPTION)
1439 if(GetView()->getController().isAlterAllowed())
1441 SaveData(-1,FIELD_DESCR);
1442 pDescrCell->Cut();
1443 CellModified(-1,FIELD_DESCR);
1446 else if(m_eChildFocus == ROW)
1448 if (nCutEvent)
1449 Application::RemoveUserEvent(nCutEvent);
1450 nCutEvent = Application::PostUserEvent(LINK(this, OTableEditorCtrl, DelayedCut));
1454 //------------------------------------------------------------------------------
1455 void OTableEditorCtrl::copy()
1457 if(GetSelectRowCount())
1458 OTableRowView::copy();
1459 else if(m_eChildFocus == NAME)
1460 pNameCell->Copy();
1461 else if(m_eChildFocus == DESCRIPTION)
1462 pDescrCell->Copy();
1465 //------------------------------------------------------------------------------
1466 void OTableEditorCtrl::paste()
1468 TransferableDataHelper aTransferData(TransferableDataHelper::CreateFromSystemClipboard(GetParent()));
1469 if(aTransferData.HasFormat(SOT_FORMATSTR_ID_SBA_TABED))
1471 if( nPasteEvent )
1472 Application::RemoveUserEvent( nPasteEvent );
1473 nPasteEvent = Application::PostUserEvent( LINK(this, OTableEditorCtrl, DelayedPaste) );
1475 else if(m_eChildFocus == NAME)
1477 if(GetView()->getController().isAlterAllowed())
1479 pNameCell->Paste();
1480 CellModified();
1483 else if(m_eChildFocus == DESCRIPTION)
1485 if(GetView()->getController().isAlterAllowed())
1487 pDescrCell->Paste();
1488 CellModified();
1493 //------------------------------------------------------------------------------
1494 sal_Bool OTableEditorCtrl::IsDeleteAllowed( long /*nRow*/ )
1496 DBG_CHKTHIS(OTableEditorCtrl,NULL);
1498 return GetSelectRowCount() != 0 && GetView()->getController().isDropAllowed();
1499 // Reference<XPropertySet> xTable = GetView()->getController().getTable();
1500 // if( !GetSelectRowCount() || (xTable.is() && ::comphelper::getString(xTable->getPropertyValue(PROPERTY_TYPE)) == ::rtl::OUString::createFromAscii("VIEW")))
1501 // return sal_False;
1503 // // Wenn nur Felder hinzugefuegt werden duerfen, Delete nur auf neuen Feldern
1504 // Reference<XConnection> xCon = GetView()->getController().getConnection();
1505 // Reference< XDatabaseMetaData> xMetaData = xCon.is() ? xCon->getMetaData() : NULL;
1507 // return !(xTable.is() && xTable->getPropertySetInfo()->getPropertyByName(PROPERTY_NAME).Attributes & PropertyAttribute::READONLY) ||
1508 // ( xMetaData.is() && xMetaData->supportsAlterTableWithAddColumn() && xMetaData->supportsAlterTableWithDropColumn());
1511 //------------------------------------------------------------------------------
1512 sal_Bool OTableEditorCtrl::IsInsertNewAllowed( long nRow )
1514 DBG_CHKTHIS(OTableEditorCtrl,NULL);
1516 sal_Bool bInsertNewAllowed = GetView()->getController().isAddAllowed();
1517 //////////////////////////////////////////////////////////////
1518 // Wenn nur Felder hinzugefuegt werden duerfen, Paste nur in neue Felder
1519 if (bInsertNewAllowed && !GetView()->getController().isDropAllowed())
1521 SetDataPtr(nRow);
1522 if( GetActRow()->IsReadOnly() )
1523 return sal_False;
1526 return bInsertNewAllowed;
1529 //------------------------------------------------------------------------------
1530 sal_Bool OTableEditorCtrl::IsPrimaryKeyAllowed( long /*nRow*/ )
1532 DBG_CHKTHIS(OTableEditorCtrl,NULL);
1533 if( !GetSelectRowCount() )
1534 return sal_False;
1536 OTableController& rController = GetView()->getController();
1539 Reference<XConnection> xCon = rController.getConnection();
1541 Reference< XDatabaseMetaData> xMetaData = xCon.is() ? xCon->getMetaData() : Reference< XDatabaseMetaData>();
1542 if(!xMetaData.is() || !xMetaData->supportsCoreSQLGrammar())
1543 return sal_False; // no primary keys allowed
1546 catch(SQLException&)
1548 OSL_ASSERT(!"supportsCoreSQLGrammar");
1551 Reference<XPropertySet> xTable = rController.getTable();
1552 //////////////////////////////////////////////////////////////
1553 // Key darf nicht veraendert werden
1554 // Dies gilt jedoch nur, wenn die Tabelle nicht neu ist und keine ::com::sun::star::sdbcx::View. Ansonsten wird kein DROP ausgeführt
1556 if(xTable.is() && ::comphelper::getString(xTable->getPropertyValue(PROPERTY_TYPE)) == ::rtl::OUString::createFromAscii("VIEW"))
1557 return sal_False;
1558 //////////////////////////////////////////////////////////////
1559 // Wenn leeres Feld, kein PrimKey
1560 // Eintrag wird nur erlaubt, wenn
1561 // - kein leerer Eintrag in der Selection ist
1562 // - kein Eintrag vom Typ Memo oder Image ist
1563 // - kein DROP erlaubt ist (s.o.) und die Spalte noch kein Required (not null) gesetzt hatte.
1564 long nIndex = FirstSelectedRow();
1565 ::boost::shared_ptr<OTableRow> pRow;
1566 while( nIndex >= 0 && nIndex < static_cast<long>(m_pRowList->size()) )
1568 pRow = (*m_pRowList)[nIndex];
1569 OFieldDescription* pFieldDescr = pRow->GetActFieldDescr();
1570 if(!pFieldDescr)
1571 return sal_False;
1572 else
1574 //////////////////////////////////////////////////////////////
1575 // Wenn Feldtyp Memo oder Image, kein PrimKey
1576 // oder wenn Spalten nicht gedroped werden können und das Required Flag ist nicht gesetzt
1577 // oder wenn eine ::com::sun::star::sdbcx::View vorhanden ist und das Required Flag nicht gesetzt ist
1578 TOTypeInfoSP pTypeInfo = pFieldDescr->getTypeInfo();
1579 if( pTypeInfo->nSearchType == ColumnSearch::NONE
1580 || (pFieldDescr->IsNullable() && pRow->IsReadOnly())
1582 return sal_False;
1585 nIndex = NextSelectedRow();
1588 return sal_True;
1591 //------------------------------------------------------------------------------
1592 void OTableEditorCtrl::Command(const CommandEvent& rEvt)
1594 DBG_CHKTHIS(OTableEditorCtrl,NULL);
1595 switch (rEvt.GetCommand())
1597 case COMMAND_CONTEXTMENU:
1599 Point aMenuPos( rEvt.GetMousePosPixel() );
1600 if (!rEvt.IsMouseEvent())
1602 if ( 1 == GetSelectColumnCount() )
1604 sal_uInt16 nSelId = GetColumnId(
1605 sal::static_int_cast< USHORT >(
1606 FirstSelectedColumn() ) );
1607 ::Rectangle aColRect( GetFieldRectPixel( 0, nSelId, sal_False ) );
1609 aMenuPos = aColRect.TopCenter();
1611 else if ( GetSelectRowCount() > 0 )
1613 ::Rectangle aColRect( GetFieldRectPixel( FirstSelectedRow(), HANDLE_ID, sal_True ) );
1615 aMenuPos = aColRect.TopCenter();
1617 else
1619 OTableRowView::Command(rEvt);
1620 return;
1624 //////////////////////////////////////////////////////////////
1625 // Kontextmenu einblenden
1626 if( !IsReadOnly() )
1628 sal_uInt16 nColId = GetColumnAtXPosPixel(aMenuPos.X());
1629 long nRow = GetRowAtYPosPixel(aMenuPos.Y());
1631 if ( HANDLE_ID != nColId )
1633 if ( nRow < 0 && nColId != BROWSER_INVALIDID )
1634 { // hit the header
1635 if ( 3 != nColId )
1636 { // 3 would mean the last column, and this last column is auto-sized
1637 if ( !IsColumnSelected( nColId ) )
1638 SelectColumnId( nColId );
1640 PopupMenu aContextMenu( ModuleRes( RID_QUERYCOLPOPUPMENU ) );
1641 aContextMenu.EnableItem( SID_DELETE, sal_False );
1642 aContextMenu.RemoveDisabledEntries(sal_True, sal_True);
1643 switch ( aContextMenu.Execute( this, aMenuPos ) )
1645 case ID_BROWSER_COLWIDTH:
1646 adjustBrowseBoxColumnWidth( this, nColId );
1647 break;
1652 else
1654 PopupMenu aContextMenu(ModuleRes(RID_TABLEDESIGNROWPOPUPMENU));
1656 aContextMenu.EnableItem( SID_CUT, IsCutAllowed(nRow) );
1657 aContextMenu.EnableItem( SID_COPY, IsCopyAllowed(nRow) );
1658 aContextMenu.EnableItem( SID_PASTE, IsPasteAllowed(nRow) );
1659 aContextMenu.EnableItem( SID_DELETE, IsDeleteAllowed(nRow) );
1660 aContextMenu.EnableItem( SID_TABLEDESIGN_TABED_PRIMARYKEY, IsPrimaryKeyAllowed(nRow) );
1661 aContextMenu.EnableItem( SID_TABLEDESIGN_INSERTROWS, IsInsertNewAllowed(nRow) );
1662 aContextMenu.CheckItem( SID_TABLEDESIGN_TABED_PRIMARYKEY, IsRowSelected(GetCurRow()) && IsPrimaryKey() );
1664 // jetzt alles, was disabled wurde, wech
1665 aContextMenu.RemoveDisabledEntries(sal_True, sal_True);
1667 if( SetDataPtr(m_nDataPos) )
1668 pDescrWin->SaveData( pActRow->GetActFieldDescr() );
1670 //////////////////////////////////////////////////////////////
1671 // Alle Aktionen, die die Zeilenzahl veraendern, muessen asynchron
1672 // ausgefuehrt werden->sonst Probleme zwischen Kontextmenu u. Browser
1673 m_nDataPos = GetCurRow();
1674 switch (aContextMenu.Execute(this, aMenuPos))
1676 case SID_CUT:
1677 cut();
1678 break;
1679 case SID_COPY:
1680 copy();
1681 break;
1682 case SID_PASTE:
1683 paste();
1684 break;
1685 case SID_DELETE:
1686 if( nDeleteEvent )
1687 Application::RemoveUserEvent( nDeleteEvent );
1688 nDeleteEvent = Application::PostUserEvent( LINK(this, OTableEditorCtrl, DelayedDelete) );
1689 break;
1690 case SID_TABLEDESIGN_INSERTROWS:
1691 if( nInsNewRowsEvent )
1692 Application::RemoveUserEvent( nInsNewRowsEvent );
1693 nInsNewRowsEvent = Application::PostUserEvent( LINK(this, OTableEditorCtrl, DelayedInsNewRows) );
1694 break;
1695 case SID_TABLEDESIGN_TABED_PRIMARYKEY:
1696 SetPrimaryKey( !IsPrimaryKey() );
1697 break;
1698 default:
1699 break;
1704 break;
1705 default:
1706 OTableRowView::Command(rEvt);
1711 //------------------------------------------------------------------------------
1712 IMPL_LINK( OTableEditorCtrl, DelayedCut, void*, /*EMPTYTAG*/ )
1714 nCutEvent = 0;
1715 OTableRowView::cut();
1716 return 0;
1719 //------------------------------------------------------------------------------
1720 IMPL_LINK( OTableEditorCtrl, DelayedPaste, void*, /*EMPTYTAG*/ )
1722 nPasteEvent = 0;
1724 sal_Int32 nPastePosition = GetView()->getController().getFirstEmptyRowPosition();
1725 if ( !GetView()->getController().getTable().is() )
1726 nPastePosition = GetSelectRowCount() ? FirstSelectedRow() : GetCurRow();
1728 if (!IsInsertNewAllowed(nPastePosition))
1729 { // kein Einfuegen erlaubt, sondern nur anhaengen, also testen, ob hinter der PastePosition noch
1730 // belegte Zeilen erscheinen
1732 sal_Int32 nFreeFromPos; // ab da nur freie Zeilen
1733 ::std::vector< ::boost::shared_ptr<OTableRow> >::reverse_iterator aIter = m_pRowList->rbegin();
1734 for(nFreeFromPos = m_pRowList->size();
1735 aIter != m_pRowList->rend() && (!(*aIter) || !(*aIter)->GetActFieldDescr() || !(*aIter)->GetActFieldDescr()->GetName().getLength());
1736 --nFreeFromPos, ++aIter)
1738 if (nPastePosition < nFreeFromPos) // es gibt mindestens eine belegte hinter PastePosition -> ganz nach hinten
1739 nPastePosition = nFreeFromPos;
1742 OTableRowView::Paste( nPastePosition );
1743 SetNoSelection();
1744 GoToRow( nPastePosition );
1746 return 0;
1749 //------------------------------------------------------------------------------
1750 IMPL_LINK( OTableEditorCtrl, DelayedDelete, void*, /*EMPTYTAG*/ )
1752 nDeleteEvent = 0;
1753 DeleteRows();
1754 return 0;
1757 //------------------------------------------------------------------------------
1758 IMPL_LINK( OTableEditorCtrl, DelayedInsNewRows, void*, /*EMPTYTAG*/ )
1760 DBG_CHKTHIS(OTableEditorCtrl,NULL);
1761 nInsNewRowsEvent = 0;
1762 sal_Int32 nPastePosition = GetView()->getController().getFirstEmptyRowPosition();
1763 if ( !GetView()->getController().getTable().is() )
1764 nPastePosition = GetSelectRowCount() ? FirstSelectedRow() : m_nDataPos;
1766 InsertNewRows( nPastePosition );
1767 SetNoSelection();
1768 GoToRow( nPastePosition );
1770 return 0;
1772 // -----------------------------------------------------------------------------
1773 void OTableEditorCtrl::AdjustFieldDescription(OFieldDescription* _pFieldDesc,
1774 MultiSelection& _rMultiSel,
1775 sal_Int32 _nPos,
1776 sal_Bool _bSet,
1777 sal_Bool _bPrimaryKey)
1779 _pFieldDesc->SetPrimaryKey( _bPrimaryKey );
1780 if(!_bSet && _pFieldDesc->getTypeInfo()->bNullable)
1782 _pFieldDesc->SetIsNullable(ColumnValue::NO_NULLS);
1783 _pFieldDesc->SetControlDefault(Any());
1784 } // if(!_bSet && _pFieldDesc->getTypeInfo()->bNullable)
1785 if ( _pFieldDesc->IsAutoIncrement() && !_bPrimaryKey )
1787 OTableController& rController = GetView()->getController();
1788 if ( rController.isAutoIncrementPrimaryKey() )
1790 _pFieldDesc->SetAutoIncrement(false);
1793 //////////////////////////////////////////////////////////////////////
1794 // update field description
1795 pDescrWin->DisplayData(_pFieldDesc);
1797 _rMultiSel.Insert( _nPos );
1798 _rMultiSel.Select( _nPos );
1800 //------------------------------------------------------------------------------
1801 void OTableEditorCtrl::SetPrimaryKey( sal_Bool bSet )
1803 DBG_CHKTHIS(OTableEditorCtrl,NULL);
1804 //////////////////////////////////////////////////////////////////////
1805 // Evtl. vorhandene Primary Keys loeschen
1806 MultiSelection aDeletedPrimKeys;
1807 aDeletedPrimKeys.SetTotalRange( Range(0,GetRowCount()) );
1808 long nIndex = 0;
1810 ::std::vector< ::boost::shared_ptr<OTableRow> >::const_iterator aIter = m_pRowList->begin();
1811 ::std::vector< ::boost::shared_ptr<OTableRow> >::const_iterator aEnd = m_pRowList->end();
1812 for(sal_Int32 nRow = 0;aIter != aEnd;++aIter,++nRow)
1814 OFieldDescription* pFieldDescr = (*aIter)->GetActFieldDescr();
1815 if( pFieldDescr && (*aIter)->IsPrimaryKey() && (!bSet || !IsRowSelected(nRow)) )
1817 AdjustFieldDescription(pFieldDescr,aDeletedPrimKeys,nRow,bSet,sal_False);
1821 //////////////////////////////////////////////////////////////////////
1822 // Die Primary Keys der markierten Zeilen setzen
1823 MultiSelection aInsertedPrimKeys;
1824 aInsertedPrimKeys.SetTotalRange( Range(0,GetRowCount()) );
1825 if( bSet )
1827 nIndex = FirstSelectedRow();
1828 while( nIndex >= 0 && nIndex < static_cast<long>(m_pRowList->size()) )
1830 //////////////////////////////////////////////////////////////////////
1831 // Key setzen
1832 ::boost::shared_ptr<OTableRow> pRow = (*m_pRowList)[nIndex];
1833 OFieldDescription* pFieldDescr = pRow->GetActFieldDescr();
1834 if(pFieldDescr)
1835 AdjustFieldDescription(pFieldDescr,aInsertedPrimKeys,nIndex,sal_False,sal_True);
1837 nIndex = NextSelectedRow();
1841 GetUndoManager()->AddUndoAction( new OPrimKeyUndoAct(this, aDeletedPrimKeys, aInsertedPrimKeys) );
1843 //////////////////////////////////////////////////////////////////////
1844 // Handle-Spalte invalidieren
1845 InvalidateHandleColumn();
1848 //////////////////////////////////////////////////////////////////////
1849 // Das ModifyFlag der TableDocSh setzen
1850 GetView()->getController().setModified( sal_True );
1851 InvalidateFeatures();
1854 //------------------------------------------------------------------------------
1855 sal_Bool OTableEditorCtrl::IsPrimaryKey()
1857 DBG_CHKTHIS(OTableEditorCtrl,NULL);
1858 //////////////////////////////////////////////////////////////////////
1859 // Gehoeren alle markierten Felder zu einem Primary Key ?
1860 long nPrimaryKeys = 0;
1861 ::std::vector< ::boost::shared_ptr<OTableRow> >::const_iterator aIter = m_pRowList->begin();
1862 ::std::vector< ::boost::shared_ptr<OTableRow> >::const_iterator aEnd = m_pRowList->end();
1863 for(sal_Int32 nRow=0;aIter != aEnd;++aIter,++nRow)
1865 if( IsRowSelected(nRow) && !(*aIter)->IsPrimaryKey() )
1866 return sal_False;
1867 if( (*aIter)->IsPrimaryKey() )
1868 ++nPrimaryKeys;
1871 //////////////////////////////////////////////////////////////////////
1872 // Gibt es unselektierte Felder, die noch zu dem Key gehoeren ?
1873 return GetSelectRowCount() == nPrimaryKeys;
1876 //------------------------------------------------------------------------------
1877 void OTableEditorCtrl::SwitchType( const TOTypeInfoSP& _pType )
1879 DBG_CHKTHIS(OTableEditorCtrl,NULL);
1880 //////////////////////////////////////////////////////////////////////
1881 // Wenn noch kein Feldname vergeben wurde
1882 long nRow(GetCurRow());
1883 OFieldDescription* pActFieldDescr = GetFieldDescr( nRow );
1884 if( pActFieldDescr )
1885 //////////////////////////////////////////////////////////////////////
1886 // Alte Beschreibung speichern
1887 pDescrWin->SaveData( pActFieldDescr );
1889 if ( nRow < 0 || nRow > static_cast<long>(m_pRowList->size()) )
1890 return;
1891 //////////////////////////////////////////////////////////////////////
1892 // Neue Beschreibung darstellen
1893 ::boost::shared_ptr<OTableRow> pRow = (*m_pRowList)[nRow];
1894 pRow->SetFieldType( _pType, sal_True );
1895 if ( _pType.get() )
1897 const sal_uInt16 nCurrentlySelected = pTypeCell->GetSelectEntryPos();
1899 if ( ( LISTBOX_ENTRY_NOTFOUND == nCurrentlySelected )
1900 || ( GetView()->getController().getTypeInfo( nCurrentlySelected ) != _pType )
1903 USHORT nEntryPos = 0;
1904 const OTypeInfoMap* pTypeInfo = GetView()->getController().getTypeInfo();
1905 OTypeInfoMap::const_iterator aIter = pTypeInfo->begin();
1906 OTypeInfoMap::const_iterator aEnd = pTypeInfo->end();
1907 for(;aIter != aEnd;++aIter,++nEntryPos)
1909 if(aIter->second == _pType)
1910 break;
1912 if (nEntryPos < pTypeCell->GetEntryCount())
1913 pTypeCell->SelectEntryPos( nEntryPos );
1917 pActFieldDescr = pRow->GetActFieldDescr();
1918 if (pActFieldDescr != NULL && !pActFieldDescr->GetFormatKey())
1920 sal_Int32 nFormatKey = ::dbtools::getDefaultNumberFormat( pActFieldDescr->GetType(),
1921 pActFieldDescr->GetScale(),
1922 pActFieldDescr->IsCurrency(),
1923 Reference< XNumberFormatTypes>(GetView()->getController().getNumberFormatter()->getNumberFormatsSupplier()->getNumberFormats(),UNO_QUERY),
1924 GetView()->getLocale());
1926 pActFieldDescr->SetFormatKey(nFormatKey);
1929 pDescrWin->DisplayData( pActFieldDescr );
1931 // -----------------------------------------------------------------------------
1932 OTableDesignView* OTableEditorCtrl::GetView() const
1934 return static_cast<OTableDesignView*>(GetParent()->GetParent());
1936 // -----------------------------------------------------------------------------
1937 void OTableEditorCtrl::DeactivateCell(sal_Bool bUpdate)
1939 OTableRowView::DeactivateCell(bUpdate);
1940 // now we have to deactivate the field description
1941 long nRow(GetCurRow());
1942 if (pDescrWin)
1943 pDescrWin->SetReadOnly(bReadOnly || !SetDataPtr(nRow) || GetActRow()->IsReadOnly());
1945 //------------------------------------------------------------------------------
1946 long OTableEditorCtrl::PreNotify( NotifyEvent& rNEvt )
1948 if (rNEvt.GetType() == EVENT_GETFOCUS)
1950 if( pDescrCell && pDescrCell->HasChildPathFocus() )
1951 m_eChildFocus = DESCRIPTION;
1952 else if(pNameCell && pNameCell->HasChildPathFocus() )
1953 m_eChildFocus = NAME;
1954 else
1955 m_eChildFocus = ROW;
1958 return OTableRowView::PreNotify(rNEvt);
1960 // -----------------------------------------------------------------------------