Files
libreoffice/sc/source/ui/app/inputwin.cxx

2528 lines
82 KiB
C++
Raw Normal View History

/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
re-base on ALv2 code. Includes: Patches contributed by Herbert Duerr i#118735 prevent endless loop if vlookup/hlookup doesn't find anything http://svn.apache.org/viewvc?view=revision&revision=1239673 Patches contributed by Andre Fischer remove lp_solver http://svn.apache.org/viewvc?view=revision&revision=1199180 i#118160: Added external CoinMP library. http://svn.apache.org/viewvc?view=revision&revision=1233909 Patches contributed by Armin Le-Grand i#118485 - Styles for OLEs are not saved. http://svn.apache.org/viewvc?view=revision&revision=1182166 i#118524: apply patch, followup fixes to 118485 http://svn.apache.org/viewvc?view=revision&revision=1186077 Patches contributed by lihuiibm i#108860 - Fix range validation. http://svn.apache.org/viewvc?view=revision&revision=1242846 i#118954 Chart data will lost after copy to different file http://svn.apache.org/viewvc?view=revision&revision=1301345 Patches contributed by Ariel Constenla-Haile Fix Linux build breaker: extra qualification on member http://svn.apache.org/viewvc?view=revision&revision=1301591 i#118696 - i#118697 - Fix some Sheet Tab Color API issues http://svn.apache.org/viewvc?view=revision&revision=1225428 i#118697 - Fix uninitialized variable http://svn.apache.org/viewvc?view=revision&revision=1225859 i#118771 - ScUndoImportTab should preserve tab background color http://svn.apache.org/viewvc?view=revision&revision=1230356 i#118921 - Repaint linked sheet tab background color after updating link http://svn.apache.org/viewvc?view=revision&revision=1245177 i#118927 - Undo/Redo "Update Link" does not reset sheet tab color http://svn.apache.org/viewvc?view=revision&revision=1245241 i#118747 - Copy tab color when transferring sheets across documents http://svn.apache.org/viewvc?view=revision&revision=1230355 Patch contributed by Oliver Rainer-Wittman i#118012 - methods <ScBroadcastAreaSlot::AreaBroadcast(..)> and <ScBroadcastAreaSlot::AreaBroadcastInRange(..)> adapt stl-container iteration in order to avoid destroyed iterators during iteration. http://svn.apache.org/viewvc?view=revision&revision=1297916 Patches contributed by Mathias Bauer gnumake4 work variously http://svn.apache.org/viewvc?view=revision&revision=1394707 http://svn.apache.org/viewvc?view=revision&revision=1394326 http://svn.apache.org/viewvc?view=revision&revision=1396797 http://svn.apache.org/viewvc?view=revision&revision=1397315 Patch contributed by Daniel Rentz calc69: #i116936# fix VBA symbol Cells http://svn.apache.org/viewvc?view=revision&revision=1172135 Patches contributed by leiw: i#118546 CPU 100% on switched off AutoCalculate with Conditional Formatting on date values http://svn.apache.org/viewvc?view=revision&revision=1301380 Re-add new function documentation. Many various cleanups. Add missing calc66: #o11817313# also look at formula result number format, remove redundant binaries.
2012-11-30 12:23:25 +00:00
/*
* This file is part of the LibreOffice project.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
* This file incorporates work covered by the following license notice:
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed
* with this work for additional information regarding copyright
* ownership. The ASF licenses this file to you under the Apache
* License, Version 2.0 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.apache.org/licenses/LICENSE-2.0 .
*/
2000-09-18 16:07:07 +00:00
#include <algorithm>
2000-09-18 16:07:07 +00:00
#include "scitems.hxx"
#include <editeng/eeitem.hxx>
#include <sfx2/app.hxx>
#include <editeng/adjustitem.hxx>
#include <editeng/editview.hxx>
#include <editeng/editstat.hxx>
#include <editeng/frmdiritem.hxx>
#include <editeng/lspcitem.hxx>
2000-09-18 16:07:07 +00:00
#include <sfx2/bindings.hxx>
#include <sfx2/viewfrm.hxx>
2000-09-18 16:07:07 +00:00
#include <sfx2/dispatch.hxx>
#include <sfx2/event.hxx>
#include <sfx2/imgmgr.hxx>
#include <stdlib.h>
#include <editeng/scriptspaceitem.hxx>
#include <editeng/scripttypeitem.hxx>
#include <vcl/cursor.hxx>
#include <vcl/help.hxx>
#include <svl/stritem.hxx>
#include <stdio.h>
2000-09-18 16:07:07 +00:00
#include "inputwin.hxx"
#include "scmod.hxx"
#include "uiitems.hxx"
#include "global.hxx"
#include "scresid.hxx"
#include "sc.hrc"
#include "globstr.hrc"
#include "reffact.hxx"
2000-09-18 16:07:07 +00:00
#include "editutil.hxx"
#include "inputhdl.hxx"
#include "tabvwsh.hxx"
#include "document.hxx"
#include "docsh.hxx"
#include "appoptio.hxx"
#include "rangenam.hxx"
CWS-TOOLING: integrate CWS frmdlg 2008-12-18 09:13:09 +0100 oj r265667 : merge from odff05 2008-12-18 07:58:16 +0100 oj r265658 : #i94555# patch from <regina>, ODFF: Add GAMMA, CHISQDIST, CHISQINV. Make the 'cumulative' parameter of GAMMADIST optional. Adapt the domain of CHIDIST to allow negative x. Remove the constraint "degrees of freedom < 1.0E5" from CHIDIST and CHIINV. Plus a mechanism to write the now optional parameter of GAMMADIST to PODF and ODFF if omitted, for backwards compatibility. 2008-12-15 14:06:11 +0100 oj r265490 : CWS-TOOLING: rebase CWS frmdlg to trunk@264807 (milestone: DEV300:m37) 2008-12-15 13:55:28 +0100 oj r265488 : CWS-TOOLING: do not delete this file, it's needed for 'cws rebase -C' CWS: frmdlg New MWS: DEV300 New milestone: m37 2008-12-15 13:55:07 +0100 oj r265487 : CWS-TOOLING: do not delete this file, it's needed for 'cws rebase -C' CWS: frmdlg New MWS: DEV300 New milestone: m37 2008-12-15 13:54:48 +0100 oj r265486 : CWS-TOOLING: do not delete this file, it's needed for 'cws rebase -C' CWS: frmdlg New MWS: DEV300 New milestone: m37 2008-12-15 13:54:36 +0100 oj r265485 : CWS-TOOLING: do not delete this file, it's needed for 'cws rebase -C' CWS: frmdlg New MWS: DEV300 New milestone: m37 2008-12-15 13:54:24 +0100 oj r265484 : CWS-TOOLING: do not delete this file, it's needed for 'cws rebase -C' CWS: frmdlg New MWS: DEV300 New milestone: m37 2008-12-15 13:48:11 +0100 oj r265483 : CWS-TOOLING: do not delete this file, it's needed for 'cws rebase -C' CWS: frmdlg New MWS: DEV300 New milestone: m37 2008-12-15 13:31:12 +0100 oj r265479 : CWS-TOOLING: do not delete this file, it's needed for 'cws rebase -C' CWS: frmdlg New MWS: DEV300 New milestone: m37 2008-12-15 13:13:58 +0100 oj r265477 : CWS-TOOLING: do not delete this file, it's needed for 'cws rebase -C' CWS: frmdlg New MWS: DEV300 New milestone: m37 2008-12-15 13:10:09 +0100 oj r265476 : CWS-TOOLING: do not delete this file, it's needed for 'cws rebase -C' CWS: frmdlg New MWS: DEV300 New milestone: m37 2008-12-15 13:05:11 +0100 oj r265475 : CWS-TOOLING: do not delete this file, it's needed for 'cws rebase -C' CWS: frmdlg New MWS: DEV300 New milestone: m37 2008-12-15 10:47:17 +0100 oj r265467 : CWS-TOOLING: do not delete this file, it's needed for 'cws rebase -C' CWS: frmdlg New MWS: DEV300 New milestone: m37 2008-12-15 10:46:19 +0100 oj r265466 : CWS-TOOLING: do not delete this file, it's needed for 'cws rebase -C' CWS: frmdlg New MWS: DEV300 New milestone: m37 2008-12-15 10:45:47 +0100 oj r265465 : CWS-TOOLING: do not delete this file, it's needed for 'cws rebase -C' CWS: frmdlg New MWS: DEV300 New milestone: m37 2008-12-15 07:35:07 +0100 oj r265458 : add dependency to formula 2008-12-15 07:34:24 +0100 oj r265457 : add dependency to formula 2008-12-12 13:22:00 +0100 msc r265413 : #i97089# 2008-12-12 13:20:25 +0100 msc r265412 : #i97089# 2008-12-12 12:35:12 +0100 msc r265406 : #i97089# 2008-12-12 12:34:16 +0100 msc r265405 : #i97089# 2008-12-12 12:33:05 +0100 msc r265404 : #i97089# 2008-12-12 12:31:11 +0100 msc r265403 : #i97089# 2008-12-08 11:59:10 +0100 oj r264981 : insert RTL_LOG 2008-12-08 11:50:17 +0100 oj r264980 : some small changes 2008-12-05 12:57:57 +0100 oj r264902 : eof changed 2008-12-05 12:56:46 +0100 oj r264901 : eof changed 2008-12-05 12:28:47 +0100 oj r264899 : wrong var used 2008-12-05 10:08:57 +0100 oj r264890 : token order reversed 2008-12-04 13:49:22 +0100 oc r264843 : #i96688: Adapt autotests because of outsourced functionwizard 2008-12-04 13:45:27 +0100 oc r264842 : #i96688: Adapt autotests because of outsourced functionwizard 2008-12-04 13:42:54 +0100 oc r264841 : #i96688: Adapt autotests because of outsourced functionwizard 2008-12-04 13:37:41 +0100 oc r264840 : #i96688: Adapt autotests because of outsourced functionwizard 2008-12-04 13:34:11 +0100 oc r264839 : #i96688: Adapt autotests because of outsourced functionwizard 2008-12-04 12:35:31 +0100 oj r264835 : new help ids for struct and function tabpage 2008-12-04 12:00:35 +0100 oj r264828 : set explicit help id 2008-12-03 14:53:27 +0100 oj r264786 : #i96845# change ref button 2008-12-03 14:51:49 +0100 oj r264785 : #i96845# change ref button 2008-12-03 08:51:57 +0100 oj r264746 : convert dos to unix lineends 2008-12-03 08:50:45 +0100 oj r264745 : convert dos to unix lineends 2008-12-03 08:50:05 +0100 oj r264744 : convert dos to unix lineends 2008-12-02 12:28:33 +0100 oj r264686 : clear help text when new helpid is set 2008-12-02 12:28:02 +0100 oj r264685 : set help id for listbox category 2008-12-02 07:15:56 +0100 oj r264655 : remove define to auto generate help ids 2008-12-01 14:36:43 +0100 oj r264604 : use temp var 2008-12-01 14:18:31 +0100 oj r264601 : moved ScJumpToken to formula 2008-12-01 14:18:11 +0100 oj r264600 : moved ScJumpToken to formula 2008-12-01 14:14:35 +0100 oj r264599 : moved ScJumpToken from sc 2008-12-01 10:48:51 +0100 oj r264589 : change quickhelptext from Shrink to Select 2008-12-01 10:28:41 +0100 oj r264588 : fix opcode data, has to be Any.Void 2008-11-28 11:16:48 +0100 oj r264532 : add help ids 2008-11-28 10:16:56 +0100 oj r264529 : set help id 2008-11-28 10:16:43 +0100 oj r264528 : set help id 2008-11-26 13:55:04 +0100 oj r264381 : #94535# use of optional instead of deleting a string myself and some small changes 2008-11-26 09:53:20 +0100 oj r264346 : compile error with debug/without debug 2008-11-25 07:41:28 +0100 oj r264271 : put static into the method which make use of them 2008-11-24 08:16:07 +0100 oj r264196 : removed not needed classes for op code 2008-11-24 08:13:44 +0100 oj r264195 : removed not needed classes for op code 2008-11-21 14:05:53 +0100 oj r264135 : make GetOpCode inline 2008-11-21 12:35:27 +0100 oj r264124 : hold symbols 2008-11-20 09:27:27 +0100 oj r264028 : merged code from DEV300_m35 which got lost 2008-11-19 20:42:12 +0100 oj r264022 : more changes for formula dialog remove 2008-11-19 20:37:41 +0100 oj r264021 : removed unused var 2008-11-19 20:35:35 +0100 oj r264020 : some more changes at token 2008-11-19 10:59:47 +0100 oj r263967 : deleted 2008-11-19 10:58:24 +0100 oj r263966 : add forui and for res files 2008-11-18 15:27:36 +0100 oj r263777 : unused para removed 2008-11-18 15:23:23 +0100 oj r263775 : add insert button to add field dlg 2008-11-18 13:39:53 +0100 oj r263764 : enable the formula dialog as well for conditional print as for conditional formatting 2008-11-18 12:03:25 +0100 oj r263760 : rename isRef in IsRef 2008-11-17 11:46:16 +0100 oj r263711 : patches for function handling 2008-11-17 11:36:22 +0100 oj r263710 : add new for forui and res file 2008-11-17 09:21:12 +0100 oj r263704 : patches for some resource for libformula 2008-11-15 12:45:30 +0100 oj r263701 : changes for formula editor extraction 2008-11-07 08:23:27 +0100 oj r263416 : merge from DEV300:m35 2008-11-07 08:22:35 +0100 oj r263415 : merge from DEV300:m35 2008-11-07 08:22:16 +0100 oj r263414 : merge from DEV300:m35 2008-11-07 08:21:41 +0100 oj r263413 : merge from DEV300:m35 2008-11-07 08:21:31 +0100 oj r263412 : merge from DEV300:m35 2008-11-07 08:20:38 +0100 oj r263411 : merge from DEV300:m35 2008-11-07 08:20:00 +0100 oj r263410 : merge from DEV300:m35 2008-11-07 08:18:50 +0100 oj r263409 : merge from DEV300:m35 2008-11-07 08:18:19 +0100 oj r263408 : merge from DEV300:m35 2008-11-07 08:10:27 +0100 oj r263407 : merge from DEV300:m35 2008-10-21 07:43:46 +0200 oj r262560 : some compile errors resolved 2008-10-17 16:40:01 +0200 oj r262291 : dep for 1st target 2008-10-07 10:08:39 +0200 oj r262077 : copy 2008-10-07 09:45:31 +0200 oj r262076 : #i94535# 2008-10-07 09:44:26 +0200 oj r262075 : #i94535# new base class 2008-10-07 09:43:21 +0200 oj r262074 : moved to formula 2008-10-07 09:41:51 +0200 oj r262073 : new images 2008-10-07 09:03:01 +0200 oj r262072 : new ids for formula 2008-10-02 08:46:27 +0200 oj r262024 : #i94535# move the formula compiler to formula 2008-10-02 08:08:54 +0200 oj r262023 : #i94535# 2008-10-02 08:06:28 +0200 oj r262022 : #i94535# 2008-10-02 08:05:52 +0200 oj r262021 : #i94535# 2008-10-01 17:15:29 +0200 oj r262014 : #i94535# 2008-10-01 17:12:40 +0200 oj r262013 : new module formula 2008-10-01 17:04:55 +0200 oj r262012 : #i94535# 2008-10-01 16:49:03 +0200 oj r262010 : #i94535# 2008-10-01 16:46:59 +0200 oj r262009 : #i94535#
2009-01-08 10:47:13 +00:00
#include <formula/compiler.hrc>
#include "dbdata.hxx"
#include "rangeutl.hxx"
#include "docfunc.hxx"
#include "funcdesc.hxx"
#include "markdata.hxx"
#include <editeng/fontitem.hxx>
#include <com/sun/star/accessibility/XAccessible.hpp>
2002-06-10 13:56:35 +00:00
#include "AccessibleEditObject.hxx"
#include "AccessibleText.hxx"
2011-07-05 09:41:08 +01:00
#include <svtools/miscopt.hxx>
#include <comphelper/string.hxx>
#include <com/sun/star/frame/XLayoutManager.hpp>
#include <com/sun/star/frame/XModel.hpp>
#include <com/sun/star/frame/XController.hpp>
2000-09-18 16:07:07 +00:00
#define THESIZE 1000000 //!!! langt... :-)
#define TBX_WINDOW_HEIGHT 22 // in Pixeln - fuer alle Systeme gleich?
#define LEFT_OFFSET 5
#define INPUTWIN_MULTILINES 6
const long BUTTON_OFFSET = 2; ///< space between input line and the button to expand / collapse
const long ADDITIONAL_BORDER = 1; ///< height of the line at the bottom
const long ADDITIONAL_SPACE = 4; ///< additional vertical space when the multiline edit has more lines
2000-09-18 16:07:07 +00:00
using com::sun::star::uno::Reference;
using com::sun::star::uno::UNO_QUERY;
using com::sun::star::frame::XLayoutManager;
using com::sun::star::frame::XModel;
using com::sun::star::frame::XFrame;
using com::sun::star::frame::XController;
using com::sun::star::beans::XPropertySet;
enum ScNameInputType
{
SC_NAME_INPUT_CELL,
SC_NAME_INPUT_RANGE,
SC_NAME_INPUT_NAMEDRANGE,
SC_NAME_INPUT_DATABASE,
SC_NAME_INPUT_ROW,
SC_NAME_INPUT_SHEET,
SC_NAME_INPUT_DEFINE,
SC_NAME_INPUT_BAD_NAME,
SC_NAME_INPUT_BAD_SELECTION,
SC_MANAGE_NAMES
};
2000-09-18 16:07:07 +00:00
ScTextWndBase::ScTextWndBase( Window* pParent, WinBits nStyle )
: Window ( pParent, nStyle )
{
if ( IsNativeControlSupported( CTRL_EDITBOX, PART_ENTIRE_CONTROL ) )
{
SetType( WINDOW_CALCINPUTLINE );
SetBorderStyle( WINDOW_BORDER_NWF );
}
}
2000-09-18 16:07:07 +00:00
//==================================================================
// class ScInputWindowWrapper
//==================================================================
SFX_IMPL_CHILDWINDOW_WITHID(ScInputWindowWrapper,FID_INPUTLINE_STATUS)
2000-09-18 16:07:07 +00:00
ScInputWindowWrapper::ScInputWindowWrapper( Window* pParentP,
sal_uInt16 nId,
2000-09-18 16:07:07 +00:00
SfxBindings* pBindings,
SfxChildWinInfo* /* pInfo */ )
: SfxChildWindow( pParentP, nId )
2000-09-18 16:07:07 +00:00
{
ScInputWindow* pWin=new ScInputWindow( pParentP, pBindings );
2000-09-18 16:07:07 +00:00
pWindow = pWin;
pWin->Show();
pWin->SetSizePixel( pWin->CalcWindowSizePixel() );
eChildAlignment = SFX_ALIGN_LOWESTTOP;
pBindings->Invalidate( FID_TOGGLEINPUTLINE );
}
// GetInfo fliegt wieder raus, wenn es ein SFX_IMPL_TOOLBOX gibt !!!!
2010-12-11 23:25:30 +01:00
SfxChildWinInfo ScInputWindowWrapper::GetInfo() const
2000-09-18 16:07:07 +00:00
{
SfxChildWinInfo aInfo = SfxChildWindow::GetInfo();
return aInfo;
}
//==================================================================
2010-11-22 16:59:17 -08:00
#define IMAGE(id) pImgMgr->SeekImage(id)
static bool lcl_isExperimentalMode()
2011-07-05 09:41:08 +01:00
{
// make inputbar feature on by default, leave the switch for the
// moment in case we need to back it out easily
return true;
2011-07-05 09:41:08 +01:00
}
2000-09-18 16:07:07 +00:00
//==================================================================
// class ScInputWindow
//==================================================================
static ScTextWndBase* lcl_chooseRuntimeImpl( Window* pParent, SfxBindings* pBind )
2011-07-05 09:41:08 +01:00
{
ScTabViewShell* pViewSh = NULL;
SfxDispatcher* pDisp = pBind->GetDispatcher();
if ( pDisp )
{
SfxViewFrame* pViewFrm = pDisp->GetFrame();
if ( pViewFrm )
pViewSh = PTR_CAST( ScTabViewShell, pViewFrm->GetViewShell() );
}
2011-07-05 09:41:08 +01:00
if ( !lcl_isExperimentalMode() )
return new ScTextWnd( pParent, pViewSh );
return new ScInputBarGroup( pParent, pViewSh );
2011-07-05 09:41:08 +01:00
}
ScInputWindow::ScInputWindow( Window* pParent, SfxBindings* pBind ) :
2000-09-18 16:07:07 +00:00
// mit WB_CLIPCHILDREN, sonst Flicker
ToolBox ( pParent, WinBits(WB_CLIPCHILDREN) ),
2000-09-18 16:07:07 +00:00
aWndPos ( this ),
pRuntimeWindow ( lcl_chooseRuntimeImpl( this, pBind ) ),
2011-07-05 09:41:08 +01:00
aTextWindow ( *pRuntimeWindow ),
pInputHdl ( NULL ),
2000-09-18 16:07:07 +00:00
aTextOk ( ScResId( SCSTR_QHELP_BTNOK ) ), // nicht immer neu aus Resource
aTextCancel ( ScResId( SCSTR_QHELP_BTNCANCEL ) ),
aTextSum ( ScResId( SCSTR_QHELP_BTNSUM ) ),
aTextEqual ( ScResId( SCSTR_QHELP_BTNEQUAL ) ),
mnMaxY (0),
bIsOkCancelMode ( false ),
bInResize ( false ),
mbIsMultiLine ( lcl_isExperimentalMode() )
2000-09-18 16:07:07 +00:00
{
ScModule* pScMod = SC_MOD();
SfxImageManager* pImgMgr = SfxImageManager::GetImageManager( pScMod );
// #i73615# don't rely on SfxViewShell::Current while constructing the input line
// (also for GetInputHdl below)
ScTabViewShell* pViewSh = NULL;
SfxDispatcher* pDisp = pBind->GetDispatcher();
if ( pDisp )
{
SfxViewFrame* pViewFrm = pDisp->GetFrame();
if ( pViewFrm )
pViewSh = PTR_CAST( ScTabViewShell, pViewFrm->GetViewShell() );
}
OSL_ENSURE( pViewSh, "no view shell for input window" );
2000-09-18 16:07:07 +00:00
// Position window, 3 buttons, input window
2000-09-18 16:07:07 +00:00
InsertWindow ( 1, &aWndPos, 0, 0 );
InsertSeparator ( 1 );
InsertItem ( SID_INPUT_FUNCTION, IMAGE( SID_INPUT_FUNCTION ), 0, 2 );
InsertItem ( SID_INPUT_SUM, IMAGE( SID_INPUT_SUM ), 0, 3 );
InsertItem ( SID_INPUT_EQUAL, IMAGE( SID_INPUT_EQUAL ), 0, 4 );
InsertSeparator ( 5 );
InsertWindow ( 7, &aTextWindow, 0, 6 );
aWndPos .SetQuickHelpText( ScResId( SCSTR_QHELP_POSWND ) );
aWndPos .SetHelpId ( HID_INSWIN_POS );
aTextWindow.SetQuickHelpText( ScResId( SCSTR_QHELP_INPUTWND ) );
aTextWindow.SetHelpId ( HID_INSWIN_INPUT );
// kein SetHelpText, die Hilfetexte kommen aus der Hilfe
SetItemText ( SID_INPUT_FUNCTION, ScResId( SCSTR_QHELP_BTNCALC ) );
SetHelpId ( SID_INPUT_FUNCTION, HID_INSWIN_CALC );
SetItemText ( SID_INPUT_SUM, aTextSum );
SetHelpId ( SID_INPUT_SUM, HID_INSWIN_SUMME );
SetItemText ( SID_INPUT_EQUAL, aTextEqual );
SetHelpId ( SID_INPUT_EQUAL, HID_INSWIN_FUNC );
SetHelpId( HID_SC_INPUTWIN ); // fuer die ganze Eingabezeile
aWndPos .Show();
2011-07-05 09:41:08 +01:00
aTextWindow.Show();
2000-09-18 16:07:07 +00:00
pInputHdl = SC_MOD()->GetInputHdl( pViewSh, false ); // use own handler even if ref-handler is set
2000-09-18 16:07:07 +00:00
if (pInputHdl)
pInputHdl->SetInputWindow( this );
2012-02-08 23:00:59 -05:00
if (pInputHdl && !pInputHdl->GetFormString().isEmpty())
2000-09-18 16:07:07 +00:00
{
// Umschalten waehrend der Funktionsautopilot aktiv ist
// -> Inhalt des Funktionsautopiloten wieder anzeigen
//! auch Selektion (am InputHdl gemerkt) wieder anzeigen
aTextWindow.SetTextString( pInputHdl->GetFormString() );
}
else if ( pInputHdl && pInputHdl->IsInputMode() )
{
// wenn waehrend des Editierens die Eingabezeile weg war
// (Editieren einer Formel, dann umschalten zu fremdem Dokument/Hilfe),
// wieder den gerade editierten Text aus dem InputHandler anzeigen
aTextWindow.SetTextString( pInputHdl->GetEditString() ); // Text anzeigen
if ( pInputHdl->IsTopMode() )
pInputHdl->SetMode( SC_INPUT_TABLE ); // Focus kommt eh nach unten
}
else if ( pViewSh )
pViewSh->UpdateInputHandler( sal_True ); // unbedingtes Update
2000-09-18 16:07:07 +00:00
pImgMgr->RegisterToolBox( this );
SetAccessibleName(ScResId(STR_ACC_TOOLBAR_FORMULA));
2000-09-18 16:07:07 +00:00
}
2010-12-11 23:25:30 +01:00
ScInputWindow::~ScInputWindow()
2000-09-18 16:07:07 +00:00
{
sal_Bool bDown = ( ScGlobal::pSysLocale == NULL ); // after Clear?
2000-09-18 16:07:07 +00:00
// if any view's input handler has a pointer to this input window, reset it
// (may be several ones, #74522#)
// member pInputHdl is not used here
if ( !bDown )
{
TypeId aScType = TYPE(ScTabViewShell);
SfxViewShell* pSh = SfxViewShell::GetFirst( &aScType );
while ( pSh )
{
ScInputHandler* pHdl = ((ScTabViewShell*)pSh)->GetInputHandler();
if ( pHdl && pHdl->GetInputWindow() == this )
{
2000-09-18 16:07:07 +00:00
pHdl->SetInputWindow( NULL );
pHdl->StopInputWinEngine( false ); // reset pTopView pointer
}
2000-09-18 16:07:07 +00:00
pSh = SfxViewShell::GetNext( *pSh, &aScType );
}
}
SfxImageManager::GetImageManager( SC_MOD() )->ReleaseToolBox( this );
2000-09-18 16:07:07 +00:00
}
void ScInputWindow::SetInputHandler( ScInputHandler* pNew )
{
// wird im Activate der View gerufen...
if ( pNew != pInputHdl )
{
// Bei Reload (letzte Version) ist pInputHdl der Input-Handler der alten,
// geloeschten ViewShell, darum hier auf keinen Fall anfassen!
pInputHdl = pNew;
if (pInputHdl)
pInputHdl->SetInputWindow( this );
}
}
bool ScInputWindow::UseSubTotal(ScRangeList* pRangeList) const
{
bool bSubTotal = false;
ScTabViewShell* pViewSh = PTR_CAST( ScTabViewShell, SfxViewShell::Current() );
if ( pViewSh )
{
ScDocument* pDoc = pViewSh->GetViewData()->GetDocument();
size_t nRangeCount (pRangeList->size());
size_t nRangeIndex (0);
while (!bSubTotal && nRangeIndex < nRangeCount)
{
const ScRange* pRange = (*pRangeList)[nRangeIndex];
if( pRange )
{
SCTAB nTabEnd(pRange->aEnd.Tab());
SCTAB nTab(pRange->aStart.Tab());
while (!bSubTotal && nTab <= nTabEnd)
{
SCROW nRowEnd(pRange->aEnd.Row());
SCROW nRow(pRange->aStart.Row());
while (!bSubTotal && nRow <= nRowEnd)
{
if (pDoc->RowFiltered(nRow, nTab))
bSubTotal = true;
else
++nRow;
}
++nTab;
}
}
++nRangeIndex;
}
const ScDBCollection::NamedDBs& rDBs = pDoc->GetDBCollection()->getNamedDBs();
ScDBCollection::NamedDBs::const_iterator itr = rDBs.begin(), itrEnd = rDBs.end();
for (; !bSubTotal && itr != itrEnd; ++itr)
{
const ScDBData& rDB = *itr;
if (!rDB.HasAutoFilter())
continue;
nRangeIndex = 0;
while (!bSubTotal && nRangeIndex < nRangeCount)
{
const ScRange* pRange = (*pRangeList)[nRangeIndex];
if( pRange )
{
ScRange aDBArea;
rDB.GetArea(aDBArea);
if (aDBArea.Intersects(*pRange))
bSubTotal = true;
}
++nRangeIndex;
}
}
}
return bSubTotal;
}
2010-12-11 23:25:30 +01:00
void ScInputWindow::Select()
2000-09-18 16:07:07 +00:00
{
ScModule* pScMod = SC_MOD();
ToolBox::Select();
switch ( GetCurItemId() )
{
case SID_INPUT_FUNCTION:
{
//! new method at ScModule to query if function autopilot is open
SfxViewFrame* pViewFrm = SfxViewFrame::Current();
if ( pViewFrm && !pViewFrm->GetChildWindow( SID_OPENDLG_FUNCTION ) )
{
2000-09-22 17:57:10 +00:00
pViewFrm->GetDispatcher()->Execute( SID_OPENDLG_FUNCTION,
2000-09-18 16:07:07 +00:00
SFX_CALLMODE_SYNCHRON | SFX_CALLMODE_RECORD );
// die Toolbox wird sowieso disabled, also braucht auch nicht umgeschaltet
// zu werden, egal ob's geklappt hat oder nicht
// SetOkCancelMode();
}
}
break;
case SID_INPUT_CANCEL:
pScMod->InputCancelHandler();
SetSumAssignMode();
break;
case SID_INPUT_OK:
pScMod->InputEnterHandler();
SetSumAssignMode();
aTextWindow.Invalidate(); // sonst bleibt Selektion stehen
break;
case SID_INPUT_SUM:
{
ScTabViewShell* pViewSh = PTR_CAST( ScTabViewShell, SfxViewShell::Current() );
if ( pViewSh )
{
const ScMarkData& rMark = pViewSh->GetViewData()->GetMarkData();
if ( rMark.IsMarked() || rMark.IsMultiMarked() )
{
ScRangeList aMarkRangeList;
rMark.FillRangeListWithMarks( &aMarkRangeList, false );
ScDocument* pDoc = pViewSh->GetViewData()->GetDocument();
2000-09-18 16:07:07 +00:00
// check if one of the marked ranges is empty
bool bEmpty = false;
const size_t nCount = aMarkRangeList.size();
for ( size_t i = 0; i < nCount; ++i )
{
const ScRange aRange( *aMarkRangeList[i] );
if ( pDoc->IsBlockEmpty( aRange.aStart.Tab(),
aRange.aStart.Col(), aRange.aStart.Row(),
aRange.aEnd.Col(), aRange.aEnd.Row() ) )
{
bEmpty = true;
break;
}
}
if ( bEmpty )
{
ScRangeList aRangeList;
const sal_Bool bDataFound = pViewSh->GetAutoSumArea( aRangeList );
if ( bDataFound )
{
ScAddress aAddr = aRangeList.back()->aEnd;
aAddr.IncRow();
const sal_Bool bSubTotal( UseSubTotal( &aRangeList ) );
pViewSh->EnterAutoSum( aRangeList, bSubTotal, aAddr );
}
}
else
2000-09-18 16:07:07 +00:00
{
const sal_Bool bSubTotal( UseSubTotal( &aMarkRangeList ) );
for ( size_t i = 0; i < nCount; ++i )
{
const ScRange aRange( *aMarkRangeList[i] );
const bool bSetCursor = ( i == nCount - 1 ? true : false );
const bool bContinue = ( i != 0 ? true : false );
if ( !pViewSh->AutoSum( aRange, bSubTotal, bSetCursor, bContinue ) )
{
pViewSh->MarkRange( aRange, false, false );
pViewSh->SetCursor( aRange.aEnd.Col(), aRange.aEnd.Row() );
const ScRangeList aRangeList;
ScAddress aAddr = aRange.aEnd;
aAddr.IncRow();
const OUString aFormula = pViewSh->GetAutoSumFormula(
aRangeList, bSubTotal, aAddr );
SetFuncString( aFormula );
break;
}
}
2000-09-18 16:07:07 +00:00
}
}
else // nur in Eingabezeile einfuegen
{
ScRangeList aRangeList;
const sal_Bool bDataFound = pViewSh->GetAutoSumArea( aRangeList );
const sal_Bool bSubTotal( UseSubTotal( &aRangeList ) );
ScAddress aAddr = pViewSh->GetViewData()->GetCurPos();
const OUString aFormula = pViewSh->GetAutoSumFormula( aRangeList, bSubTotal, aAddr );
2000-09-18 16:07:07 +00:00
SetFuncString( aFormula );
if ( bDataFound && pScMod->IsEditMode() )
{
ScInputHandler* pHdl = pScMod->GetInputHdl( pViewSh );
if ( pHdl )
{
pHdl->InitRangeFinder( aFormula );
//! SetSelection am InputHandler ???
//! bSelIsRef setzen ???
const sal_Int32 nOpen = aFormula.indexOf('(');
const xub_StrLen nLen = aFormula.getLength();
if ( nOpen != -1 && nLen > nOpen )
2000-09-18 16:07:07 +00:00
{
sal_uInt8 nAdd(1);
if (bSubTotal)
nAdd = 3;
ESelection aSel(0,nOpen+nAdd,0,nLen-1);
2000-09-18 16:07:07 +00:00
EditView* pTableView = pHdl->GetTableView();
if (pTableView)
pTableView->SetSelection(aSel);
EditView* pTopView = pHdl->GetTopView();
if (pTopView)
pTopView->SetSelection(aSel);
}
}
}
}
}
}
break;
case SID_INPUT_EQUAL:
{
aTextWindow.StartEditEngine();
if ( pScMod->IsEditMode() ) // nicht, wenn z.B. geschuetzt
{
aTextWindow.StartEditEngine();
aTextWindow.SetTextString(OUString('='));
2000-09-18 16:07:07 +00:00
EditView* pView = aTextWindow.GetEditView();
if (pView)
{
pView->SetSelection( ESelection(0,1, 0,1) );
pScMod->InputChanged(pView);
SetOkCancelMode();
pView->SetEditEngineUpdateMode(sal_True);
2000-09-18 16:07:07 +00:00
}
}
break;
}
}
}
void ScInputWindow::Paint( const Rectangle& rRect )
{
ToolBox::Paint( rRect );
// draw a line at the bottom to distinguish that from the grid
// (we have space for that thanks to ADDITIONAL_BORDER)
const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
SetLineColor( rStyleSettings.GetShadowColor() );
Size aSize = GetSizePixel();
DrawLine( Point( 0, aSize.Height() - 1 ), Point( aSize.Width() - 1, aSize.Height() - 1 ) );
}
2010-12-11 23:25:30 +01:00
void ScInputWindow::Resize()
2000-09-18 16:07:07 +00:00
{
ToolBox::Resize();
if ( mbIsMultiLine )
2011-07-05 09:41:08 +01:00
{
aTextWindow.Resize();
2011-11-28 10:58:31 +00:00
Size aSize = GetSizePixel();
aSize.Height() = CalcWindowSizePixel().Height() + ADDITIONAL_BORDER;
ScInputBarGroup* pGroupBar = dynamic_cast< ScInputBarGroup* > ( pRuntimeWindow.get() );
if ( pGroupBar )
{
// To ensure smooth display and prevent the items in the toolbar being
// repositioned ( vertically ) we lock the vertical positioning of the toolbox
// items when we are displaying > 1 line.
// So, we need to adjust the height of the toolbox accordingly. If we don't
// then the largest item ( e.g. the GroupBar window ) will actually be
// positioned such that the toolbar will cut off the bottom of that item
if ( pGroupBar->GetNumLines() > 1 )
aSize.Height() += pGroupBar->GetVertOffset() + ADDITIONAL_SPACE;
}
SetSizePixel(aSize);
Invalidate();
2011-07-05 09:41:08 +01:00
}
else
{
long nWidth = GetSizePixel().Width();
long nLeft = aTextWindow.GetPosPixel().X();
Size aSize = aTextWindow.GetSizePixel();
aSize.Width() = std::max( ((long)(nWidth - nLeft - 5)), (long)0 );
aTextWindow.SetSizePixel( aSize );
aTextWindow.Invalidate();
}
2000-09-18 16:07:07 +00:00
}
void ScInputWindow::SetFuncString( const OUString& rString, sal_Bool bDoEdit )
2000-09-18 16:07:07 +00:00
{
//! new method at ScModule to query if function autopilot is open
SfxViewFrame* pViewFrm = SfxViewFrame::Current();
EnableButtons( pViewFrm && !pViewFrm->GetChildWindow( SID_OPENDLG_FUNCTION ) );
aTextWindow.StartEditEngine();
ScModule* pScMod = SC_MOD();
if ( pScMod->IsEditMode() )
{
if ( bDoEdit )
aTextWindow.GrabFocus();
2000-09-18 16:07:07 +00:00
aTextWindow.SetTextString( rString );
EditView* pView = aTextWindow.GetEditView();
if (pView)
{
sal_Int32 nLen = rString.getLength();
2000-09-18 16:07:07 +00:00
if ( nLen > 0 )
{
nLen--;
pView->SetSelection( ESelection( 0, nLen, 0, nLen ) );
}
pScMod->InputChanged(pView);
if ( bDoEdit )
SetOkCancelMode(); // nicht, wenn gleich hinterher Enter/Cancel
pView->SetEditEngineUpdateMode(sal_True);
2000-09-18 16:07:07 +00:00
}
}
}
void ScInputWindow::SetPosString( const OUString& rStr )
2000-09-18 16:07:07 +00:00
{
aWndPos.SetPos( rStr );
}
void ScInputWindow::SetTextString( const OUString& rString )
2000-09-18 16:07:07 +00:00
{
if (rString.getLength() <= 32767)
2000-09-18 16:07:07 +00:00
aTextWindow.SetTextString(rString);
else
aTextWindow.SetTextString(rString.copy(0, 32767));
2000-09-18 16:07:07 +00:00
}
void ScInputWindow::SetOkCancelMode()
{
//! new method at ScModule to query if function autopilot is open
SfxViewFrame* pViewFrm = SfxViewFrame::Current();
EnableButtons( pViewFrm && !pViewFrm->GetChildWindow( SID_OPENDLG_FUNCTION ) );
ScModule* pScMod = SC_MOD();
SfxImageManager* pImgMgr = SfxImageManager::GetImageManager( pScMod );
2000-09-18 16:07:07 +00:00
if (!bIsOkCancelMode)
{
RemoveItem( 3 ); // SID_INPUT_SUM und SID_INPUT_EQUAL entfernen
RemoveItem( 3 );
InsertItem( SID_INPUT_CANCEL, IMAGE( SID_INPUT_CANCEL ), 0, 3 );
InsertItem( SID_INPUT_OK, IMAGE( SID_INPUT_OK ), 0, 4 );
SetItemText ( SID_INPUT_CANCEL, aTextCancel );
SetHelpId ( SID_INPUT_CANCEL, HID_INSWIN_CANCEL );
SetItemText ( SID_INPUT_OK, aTextOk );
SetHelpId ( SID_INPUT_OK, HID_INSWIN_OK );
bIsOkCancelMode = sal_True;
2000-09-18 16:07:07 +00:00
}
}
void ScInputWindow::SetSumAssignMode()
{
//! new method at ScModule to query if function autopilot is open
SfxViewFrame* pViewFrm = SfxViewFrame::Current();
EnableButtons( pViewFrm && !pViewFrm->GetChildWindow( SID_OPENDLG_FUNCTION ) );
ScModule* pScMod = SC_MOD();
SfxImageManager* pImgMgr = SfxImageManager::GetImageManager( pScMod );
2000-09-18 16:07:07 +00:00
if (bIsOkCancelMode)
{
// SID_INPUT_CANCEL, und SID_INPUT_OK entfernen
RemoveItem( 3 );
RemoveItem( 3 );
InsertItem( SID_INPUT_SUM, IMAGE( SID_INPUT_SUM ), 0, 3 );
InsertItem( SID_INPUT_EQUAL, IMAGE( SID_INPUT_EQUAL ), 0, 4 );
SetItemText ( SID_INPUT_SUM, aTextSum );
SetHelpId ( SID_INPUT_SUM, HID_INSWIN_SUMME );
SetItemText ( SID_INPUT_EQUAL, aTextEqual );
SetHelpId ( SID_INPUT_EQUAL, HID_INSWIN_FUNC );
bIsOkCancelMode = false;
2000-09-18 16:07:07 +00:00
SetFormulaMode(false); // kein editieren -> keine Formel
2000-09-18 16:07:07 +00:00
}
}
void ScInputWindow::SetFormulaMode( sal_Bool bSet )
2000-09-18 16:07:07 +00:00
{
aWndPos.SetFormulaMode(bSet);
aTextWindow.SetFormulaMode(bSet);
}
void ScInputWindow::SetText( const OUString& rString )
2000-09-18 16:07:07 +00:00
{
ToolBox::SetText(rString);
}
OUString ScInputWindow::GetText() const
2000-09-18 16:07:07 +00:00
{
return ToolBox::GetText();
}
sal_Bool ScInputWindow::IsInputActive()
2000-09-18 16:07:07 +00:00
{
return aTextWindow.IsInputActive();
2000-09-18 16:07:07 +00:00
}
EditView* ScInputWindow::GetEditView()
{
return aTextWindow.GetEditView();
}
void ScInputWindow::MakeDialogEditView()
{
aTextWindow.MakeDialogEditView();
}
void ScInputWindow::StopEditEngine( sal_Bool bAll )
2000-09-18 16:07:07 +00:00
{
aTextWindow.StopEditEngine( bAll );
2000-09-18 16:07:07 +00:00
}
void ScInputWindow::TextGrabFocus()
{
aTextWindow.TextGrabFocus();
2000-09-18 16:07:07 +00:00
}
void ScInputWindow::TextInvalidate()
{
aTextWindow.Invalidate();
}
void ScInputWindow::SwitchToTextWin()
{
// used for shift-ctrl-F2
aTextWindow.StartEditEngine();
if ( SC_MOD()->IsEditMode() )
{
aTextWindow.TextGrabFocus();
EditView* pView = aTextWindow.GetEditView();
if (pView)
{
sal_Int32 nPara = pView->GetEditEngine()->GetParagraphCount() ? ( pView->GetEditEngine()->GetParagraphCount() - 1 ) : 0;
xub_StrLen nLen = pView->GetEditEngine()->GetTextLen( nPara );
ESelection aSel( nPara, nLen, nPara, nLen );
pView->SetSelection( aSel ); // set cursor to end of text
}
}
}
2000-09-18 16:07:07 +00:00
void ScInputWindow::PosGrabFocus()
{
aWndPos.GrabFocus();
}
void ScInputWindow::EnableButtons( sal_Bool bEnable )
2000-09-18 16:07:07 +00:00
{
// when enabling buttons, always also enable the input window itself
if ( bEnable && !IsEnabled() )
Enable();
2000-09-18 16:07:07 +00:00
EnableItem( SID_INPUT_FUNCTION, bEnable );
EnableItem( bIsOkCancelMode ? SID_INPUT_CANCEL : SID_INPUT_SUM, bEnable );
EnableItem( bIsOkCancelMode ? SID_INPUT_OK : SID_INPUT_EQUAL, bEnable );
// Invalidate();
}
void ScInputWindow::StateChanged( StateChangedType nType )
{
ToolBox::StateChanged( nType );
if ( nType == STATE_CHANGE_INITSHOW ) Resize();
}
void ScInputWindow::DataChanged( const DataChangedEvent& rDCEvt )
{
if ( rDCEvt.GetType() == DATACHANGED_SETTINGS && (rDCEvt.GetFlags() & SETTINGS_STYLE) )
{
// update item images
ScModule* pScMod = SC_MOD();
SfxImageManager* pImgMgr = SfxImageManager::GetImageManager( pScMod );
2010-11-22 16:59:17 -08:00
// IMAGE macro uses pScMod, pImgMg
SetItemImage( SID_INPUT_FUNCTION, IMAGE( SID_INPUT_FUNCTION ) );
if ( bIsOkCancelMode )
{
SetItemImage( SID_INPUT_CANCEL, IMAGE( SID_INPUT_CANCEL ) );
SetItemImage( SID_INPUT_OK, IMAGE( SID_INPUT_OK ) );
}
else
{
SetItemImage( SID_INPUT_SUM, IMAGE( SID_INPUT_SUM ) );
SetItemImage( SID_INPUT_EQUAL, IMAGE( SID_INPUT_EQUAL ) );
}
}
ToolBox::DataChanged( rDCEvt );
}
bool ScInputWindow::IsPointerAtResizePos()
{
if ( GetOutputSizePixel().Height() - GetPointerPosPixel().Y() <= 4 )
return true;
else
return false;
}
void ScInputWindow::MouseMove( const MouseEvent& rMEvt )
{
if ( mbIsMultiLine )
{
Point aPosPixel = GetPointerPosPixel();
ScInputBarGroup* pGroupBar = dynamic_cast< ScInputBarGroup* > ( pRuntimeWindow.get() );
if ( bInResize || IsPointerAtResizePos() )
SetPointer( Pointer( POINTER_WINDOW_SSIZE ) );
else
SetPointer( Pointer( POINTER_ARROW ) );
if ( bInResize )
{
// detect direction
long nResizeThreshold = ( (long)TBX_WINDOW_HEIGHT * 0.7 );
bool bResetPointerPos = false;
// Detect attempt to expand toolbar too much
if ( aPosPixel.Y() >= mnMaxY )
{
bResetPointerPos = true;
aPosPixel.Y() = mnMaxY;
} // or expanding down
else if ( GetOutputSizePixel().Height() - aPosPixel.Y() < -nResizeThreshold )
{
pGroupBar->IncrementVerticalSize();
bResetPointerPos = true;
} // or shrinking up
else if ( ( GetOutputSizePixel().Height() - aPosPixel.Y() ) > nResizeThreshold )
{
bResetPointerPos = true;
pGroupBar->DecrementVerticalSize();
}
if ( bResetPointerPos )
{
aPosPixel.Y() = GetOutputSizePixel().Height();
SetPointerPosPixel( aPosPixel );
}
}
}
ToolBox::MouseMove( rMEvt );
}
void ScInputWindow::MouseButtonDown( const MouseEvent& rMEvt )
{
if ( mbIsMultiLine )
{
if ( rMEvt.IsLeft() )
{
if ( IsPointerAtResizePos() )
{
// Don't leave the mouse pointer leave *this* window
CaptureMouse();
bInResize = true;
// find the height of the gridwin, we don't wan't to be
// able to expand the toolbar too far so we need to
// caculate an upper limit
// I'd prefer to leave at least a single column header and a
// row but I don't know how to get that value in pixels.
// Use TBX_WINDOW_HEIGHT for the moment
ScTabViewShell* pViewSh = ScTabViewShell::GetActiveViewShell();
mnMaxY = GetOutputSizePixel().Height() + ( pViewSh->GetGridHeight(SC_SPLIT_TOP) + pViewSh->GetGridHeight(SC_SPLIT_BOTTOM) ) - TBX_WINDOW_HEIGHT;
}
}
}
ToolBox::MouseButtonDown( rMEvt );
}
void ScInputWindow::MouseButtonUp( const MouseEvent& rMEvt )
{
if ( mbIsMultiLine )
{
ReleaseMouse();
if ( rMEvt.IsLeft() )
{
bInResize = false;
mnMaxY = 0;
}
}
ToolBox::MouseButtonUp( rMEvt );
}
2011-07-05 09:41:08 +01:00
//========================================================================
// ScInputBarGroup
//========================================================================
ScInputBarGroup::ScInputBarGroup(Window* pParent, ScTabViewShell* pViewSh)
: ScTextWndBase ( pParent, WinBits(WB_HIDE | WB_TABSTOP ) ),
aMultiTextWnd ( this, pViewSh ),
aButton ( this, WB_TABSTOP | WB_RECTSTYLE | WB_SMALLSTYLE ),
aScrollBar ( this, WB_TABSTOP | WB_VERT | WB_DRAG ),
nVertOffset ( 0 )
2011-07-05 09:41:08 +01:00
{
aMultiTextWnd.Show();
aMultiTextWnd.SetQuickHelpText( ScResId( SCSTR_QHELP_INPUTWND ) );
aMultiTextWnd.SetHelpId( HID_INSWIN_INPUT );
Size aSize( GetSettings().GetStyleSettings().GetScrollBarSize(), aMultiTextWnd.GetPixelHeightForLines(1) );
aButton.SetClickHdl( LINK( this, ScInputBarGroup, ClickHdl ) );
aButton.SetSizePixel( aSize );
aButton.Enable();
aButton.SetSymbol( SYMBOL_SPIN_DOWN );
aButton.SetQuickHelpText( ScResId( SCSTR_QHELP_EXPAND_FORMULA ) );
aButton.Show();
aScrollBar.SetSizePixel( aSize );
aScrollBar.SetScrollHdl( LINK( this, ScInputBarGroup, Impl_ScrollHdl ) );
2011-07-05 09:41:08 +01:00
}
ScInputBarGroup::~ScInputBarGroup()
{
}
void
ScInputBarGroup::InsertAccessibleTextData( ScAccessibleEditLineTextData& rTextData )
{
aMultiTextWnd.InsertAccessibleTextData( rTextData );
2011-07-05 09:41:08 +01:00
}
void
ScInputBarGroup::RemoveAccessibleTextData( ScAccessibleEditLineTextData& rTextData )
{
aMultiTextWnd.RemoveAccessibleTextData( rTextData );
2011-07-05 09:41:08 +01:00
}
const OUString&
2011-07-05 09:41:08 +01:00
ScInputBarGroup::GetTextString() const
{
return aMultiTextWnd.GetTextString();
2011-07-05 09:41:08 +01:00
}
void ScInputBarGroup::SetTextString( const OUString& rString )
2011-07-05 09:41:08 +01:00
{
aMultiTextWnd.SetTextString(rString);
2011-07-05 09:41:08 +01:00
}
void ScInputBarGroup::Resize()
{
Window *w=GetParent();
ScInputWindow *pParent;
pParent=dynamic_cast<ScInputWindow*>(w);
2011-07-05 09:41:08 +01:00
if(pParent==NULL)
{
OSL_FAIL("The parent window pointer pParent is null");
return;
}
long nWidth = pParent->GetSizePixel().Width();
long nLeft = GetPosPixel().X();
Size aSize = GetSizePixel();
aSize.Width() = std::max( ((long)(nWidth - nLeft - LEFT_OFFSET)), (long)0 );
aScrollBar.SetPosPixel(Point( aSize.Width() - aButton.GetSizePixel().Width(), aButton.GetSizePixel().Height() ) );
Size aTmpSize( aSize );
aTmpSize.Width() = aTmpSize.Width() - aButton.GetSizePixel().Width() - BUTTON_OFFSET;
aMultiTextWnd.SetSizePixel(aTmpSize);
aMultiTextWnd.Resize();
aSize.Height() = aMultiTextWnd.GetSizePixel().Height();
SetSizePixel(aSize);
if( aMultiTextWnd.GetNumLines() > 1 )
{
aButton.SetSymbol( SYMBOL_SPIN_UP );
aButton.SetQuickHelpText( ScResId( SCSTR_QHELP_COLLAPSE_FORMULA ) );
Size scrollSize = aButton.GetSizePixel();
scrollSize.Height() = aMultiTextWnd.GetSizePixel().Height() - aButton.GetSizePixel().Height();
aScrollBar.SetSizePixel( scrollSize );
Size aOutSz = aMultiTextWnd.GetOutputSize();
aScrollBar.SetVisibleSize( aOutSz.Height() );
aScrollBar.SetPageSize( aOutSz.Height() );
aScrollBar.SetLineSize( aMultiTextWnd.GetTextHeight() );
aScrollBar.SetRange( Range( 0, aMultiTextWnd.GetEditEngTxtHeight() ) );
aScrollBar.Resize();
aScrollBar.Show();
}
else
{
aButton.SetSymbol( SYMBOL_SPIN_DOWN );
aButton.SetQuickHelpText( ScResId( SCSTR_QHELP_EXPAND_FORMULA ) );
aScrollBar.Hide();
}
aButton.SetPosPixel(Point(aSize.Width() - aButton.GetSizePixel().Width(), 0));
Invalidate();
2011-07-05 09:41:08 +01:00
}
void ScInputBarGroup::StopEditEngine( sal_Bool bAll )
{
aMultiTextWnd.StopEditEngine( bAll );
2011-07-05 09:41:08 +01:00
}
void ScInputBarGroup::StartEditEngine()
{
aMultiTextWnd.StartEditEngine();
2011-07-05 09:41:08 +01:00
}
2011-07-05 09:41:08 +01:00
void ScInputBarGroup::MakeDialogEditView()
{
aMultiTextWnd.MakeDialogEditView();
2011-07-05 09:41:08 +01:00
}
EditView* ScInputBarGroup::GetEditView()
{
return aMultiTextWnd.GetEditView();
2011-07-05 09:41:08 +01:00
}
sal_Bool ScInputBarGroup::IsInputActive()
{
return aMultiTextWnd.IsInputActive();
2011-07-05 09:41:08 +01:00
}
void ScInputBarGroup::SetFormulaMode(sal_Bool bSet)
{
aMultiTextWnd.SetFormulaMode(bSet);
}
void ScInputBarGroup::IncrementVerticalSize()
{
aMultiTextWnd.SetNumLines( aMultiTextWnd.GetNumLines() + 1 );
TriggerToolboxLayout();
}
void ScInputBarGroup::DecrementVerticalSize()
{
if ( aMultiTextWnd.GetNumLines() > 1 )
{
aMultiTextWnd.SetNumLines( aMultiTextWnd.GetNumLines() - 1 );
TriggerToolboxLayout();
}
}
IMPL_LINK_NOARG(ScInputBarGroup, ClickHdl)
{
Window *w=GetParent();
ScInputWindow *pParent;
pParent=dynamic_cast<ScInputWindow*>(w);
if(pParent==NULL)
{
OSL_FAIL("The parent window pointer pParent is null");
return 1;
}
if( aMultiTextWnd.GetNumLines() > 1 )
{
aMultiTextWnd.SetNumLines( 1 );
}
else
{
aMultiTextWnd.SetNumLines( aMultiTextWnd.GetLastNumExpandedLines() );
}
TriggerToolboxLayout();
// Restore focus to input line(s) if necessary
if ( SC_MOD()->GetInputHdl()->IsTopMode() )
aMultiTextWnd.GrabFocus();
return 0;
}
void ScInputBarGroup::TriggerToolboxLayout()
{
Window *w=GetParent();
ScInputWindow *pParent;
pParent=dynamic_cast<ScInputWindow*>(w);
SfxViewFrame* pViewFrm = SfxViewFrame::Current();
// Capture the vertical position of this window in the toolbar, when we increase
// the size of the toolbar to accomadate expanded line input we need to take this
// into account
if ( !nVertOffset )
nVertOffset = pParent->GetItemPosRect( pParent->GetItemCount() - 1 ).Top();
if ( pViewFrm )
{
Reference< com::sun::star::beans::XPropertySet > xPropSet( pViewFrm->GetFrame().GetFrameInterface(), UNO_QUERY );
Reference< ::com::sun::star::frame::XLayoutManager > xLayoutManager;
if ( xPropSet.is() )
{
com::sun::star::uno::Any aValue = xPropSet->getPropertyValue("LayoutManager");
aValue >>= xLayoutManager;
}
if ( xLayoutManager.is() )
{
if ( aMultiTextWnd.GetNumLines() > 1)
pParent->SetToolbarLayoutMode( TBX_LAYOUT_LOCKVERT );
else
pParent->SetToolbarLayoutMode( TBX_LAYOUT_NORMAL );
xLayoutManager->lock();
DataChangedEvent aFakeUpdate( DATACHANGED_SETTINGS, NULL, SETTINGS_STYLE );
// this basically will trigger the reposititioning of the
// items in the toolbar from ImplFormat ( which is controlled by
// mnWinHeight ) which in turn is updated in ImplCalcItem which is
// controlled by mbCalc. Additionally the ImplFormat above is
// controlled via mbFormat. It seems the easiest way to get these
// booleans set is to send in the fake event below.
pParent->DataChanged( aFakeUpdate);
2011-11-28 10:58:31 +00:00
// highest item in toolbar will have been calculated via the
// event above. Call resize on InputBar to pick up the height
// change
pParent->Resize();
// unlock relayouts the toolbars in the 4 quadrants
xLayoutManager->unlock();
}
}
2011-07-05 09:41:08 +01:00
}
IMPL_LINK_NOARG(ScInputBarGroup, Impl_ScrollHdl)
{
aMultiTextWnd.DoScroll();
2011-09-07 13:26:36 -04:00
return 0;
}
void ScInputBarGroup::TextGrabFocus()
{
aMultiTextWnd.TextGrabFocus();
}
//========================================================================
// ScMultiTextWnd
//========================================================================
ScMultiTextWnd::ScMultiTextWnd( ScInputBarGroup* pParen, ScTabViewShell* pViewSh )
:
ScTextWnd( pParen, pViewSh ),
mrGroupBar(* pParen ),
mnLines( 1 ),
mnLastExpandedLines( INPUTWIN_MULTILINES ),
mbInvalidate( false )
2011-07-05 09:41:08 +01:00
{
Size aBorder;
aBorder = CalcWindowSize( aBorder);
mnBorderHeight = aBorder.Height();
}
ScMultiTextWnd::~ScMultiTextWnd()
{
2011-07-05 09:41:08 +01:00
}
void ScMultiTextWnd::Paint( const Rectangle& rRect )
{
EditView* pView = GetEditView();
if ( pView )
{
if ( mbInvalidate )
{
pView->Invalidate();
mbInvalidate = false;
}
pEditView->Paint( rRect );
}
}
EditView* ScMultiTextWnd::GetEditView()
2011-07-05 09:41:08 +01:00
{
if ( !pEditView )
InitEditEngine();
return pEditView;
2011-07-05 09:41:08 +01:00
}
long ScMultiTextWnd::GetPixelHeightForLines( long nLines )
2011-07-05 09:41:08 +01:00
{
// add padding ( for the borders of the window )
return ( nLines * LogicToPixel( Size( 0, GetTextHeight() ) ).Height() ) + mnBorderHeight;
}
void ScMultiTextWnd::SetNumLines( long nLines )
{
mnLines = nLines;
if ( nLines > 1 )
2011-11-28 10:58:31 +00:00
{
mnLastExpandedLines = nLines;
2011-11-28 10:58:31 +00:00
Resize();
}
}
void ScMultiTextWnd::Resize()
{
// Only Height is recalculated here, Width is applied from
// parent/container window
Size aTextBoxSize = GetSizePixel();
aTextBoxSize.Height() = GetPixelHeightForLines( mnLines );
SetSizePixel( aTextBoxSize );
if(pEditView)
{
Size aOutputSize = GetOutputSizePixel();
Rectangle aOutputArea = PixelToLogic( Rectangle( Point(), aOutputSize ));
pEditView->SetOutputArea( aOutputArea );
// Don't leave an empty area at the bottom if we can move the text down.
long nMaxVisAreaTop = pEditEngine->GetTextHeight() - aOutputArea.GetHeight();
if (pEditView->GetVisArea().Top() > nMaxVisAreaTop)
{
pEditView->Scroll(0, pEditView->GetVisArea().Top() - nMaxVisAreaTop);
}
pEditEngine->SetPaperSize( PixelToLogic( Size( aOutputSize.Width(), 10000 ) ) );
}
2011-11-28 10:58:31 +00:00
SetScrollBarRange();
}
IMPL_LINK(ScMultiTextWnd, ModifyHdl, EENotify*, pNotify)
{
ScTextWnd::NotifyHdl( pNotify );
return 0;
}
IMPL_LINK(ScMultiTextWnd, NotifyHdl, EENotify*, pNotify)
{
// need to process EE_NOTIFY_TEXTVIEWSCROLLED here
// sometimes we don't seem to get EE_NOTIFY_TEXTVIEWSCROLLED e.g. when
// we insert text at the beginning of the text so the cursor never moves
// down to generate a scroll event
if ( pNotify && ( pNotify->eNotificationType == EE_NOTIFY_TEXTVIEWSCROLLED
|| pNotify->eNotificationType == EE_NOTIFY_TEXTHEIGHTCHANGED ) )
SetScrollBarRange();
return 0;
}
long ScMultiTextWnd::GetEditEngTxtHeight()
{
return pEditView ? pEditView->GetEditEngine()->GetTextHeight() : 0;
}
void ScMultiTextWnd::SetScrollBarRange()
{
if ( pEditView )
{
ScrollBar& rVBar = mrGroupBar.GetScrollBar();
rVBar.SetRange( Range( 0, GetEditEngTxtHeight() ) );
long currentDocPos = pEditView->GetVisArea().TopLeft().Y();
rVBar.SetThumbPos( currentDocPos );
}
}
void
ScMultiTextWnd::DoScroll()
{
if ( pEditView )
{
ScrollBar& rVBar = mrGroupBar.GetScrollBar();
long currentDocPos = pEditView->GetVisArea().TopLeft().Y();
long nDiff = currentDocPos - rVBar.GetThumbPos();
pEditView->Scroll( 0, nDiff );
currentDocPos = pEditView->GetVisArea().TopLeft().Y();
rVBar.SetThumbPos( currentDocPos );
}
}
void ScMultiTextWnd::StartEditEngine()
{
// Bei "eigener Modalitaet" (Doc-modale Dialoge) nicht aktivieren
SfxObjectShell* pObjSh = SfxObjectShell::Current();
if ( pObjSh && pObjSh->IsInModalMode() )
return;
if ( !pEditView || !pEditEngine )
{
InitEditEngine();
}
SC_MOD()->SetInputMode( SC_INPUT_TOP );
SfxViewFrame* pViewFrm = SfxViewFrame::Current();
if (pViewFrm)
pViewFrm->GetBindings().Invalidate( SID_ATTR_INSERT );
}
static void lcl_ExtendEditFontAttribs( SfxItemSet& rSet )
{
const SfxPoolItem& rFontItem = rSet.Get( EE_CHAR_FONTINFO );
rSet.Put( rFontItem, EE_CHAR_FONTINFO_CJK );
rSet.Put( rFontItem, EE_CHAR_FONTINFO_CTL );
const SfxPoolItem& rHeightItem = rSet.Get( EE_CHAR_FONTHEIGHT );
rSet.Put( rHeightItem, EE_CHAR_FONTHEIGHT_CJK );
rSet.Put( rHeightItem, EE_CHAR_FONTHEIGHT_CTL );
const SfxPoolItem& rWeightItem = rSet.Get( EE_CHAR_WEIGHT );
rSet.Put( rWeightItem, EE_CHAR_WEIGHT_CJK );
rSet.Put( rWeightItem, EE_CHAR_WEIGHT_CTL );
const SfxPoolItem& rItalicItem = rSet.Get( EE_CHAR_ITALIC );
rSet.Put( rItalicItem, EE_CHAR_ITALIC_CJK );
rSet.Put( rItalicItem, EE_CHAR_ITALIC_CTL );
const SfxPoolItem& rLangItem = rSet.Get( EE_CHAR_LANGUAGE );
rSet.Put( rLangItem, EE_CHAR_LANGUAGE_CJK );
rSet.Put( rLangItem, EE_CHAR_LANGUAGE_CTL );
}
static void lcl_ModifyRTLDefaults( SfxItemSet& rSet )
{
rSet.Put( SvxAdjustItem( SVX_ADJUST_RIGHT, EE_PARA_JUST ) );
// always using rtl writing direction would break formulas
//rSet.Put( SvxFrameDirectionItem( FRMDIR_HORI_RIGHT_TOP, EE_PARA_WRITINGDIR ) );
// PaperSize width is limited to USHRT_MAX in RTL mode (because of EditEngine's
// sal_uInt16 values in EditLine), so the text may be wrapped and line spacing must be
// increased to not see the beginning of the next line.
SvxLineSpacingItem aItem( SVX_LINESPACE_TWO_LINES, EE_PARA_SBL );
aItem.SetPropLineSpace( 200 );
rSet.Put( aItem );
}
static void lcl_ModifyRTLVisArea( EditView* pEditView )
{
Rectangle aVisArea = pEditView->GetVisArea();
Size aPaper = pEditView->GetEditEngine()->GetPaperSize();
long nDiff = aPaper.Width() - aVisArea.Right();
aVisArea.Left() += nDiff;
aVisArea.Right() += nDiff;
pEditView->SetVisArea(aVisArea);
}
void ScMultiTextWnd::InitEditEngine()
{
ScFieldEditEngine* pNew;
ScTabViewShell* pViewSh = GetViewShell();
ScDocShell* pDocSh = NULL;
if ( pViewSh )
{
pDocSh = pViewSh->GetViewData()->GetDocShell();
ScDocument* pDoc = pViewSh->GetViewData()->GetDocument();
pNew = new ScFieldEditEngine(pDoc, pDoc->GetEnginePool(), pDoc->GetEditPool());
}
else
pNew = new ScFieldEditEngine(NULL, EditEngine::CreatePool(), NULL, true);
pNew->SetExecuteURL( false );
pEditEngine = pNew;
Size barSize=GetSizePixel();
pEditEngine->SetUpdateMode( false );
pEditEngine->SetPaperSize( PixelToLogic(Size(barSize.Width(),10000)) );
pEditEngine->SetWordDelimiters(
ScEditUtil::ModifyDelimiters( pEditEngine->GetWordDelimiters() ) );
UpdateAutoCorrFlag();
{
SfxItemSet* pSet = new SfxItemSet( pEditEngine->GetEmptyItemSet() );
pEditEngine->SetFontInfoInItemSet( *pSet, aTextFont );
lcl_ExtendEditFontAttribs( *pSet );
// turn off script spacing to match DrawText output
pSet->Put( SvxScriptSpaceItem( false, EE_PARA_ASIANCJKSPACING ) );
if ( bIsRTL )
lcl_ModifyRTLDefaults( *pSet );
pEditEngine->SetDefaults( pSet );
2011-07-05 09:41:08 +01:00
}
// Wenn in der Zelle URL-Felder enthalten sind, muessen die auch in
// die Eingabezeile uebernommen werden, weil sonst die Positionen nicht stimmen.
sal_Bool bFilled = false;
ScInputHandler* pHdl = SC_MOD()->GetInputHdl();
if ( pHdl ) //! Testen, ob's der richtige InputHdl ist?
bFilled = pHdl->GetTextAndFields( *pEditEngine );
pEditEngine->SetUpdateMode( sal_True );
// aString ist die Wahrheit...
if (bFilled && pEditEngine->GetText() == aString)
Invalidate(); // Repaint fuer (hinterlegte) Felder
else
pEditEngine->SetText(aString); // dann wenigstens den richtigen Text
pEditView = new EditView( pEditEngine, this );
pEditView->SetInsertMode(bIsInsertMode);
// Text aus Clipboard wird als ASCII einzeilig uebernommen
sal_uLong n = pEditView->GetControlWord();
pEditView->SetControlWord( n | EV_CNTRL_SINGLELINEPASTE );
pEditEngine->InsertView( pEditView, EE_APPEND );
Resize();
if ( bIsRTL )
lcl_ModifyRTLVisArea( pEditView );
pEditEngine->SetModifyHdl(LINK(this, ScMultiTextWnd, ModifyHdl));
pEditEngine->SetNotifyHdl(LINK(this, ScMultiTextWnd, NotifyHdl));
if (!maAccTextDatas.empty())
maAccTextDatas.back()->StartEdit();
// as long as EditEngine and DrawText sometimes differ for CTL text,
// repaint now to have the EditEngine's version visible
if (pDocSh)
{
ScDocument* pDoc = pDocSh->GetDocument(); // any document
sal_uInt8 nScript = pDoc->GetStringScriptType( aString );
if ( nScript & SCRIPTTYPE_COMPLEX )
Invalidate();
}
}
void ScMultiTextWnd::StopEditEngine( sal_Bool bAll )
{
if ( pEditEngine )
pEditEngine->SetNotifyHdl(Link());
ScTextWnd::StopEditEngine( bAll );
2011-07-05 09:41:08 +01:00
}
void ScMultiTextWnd::SetTextString( const OUString& rNewString )
{
// Ideally it would be best to create on demand the EditEngine/EditView here, but... for
// the initialisation scenario where a cell is first clicked on we end up with the text in the
// inputbar window scrolled to the bottom if we do that here ( because the tableview and topview
// are synced I guess ).
// should fix that I suppose :-/ need to look a bit further into that
mbInvalidate = true; // ensure next Paint ( that uses editengine ) call will call Invalidate first
ScTextWnd::SetTextString( rNewString );
SetScrollBarRange();
DoScroll();
}
2000-09-18 16:07:07 +00:00
//========================================================================
// ScTextWnd
2000-09-18 16:07:07 +00:00
//========================================================================
ScTextWnd::ScTextWnd( Window* pParent, ScTabViewShell* pViewSh )
2011-07-05 09:41:08 +01:00
: ScTextWndBase ( pParent, WinBits(WB_HIDE | WB_BORDER) ),
2001-04-03 16:44:46 +00:00
DragSourceHelper( this ),
2000-09-18 16:07:07 +00:00
pEditEngine ( NULL ),
pEditView ( NULL ),
bIsInsertMode( sal_True ),
bFormulaMode ( false ),
2011-07-05 09:41:08 +01:00
bInputMode ( false ),
mpViewShell(pViewSh)
2000-09-18 16:07:07 +00:00
{
EnableRTL( false ); // EditEngine can't be used with VCL EnableRTL
bIsRTL = GetSettings().GetLayoutRTL();
2011-03-01 14:29:24 +01:00
// always use application font, so a font with cjk chars can be installed
2000-09-18 16:07:07 +00:00
Font aAppFont = GetFont();
aTextFont = aAppFont;
aTextFont.SetSize( PixelToLogic( aAppFont.GetSize(), MAP_TWIP ) ); // AppFont ist in Pixeln
const StyleSettings& rStyleSettings = Application::GetSettings().GetStyleSettings();
Color aBgColor= rStyleSettings.GetWindowColor();
Color aTxtColor= rStyleSettings.GetWindowTextColor();
aTextFont.SetTransparent ( sal_True );
2000-09-18 16:07:07 +00:00
aTextFont.SetFillColor ( aBgColor );
//aTextFont.SetColor ( COL_FIELDTEXT );
aTextFont.SetColor (aTxtColor);
aTextFont.SetWeight ( WEIGHT_NORMAL );
Size aSize(1,TBX_WINDOW_HEIGHT);
Size aMinEditSize( Edit::GetMinimumEditSize() );
if( aMinEditSize.Height() > aSize.Height() )
aSize.Height() = aMinEditSize.Height();
SetSizePixel ( aSize );
2000-09-18 16:07:07 +00:00
SetBackground ( aBgColor );
SetLineColor ( COL_BLACK );
SetMapMode ( MAP_TWIP );
SetPointer ( POINTER_TEXT );
SetFont( aTextFont );
2000-09-18 16:07:07 +00:00
}
2010-12-11 23:25:30 +01:00
ScTextWnd::~ScTextWnd()
2000-09-18 16:07:07 +00:00
{
while (!maAccTextDatas.empty()) {
maAccTextDatas.back()->Dispose();
}
delete pEditView;
delete pEditEngine;
2000-09-18 16:07:07 +00:00
}
void ScTextWnd::Paint( const Rectangle& rRect )
2000-09-18 16:07:07 +00:00
{
if (pEditView)
pEditView->Paint( rRect );
2000-09-18 16:07:07 +00:00
else
{
SetFont( aTextFont );
long nDiff = GetOutputSizePixel().Height()
- LogicToPixel( Size( 0, GetTextHeight() ) ).Height();
// if (nDiff<2) nDiff=2; // mind. 1 Pixel
long nStartPos = 0;
if ( bIsRTL )
{
// right-align
nStartPos += GetOutputSizePixel().Width() -
LogicToPixel( Size( GetTextWidth( aString ), 0 ) ).Width();
// LayoutMode isn't changed as long as ModifyRTLDefaults doesn't include SvxFrameDirectionItem
}
DrawText( PixelToLogic( Point( nStartPos, nDiff/2 ) ), aString );
2000-09-18 16:07:07 +00:00
}
}
2010-12-11 23:25:30 +01:00
void ScTextWnd::Resize()
2000-09-18 16:07:07 +00:00
{
if (pEditView)
{
Size aSize = GetOutputSizePixel();
long nDiff = aSize.Height()
- LogicToPixel( Size( 0, GetTextHeight() ) ).Height();
pEditView->SetOutputArea(
PixelToLogic( Rectangle( Point( 0, (nDiff > 0) ? nDiff/2 : 1 ),
2000-09-18 16:07:07 +00:00
aSize ) ) );
}
}
2010-12-11 23:25:30 +01:00
void ScTextWnd::MouseMove( const MouseEvent& rMEvt )
2000-09-18 16:07:07 +00:00
{
if (pEditView)
pEditView->MouseMove( rMEvt );
}
2010-12-11 23:25:30 +01:00
void ScTextWnd::MouseButtonDown( const MouseEvent& rMEvt )
2000-09-18 16:07:07 +00:00
{
if (!HasFocus())
{
StartEditEngine();
if ( SC_MOD()->IsEditMode() )
GrabFocus();
}
if (pEditView)
{
pEditView->SetEditEngineUpdateMode( sal_True );
2000-09-18 16:07:07 +00:00
pEditView->MouseButtonDown( rMEvt );
}
}
2010-12-11 23:25:30 +01:00
void ScTextWnd::MouseButtonUp( const MouseEvent& rMEvt )
2000-09-18 16:07:07 +00:00
{
if (pEditView)
if (pEditView->MouseButtonUp( rMEvt ))
2001-10-02 17:32:43 +00:00
{
if ( rMEvt.IsMiddle() &&
GetSettings().GetMouseSettings().GetMiddleButtonAction() == MOUSE_MIDDLE_PASTESELECTION )
{
// EditView may have pasted from selection
SC_MOD()->InputChanged( pEditView );
}
else
SC_MOD()->InputSelection( pEditView );
}
2000-09-18 16:07:07 +00:00
}
2010-12-11 23:25:30 +01:00
void ScTextWnd::Command( const CommandEvent& rCEvt )
2000-09-18 16:07:07 +00:00
{
bInputMode = sal_True;
sal_uInt16 nCommand = rCEvt.GetCommand();
if ( pEditView /* && nCommand == COMMAND_STARTDRAG */ )
2000-09-18 16:07:07 +00:00
{
ScModule* pScMod = SC_MOD();
ScTabViewShell* pStartViewSh = ScTabViewShell::GetActiveViewShell();
2011-03-01 14:29:24 +01:00
// don't modify the font defaults here - the right defaults are
// already set in StartEditEngine when the EditEngine is created
2000-09-18 16:07:07 +00:00
2011-03-01 14:29:24 +01:00
// verhindern, dass die EditView beim View-Umschalten wegkommt
pScMod->SetInEditCommand( true );
2000-09-18 16:07:07 +00:00
pEditView->Command( rCEvt );
pScMod->SetInEditCommand( false );
2000-09-18 16:07:07 +00:00
2011-03-01 14:29:24 +01:00
// COMMAND_STARTDRAG heiss noch lange nicht, dass der Inhalt geaendert wurde
2000-09-18 16:07:07 +00:00
// darum in dem Fall kein InputChanged
//! erkennen, ob mit Move gedraggt wurde, oder Drag&Move irgendwie verbieten
if ( nCommand == COMMAND_STARTDRAG )
{
// ist auf eine andere View gedraggt worden?
ScTabViewShell* pEndViewSh = ScTabViewShell::GetActiveViewShell();
if ( pEndViewSh != pStartViewSh && pStartViewSh != NULL )
{
ScViewData* pViewData = pStartViewSh->GetViewData();
ScInputHandler* pHdl = pScMod->GetInputHdl( pStartViewSh );
if ( pHdl && pViewData->HasEditView( pViewData->GetActivePart() ) )
{
pHdl->CancelHandler();
pViewData->GetView()->ShowCursor(); // fehlt bei KillEditView, weil nicht aktiv
}
}
}
else if ( nCommand == COMMAND_CURSORPOS )
{
// don't call InputChanged for COMMAND_CURSORPOS
}
else if ( nCommand == COMMAND_INPUTLANGUAGECHANGE )
{
// #i55929# Font and font size state depends on input language if nothing is selected,
// so the slots have to be invalidated when the input language is changed.
SfxViewFrame* pViewFrm = SfxViewFrame::Current();
if (pViewFrm)
{
SfxBindings& rBindings = pViewFrm->GetBindings();
rBindings.Invalidate( SID_ATTR_CHAR_FONT );
rBindings.Invalidate( SID_ATTR_CHAR_FONTHEIGHT );
}
}
else if ( nCommand == COMMAND_WHEEL )
{
//don't call InputChanged for COMMAND_WHEEL
}
2000-09-18 16:07:07 +00:00
else
SC_MOD()->InputChanged( pEditView );
}
else
Window::Command(rCEvt); // sonst soll sich die Basisklasse drum kuemmern...
bInputMode = false;
2000-09-18 16:07:07 +00:00
}
void ScTextWnd::StartDrag( sal_Int8 /* nAction */, const Point& rPosPixel )
2001-04-03 16:44:46 +00:00
{
if ( pEditView )
{
CommandEvent aDragEvent( rPosPixel, COMMAND_STARTDRAG, sal_True );
2001-04-03 16:44:46 +00:00
pEditView->Command( aDragEvent );
// handling of d&d to different view (CancelHandler) can't be done here,
// because the call returns before d&d is complete.
}
}
2010-12-11 23:25:30 +01:00
void ScTextWnd::KeyInput(const KeyEvent& rKEvt)
2000-09-18 16:07:07 +00:00
{
bInputMode = sal_True;
2000-09-18 16:07:07 +00:00
if (!SC_MOD()->InputKeyEvent( rKEvt ))
{
sal_Bool bUsed = false;
2000-09-18 16:07:07 +00:00
ScTabViewShell* pViewSh = ScTabViewShell::GetActiveViewShell();
if ( pViewSh )
bUsed = pViewSh->SfxKeyInput(rKEvt); // nur Acceleratoren, keine Eingabe
if (!bUsed)
Window::KeyInput( rKEvt );
}
bInputMode = false;
2000-09-18 16:07:07 +00:00
}
2010-12-11 23:25:30 +01:00
void ScTextWnd::GetFocus()
2000-09-18 16:07:07 +00:00
{
ScTabViewShell* pViewSh = ScTabViewShell::GetActiveViewShell();
if ( pViewSh )
pViewSh->SetFormShellAtTop( false ); // focus in input line -> FormShell no longer on top
2000-09-18 16:07:07 +00:00
}
2010-12-11 23:25:30 +01:00
void ScTextWnd::LoseFocus()
2000-09-18 16:07:07 +00:00
{
}
OUString ScTextWnd::GetText() const
2000-09-18 16:07:07 +00:00
{
// ueberladen, um per Testtool an den Text heranzukommen
if ( pEditEngine )
return pEditEngine->GetText();
else
return GetTextString();
}
void ScTextWnd::SetFormulaMode( sal_Bool bSet )
2000-09-18 16:07:07 +00:00
{
if ( bSet != bFormulaMode )
{
bFormulaMode = bSet;
UpdateAutoCorrFlag();
}
}
void ScTextWnd::UpdateAutoCorrFlag()
{
if ( pEditEngine )
{
sal_uLong nControl = pEditEngine->GetControlWord();
sal_uLong nOld = nControl;
2000-09-18 16:07:07 +00:00
if ( bFormulaMode )
nControl &= ~EE_CNTRL_AUTOCORRECT; // keine Autokorrektur in Formeln
else
nControl |= EE_CNTRL_AUTOCORRECT; // sonst schon
if ( nControl != nOld )
pEditEngine->SetControlWord( nControl );
}
}
ScTabViewShell* ScTextWnd::GetViewShell()
{
return mpViewShell;
}
2000-09-18 16:07:07 +00:00
void ScTextWnd::StartEditEngine()
{
2011-03-01 14:29:24 +01:00
// Bei "eigener Modalitaet" (Doc-modale Dialoge) nicht aktivieren
2000-09-18 16:07:07 +00:00
SfxObjectShell* pObjSh = SfxObjectShell::Current();
if ( pObjSh && pObjSh->IsInModalMode() )
return;
if ( !pEditView || !pEditEngine )
{
ScFieldEditEngine* pNew;
ScTabViewShell* pViewSh = ScTabViewShell::GetActiveViewShell();
if ( pViewSh )
{
ScDocument* pDoc = pViewSh->GetViewData()->GetDocument();
pNew = new ScFieldEditEngine(pDoc, pDoc->GetEnginePool(), pDoc->GetEditPool());
2000-09-18 16:07:07 +00:00
}
else
pNew = new ScFieldEditEngine(NULL, EditEngine::CreatePool(), NULL, true);
pNew->SetExecuteURL( false );
2000-09-18 16:07:07 +00:00
pEditEngine = pNew;
pEditEngine->SetUpdateMode( false );
pEditEngine->SetPaperSize( Size( bIsRTL ? USHRT_MAX : THESIZE, 300 ) );
2000-09-18 16:07:07 +00:00
pEditEngine->SetWordDelimiters(
ScEditUtil::ModifyDelimiters( pEditEngine->GetWordDelimiters() ) );
UpdateAutoCorrFlag();
{
SfxItemSet* pSet = new SfxItemSet( pEditEngine->GetEmptyItemSet() );
pEditEngine->SetFontInfoInItemSet( *pSet, aTextFont );
lcl_ExtendEditFontAttribs( *pSet );
// turn off script spacing to match DrawText output
pSet->Put( SvxScriptSpaceItem( false, EE_PARA_ASIANCJKSPACING ) );
if ( bIsRTL )
lcl_ModifyRTLDefaults( *pSet );
2000-09-18 16:07:07 +00:00
pEditEngine->SetDefaults( pSet );
}
2011-03-01 14:29:24 +01:00
// Wenn in der Zelle URL-Felder enthalten sind, muessen die auch in
2000-09-18 16:07:07 +00:00
// die Eingabezeile uebernommen werden, weil sonst die Positionen nicht stimmen.
sal_Bool bFilled = false;
2000-09-18 16:07:07 +00:00
ScInputHandler* pHdl = SC_MOD()->GetInputHdl();
if ( pHdl ) //! Testen, ob's der richtige InputHdl ist?
bFilled = pHdl->GetTextAndFields( *pEditEngine );
pEditEngine->SetUpdateMode( sal_True );
2000-09-18 16:07:07 +00:00
// aString ist die Wahrheit...
if (bFilled && pEditEngine->GetText() == aString)
2000-09-18 16:07:07 +00:00
Invalidate(); // Repaint fuer (hinterlegte) Felder
else
pEditEngine->SetText(aString); // dann wenigstens den richtigen Text
pEditView = new EditView( pEditEngine, this );
pEditView->SetInsertMode(bIsInsertMode);
// Text aus Clipboard wird als ASCII einzeilig uebernommen
sal_uLong n = pEditView->GetControlWord();
2000-09-18 16:07:07 +00:00
pEditView->SetControlWord( n | EV_CNTRL_SINGLELINEPASTE );
pEditEngine->InsertView( pEditView, EE_APPEND );
Resize();
if ( bIsRTL )
lcl_ModifyRTLVisArea( pEditView );
pEditEngine->SetModifyHdl(LINK(this, ScTextWnd, NotifyHdl));
if (!maAccTextDatas.empty())
maAccTextDatas.back()->StartEdit();
// as long as EditEngine and DrawText sometimes differ for CTL text,
// repaint now to have the EditEngine's version visible
// SfxObjectShell* pObjSh = SfxObjectShell::Current();
if ( pObjSh && pObjSh->ISA(ScDocShell) )
{
ScDocument* pDoc = ((ScDocShell*)pObjSh)->GetDocument(); // any document
sal_uInt8 nScript = pDoc->GetStringScriptType( aString );
if ( nScript & SCRIPTTYPE_COMPLEX )
Invalidate();
}
2000-09-18 16:07:07 +00:00
}
SC_MOD()->SetInputMode( SC_INPUT_TOP );
2000-09-22 17:57:10 +00:00
SfxViewFrame* pViewFrm = SfxViewFrame::Current();
if (pViewFrm)
pViewFrm->GetBindings().Invalidate( SID_ATTR_INSERT );
2000-09-18 16:07:07 +00:00
}
IMPL_LINK_NOARG(ScTextWnd, NotifyHdl)
{
if (pEditView && !bInputMode)
{
ScInputHandler* pHdl = SC_MOD()->GetInputHdl();
2011-03-01 14:29:24 +01:00
// Use the InputHandler's InOwnChange flag to prevent calling InputChanged
// while an InputHandler method is modifying the EditEngine content
if ( pHdl && !pHdl->IsInOwnChange() )
pHdl->InputChanged( pEditView, sal_True ); // #i20282# InputChanged must know if called from modify handler
}
return 0;
}
void ScTextWnd::StopEditEngine( sal_Bool bAll )
2000-09-18 16:07:07 +00:00
{
if (pEditView)
{
if (!maAccTextDatas.empty())
maAccTextDatas.back()->EndEdit();
2000-09-18 16:07:07 +00:00
ScModule* pScMod = SC_MOD();
if (!bAll)
pScMod->InputSelection( pEditView );
2000-09-18 16:07:07 +00:00
aString = pEditEngine->GetText();
bIsInsertMode = pEditView->IsInsertMode();
sal_Bool bSelection = pEditView->HasSelection();
pEditEngine->SetModifyHdl(Link());
2000-09-18 16:07:07 +00:00
DELETEZ(pEditView);
DELETEZ(pEditEngine);
if ( pScMod->IsEditMode() && !bAll )
2000-09-18 16:07:07 +00:00
pScMod->SetInputMode(SC_INPUT_TABLE);
2000-09-22 17:57:10 +00:00
SfxViewFrame* pViewFrm = SfxViewFrame::Current();
if (pViewFrm)
pViewFrm->GetBindings().Invalidate( SID_ATTR_INSERT );
2000-09-18 16:07:07 +00:00
if (bSelection)
Invalidate(); // damit Selektion nicht stehenbleibt
}
}
static sal_Int32 findFirstNonMatchingChar(const OUString& rStr1, const OUString rStr2)
{
// Search the string for unmatching chars
const sal_Unicode* pStr1 = rStr1.getStr();
const sal_Unicode* pStr2 = rStr2.getStr();
sal_Int32 i = 0;
while ( i < rStr1.getLength() )
{
// Abort on the first unmatching char
if ( *pStr1 != *pStr2 )
return i;
++pStr1,
++pStr2,
++i;
}
return i;
}
void ScTextWnd::SetTextString( const OUString& rNewString )
2000-09-18 16:07:07 +00:00
{
if ( rNewString != aString )
{
bInputMode = sal_True;
2000-09-18 16:07:07 +00:00
// Position der Aenderung suchen, nur Rest painten
if (!pEditEngine)
{
sal_Bool bPaintAll;
if ( bIsRTL )
bPaintAll = sal_True;
else
{
// test if CTL script type is involved
sal_uInt8 nOldScript = 0;
sal_uInt8 nNewScript = 0;
SfxObjectShell* pObjSh = SfxObjectShell::Current();
if ( pObjSh && pObjSh->ISA(ScDocShell) )
{
// any document can be used (used only for its break iterator)
ScDocument* pDoc = ((ScDocShell*)pObjSh)->GetDocument();
nOldScript = pDoc->GetStringScriptType( aString );
nNewScript = pDoc->GetStringScriptType( rNewString );
}
bPaintAll = ( nOldScript & SCRIPTTYPE_COMPLEX ) || ( nNewScript & SCRIPTTYPE_COMPLEX );
}
2000-09-18 16:07:07 +00:00
if ( bPaintAll )
{
// if CTL is involved, the whole text has to be redrawn
Invalidate();
}
2000-09-18 16:07:07 +00:00
else
{
long nTextSize = 0;
sal_Int32 nDifPos;
if (rNewString.getLength() > aString.getLength())
nDifPos = findFirstNonMatchingChar(rNewString, aString);
else
nDifPos = findFirstNonMatchingChar(aString, rNewString);
long nSize1 = GetTextWidth(aString);
long nSize2 = GetTextWidth(rNewString);
if ( nSize1>0 && nSize2>0 )
nTextSize = std::max( nSize1, nSize2 );
else
nTextSize = GetOutputSize().Width(); // Ueberlauf
Point aLogicStart = PixelToLogic(Point(0,0));
long nStartPos = aLogicStart.X();
long nInvPos = nStartPos;
if (nDifPos)
nInvPos += GetTextWidth(aString,0,nDifPos);
sal_uInt16 nFlags = 0;
if ( nDifPos == aString.getLength() ) // only new characters appended
nFlags = INVALIDATE_NOERASE; // then background is already clear
Invalidate( Rectangle( nInvPos, 0,
nStartPos+nTextSize, GetOutputSize().Height()-1 ),
nFlags );
}
2000-09-18 16:07:07 +00:00
}
else
{
pEditEngine->SetText(rNewString);
}
aString = rNewString;
if (!maAccTextDatas.empty())
maAccTextDatas.back()->TextChanged();
bInputMode = false;
2000-09-18 16:07:07 +00:00
}
}
const OUString& ScTextWnd::GetTextString() const
2000-09-18 16:07:07 +00:00
{
return aString;
}
sal_Bool ScTextWnd::IsInputActive()
2000-09-18 16:07:07 +00:00
{
return HasFocus();
}
EditView* ScTextWnd::GetEditView()
{
return pEditView;
}
void ScTextWnd::MakeDialogEditView()
{
if ( pEditView ) return;
ScFieldEditEngine* pNew;
ScTabViewShell* pViewSh = ScTabViewShell::GetActiveViewShell();
if ( pViewSh )
{
ScDocument* pDoc = pViewSh->GetViewData()->GetDocument();
pNew = new ScFieldEditEngine(pDoc, pDoc->GetEnginePool(), pDoc->GetEditPool());
2000-09-18 16:07:07 +00:00
}
else
pNew = new ScFieldEditEngine(NULL, EditEngine::CreatePool(), NULL, true);
pNew->SetExecuteURL( false );
2000-09-18 16:07:07 +00:00
pEditEngine = pNew;
pEditEngine->SetUpdateMode( false );
pEditEngine->SetWordDelimiters( pEditEngine->GetWordDelimiters() + "=" );
pEditEngine->SetPaperSize( Size( bIsRTL ? USHRT_MAX : THESIZE, 300 ) );
2000-09-18 16:07:07 +00:00
SfxItemSet* pSet = new SfxItemSet( pEditEngine->GetEmptyItemSet() );
pEditEngine->SetFontInfoInItemSet( *pSet, aTextFont );
lcl_ExtendEditFontAttribs( *pSet );
if ( bIsRTL )
lcl_ModifyRTLDefaults( *pSet );
2000-09-18 16:07:07 +00:00
pEditEngine->SetDefaults( pSet );
pEditEngine->SetUpdateMode( sal_True );
2000-09-18 16:07:07 +00:00
pEditView = new EditView( pEditEngine, this );
pEditEngine->InsertView( pEditView, EE_APPEND );
Resize();
if ( bIsRTL )
lcl_ModifyRTLVisArea( pEditView );
if (!maAccTextDatas.empty())
maAccTextDatas.back()->StartEdit();
2000-09-18 16:07:07 +00:00
}
void ScTextWnd::ImplInitSettings()
{
bIsRTL = GetSettings().GetLayoutRTL();
2000-09-18 16:07:07 +00:00
const StyleSettings& rStyleSettings = Application::GetSettings().GetStyleSettings();
Color aBgColor= rStyleSettings.GetWindowColor();
Color aTxtColor= rStyleSettings.GetWindowTextColor();
aTextFont.SetFillColor ( aBgColor );
aTextFont.SetColor (aTxtColor);
SetBackground ( aBgColor );
Invalidate();
}
2002-06-10 13:56:35 +00:00
::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > ScTextWnd::CreateAccessible()
2002-06-10 13:56:35 +00:00
{
return new ScAccessibleEditObject(GetAccessibleParentWindow()->GetAccessible(), NULL, this,
OUString(ScResId(STR_ACC_EDITLINE_NAME)),
OUString(ScResId(STR_ACC_EDITLINE_DESCR)), ScAccessibleEditObject::EditLine);
2002-06-10 13:56:35 +00:00
}
void ScTextWnd::InsertAccessibleTextData( ScAccessibleEditLineTextData& rTextData )
{
OSL_ENSURE( ::std::find( maAccTextDatas.begin(), maAccTextDatas.end(), &rTextData ) == maAccTextDatas.end(),
"ScTextWnd::InsertAccessibleTextData - passed object already registered" );
maAccTextDatas.push_back( &rTextData );
}
void ScTextWnd::RemoveAccessibleTextData( ScAccessibleEditLineTextData& rTextData )
{
AccTextDataVector::iterator aEnd = maAccTextDatas.end();
AccTextDataVector::iterator aIt = ::std::find( maAccTextDatas.begin(), aEnd, &rTextData );
OSL_ENSURE( aIt != aEnd, "ScTextWnd::RemoveAccessibleTextData - passed object not registered" );
if( aIt != aEnd )
maAccTextDatas.erase( aIt );
}
2000-09-18 16:07:07 +00:00
// -----------------------------------------------------------------------
void ScTextWnd::DataChanged( const DataChangedEvent& rDCEvt )
{
if ( (rDCEvt.GetType() == DATACHANGED_SETTINGS) &&
(rDCEvt.GetFlags() & SETTINGS_STYLE) )
{
ImplInitSettings();
Invalidate();
}
else
Window::DataChanged( rDCEvt );
}
void ScTextWnd::TextGrabFocus()
{
GrabFocus();
}
2000-09-18 16:07:07 +00:00
//========================================================================
// Positionsfenster
//========================================================================
ScPosWnd::ScPosWnd( Window* pParent ) :
ComboBox ( pParent, WinBits(WB_HIDE | WB_DROPDOWN) ),
pAccel ( NULL ),
nTipVisible ( 0 ),
bFormulaMode( false )
2000-09-18 16:07:07 +00:00
{
Size aSize( GetTextWidth( OUString("GW99999:GW99999") ),
2000-09-18 16:07:07 +00:00
GetTextHeight() );
aSize.Width() += 25; // ??
aSize.Height() = CalcWindowSizePixel(11); // Funktionen: 10 MRU + "andere..."
SetSizePixel( aSize );
FillRangeNames();
StartListening( *SFX_APP() ); // fuer Navigator-Bereichsnamen-Updates
}
2010-12-11 23:25:30 +01:00
ScPosWnd::~ScPosWnd()
2000-09-18 16:07:07 +00:00
{
EndListening( *SFX_APP() );
HideTip();
2000-09-18 16:07:07 +00:00
delete pAccel;
}
void ScPosWnd::SetFormulaMode( sal_Bool bSet )
2000-09-18 16:07:07 +00:00
{
if ( bSet != bFormulaMode )
{
bFormulaMode = bSet;
if ( bSet )
FillFunctions();
else
FillRangeNames();
HideTip();
2000-09-18 16:07:07 +00:00
}
}
void ScPosWnd::SetPos( const OUString& rPosStr )
2000-09-18 16:07:07 +00:00
{
if ( aPosStr != rPosStr )
{
aPosStr = rPosStr;
SetText(aPosStr);
}
}
namespace {
OUString createLocalRangeName(const OUString& rName, const OUString& rTableName)
{
OUStringBuffer aString (rName);
aString.append(" (");
aString.append(rTableName);
aString.append(")");
return aString.makeStringAndClear();
}
}
2000-09-18 16:07:07 +00:00
void ScPosWnd::FillRangeNames()
{
Clear();
SfxObjectShell* pObjSh = SfxObjectShell::Current();
if ( pObjSh && pObjSh->ISA(ScDocShell) )
{
ScDocument* pDoc = ((ScDocShell*)pObjSh)->GetDocument();
InsertEntry(ScGlobal::GetRscString( STR_MANAGE_NAMES ));
SetSeparatorPos(0);
ScRange aDummy;
std::set<OUString> aSet;
2000-09-18 16:07:07 +00:00
ScRangeName* pRangeNames = pDoc->GetRangeName();
if (!pRangeNames->empty())
2000-09-18 16:07:07 +00:00
{
ScRangeName::const_iterator itrBeg = pRangeNames->begin(), itrEnd = pRangeNames->end();
for (ScRangeName::const_iterator itr = itrBeg; itr != itrEnd; ++itr)
2000-09-18 16:07:07 +00:00
{
if (itr->second->IsValidReference(aDummy))
aSet.insert(itr->second->GetName());
2000-09-18 16:07:07 +00:00
}
}
for (SCTAB i = 0; i < pDoc->GetTableCount(); ++i)
{
ScRangeName* pLocalRangeName = pDoc->GetRangeName(i);
if (pLocalRangeName && !pLocalRangeName->empty())
{
OUString aTableName;
pDoc->GetName(i, aTableName);
for (ScRangeName::const_iterator itr = pLocalRangeName->begin(); itr != pLocalRangeName->end(); ++itr)
{
if (itr->second->IsValidReference(aDummy))
aSet.insert(createLocalRangeName(itr->second->GetName(), aTableName));
}
}
}
if (!aSet.empty())
{
for (std::set<OUString>::iterator itr = aSet.begin();
itr != aSet.end(); ++itr)
2000-09-18 16:07:07 +00:00
{
InsertEntry(*itr);
2000-09-18 16:07:07 +00:00
}
}
}
SetText(aPosStr);
}
void ScPosWnd::FillFunctions()
{
Clear();
OUString aFirstName;
2000-09-18 16:07:07 +00:00
const ScAppOptions& rOpt = SC_MOD()->GetAppOptions();
sal_uInt16 nMRUCount = rOpt.GetLRUFuncListCount();
const sal_uInt16* pMRUList = rOpt.GetLRUFuncList();
2000-09-18 16:07:07 +00:00
if (pMRUList)
{
const ScFunctionList* pFuncList = ScGlobal::GetStarCalcFunctionList();
sal_uLong nListCount = pFuncList->GetCount();
for (sal_uInt16 i=0; i<nMRUCount; i++)
2000-09-18 16:07:07 +00:00
{
sal_uInt16 nId = pMRUList[i];
for (sal_uLong j=0; j<nListCount; j++)
2000-09-18 16:07:07 +00:00
{
const ScFuncDesc* pDesc = pFuncList->GetFunction( j );
if ( pDesc->nFIndex == nId && pDesc->pFuncName )
{
InsertEntry( *pDesc->pFuncName );
if (aFirstName.isEmpty())
2000-09-18 16:07:07 +00:00
aFirstName = *pDesc->pFuncName;
break; // nicht weitersuchen
}
}
}
}
//! Eintrag "Andere..." fuer Funktions-Autopilot wieder aufnehmen,
//! wenn der Funktions-Autopilot mit dem bisher eingegebenen Text arbeiten kann!
// InsertEntry( ScGlobal::GetRscString(STR_FUNCTIONLIST_MORE) );
SetText(aFirstName);
}
void ScPosWnd::Notify( SfxBroadcaster&, const SfxHint& rHint )
2000-09-18 16:07:07 +00:00
{
if ( !bFormulaMode )
{
// muss die Liste der Bereichsnamen updgedated werden?
if ( rHint.ISA(SfxSimpleHint) )
{
sal_uLong nHintId = ((SfxSimpleHint&)rHint).GetId();
2000-09-18 16:07:07 +00:00
if ( nHintId == SC_HINT_AREAS_CHANGED || nHintId == SC_HINT_NAVIGATOR_UPDATEALL)
FillRangeNames();
}
else if ( rHint.ISA(SfxEventHint) )
{
sal_uLong nEventId = ((SfxEventHint&)rHint).GetEventId();
2000-09-18 16:07:07 +00:00
if ( nEventId == SFX_EVENT_ACTIVATEDOC )
FillRangeNames();
}
}
}
void ScPosWnd::HideTip()
{
if ( nTipVisible )
{
Help::HideTip( nTipVisible );
nTipVisible = 0;
}
}
static ScNameInputType lcl_GetInputType( const OUString& rText )
{
ScNameInputType eRet = SC_NAME_INPUT_BAD_NAME; // the more general error
ScTabViewShell* pViewSh = ScTabViewShell::GetActiveViewShell();
if ( pViewSh )
{
ScViewData* pViewData = pViewSh->GetViewData();
ScDocument* pDoc = pViewData->GetDocument();
SCTAB nTab = pViewData->GetTabNo();
CWS-TOOLING: integrate CWS frmdlg 2008-12-18 09:13:09 +0100 oj r265667 : merge from odff05 2008-12-18 07:58:16 +0100 oj r265658 : #i94555# patch from <regina>, ODFF: Add GAMMA, CHISQDIST, CHISQINV. Make the 'cumulative' parameter of GAMMADIST optional. Adapt the domain of CHIDIST to allow negative x. Remove the constraint "degrees of freedom < 1.0E5" from CHIDIST and CHIINV. Plus a mechanism to write the now optional parameter of GAMMADIST to PODF and ODFF if omitted, for backwards compatibility. 2008-12-15 14:06:11 +0100 oj r265490 : CWS-TOOLING: rebase CWS frmdlg to trunk@264807 (milestone: DEV300:m37) 2008-12-15 13:55:28 +0100 oj r265488 : CWS-TOOLING: do not delete this file, it's needed for 'cws rebase -C' CWS: frmdlg New MWS: DEV300 New milestone: m37 2008-12-15 13:55:07 +0100 oj r265487 : CWS-TOOLING: do not delete this file, it's needed for 'cws rebase -C' CWS: frmdlg New MWS: DEV300 New milestone: m37 2008-12-15 13:54:48 +0100 oj r265486 : CWS-TOOLING: do not delete this file, it's needed for 'cws rebase -C' CWS: frmdlg New MWS: DEV300 New milestone: m37 2008-12-15 13:54:36 +0100 oj r265485 : CWS-TOOLING: do not delete this file, it's needed for 'cws rebase -C' CWS: frmdlg New MWS: DEV300 New milestone: m37 2008-12-15 13:54:24 +0100 oj r265484 : CWS-TOOLING: do not delete this file, it's needed for 'cws rebase -C' CWS: frmdlg New MWS: DEV300 New milestone: m37 2008-12-15 13:48:11 +0100 oj r265483 : CWS-TOOLING: do not delete this file, it's needed for 'cws rebase -C' CWS: frmdlg New MWS: DEV300 New milestone: m37 2008-12-15 13:31:12 +0100 oj r265479 : CWS-TOOLING: do not delete this file, it's needed for 'cws rebase -C' CWS: frmdlg New MWS: DEV300 New milestone: m37 2008-12-15 13:13:58 +0100 oj r265477 : CWS-TOOLING: do not delete this file, it's needed for 'cws rebase -C' CWS: frmdlg New MWS: DEV300 New milestone: m37 2008-12-15 13:10:09 +0100 oj r265476 : CWS-TOOLING: do not delete this file, it's needed for 'cws rebase -C' CWS: frmdlg New MWS: DEV300 New milestone: m37 2008-12-15 13:05:11 +0100 oj r265475 : CWS-TOOLING: do not delete this file, it's needed for 'cws rebase -C' CWS: frmdlg New MWS: DEV300 New milestone: m37 2008-12-15 10:47:17 +0100 oj r265467 : CWS-TOOLING: do not delete this file, it's needed for 'cws rebase -C' CWS: frmdlg New MWS: DEV300 New milestone: m37 2008-12-15 10:46:19 +0100 oj r265466 : CWS-TOOLING: do not delete this file, it's needed for 'cws rebase -C' CWS: frmdlg New MWS: DEV300 New milestone: m37 2008-12-15 10:45:47 +0100 oj r265465 : CWS-TOOLING: do not delete this file, it's needed for 'cws rebase -C' CWS: frmdlg New MWS: DEV300 New milestone: m37 2008-12-15 07:35:07 +0100 oj r265458 : add dependency to formula 2008-12-15 07:34:24 +0100 oj r265457 : add dependency to formula 2008-12-12 13:22:00 +0100 msc r265413 : #i97089# 2008-12-12 13:20:25 +0100 msc r265412 : #i97089# 2008-12-12 12:35:12 +0100 msc r265406 : #i97089# 2008-12-12 12:34:16 +0100 msc r265405 : #i97089# 2008-12-12 12:33:05 +0100 msc r265404 : #i97089# 2008-12-12 12:31:11 +0100 msc r265403 : #i97089# 2008-12-08 11:59:10 +0100 oj r264981 : insert RTL_LOG 2008-12-08 11:50:17 +0100 oj r264980 : some small changes 2008-12-05 12:57:57 +0100 oj r264902 : eof changed 2008-12-05 12:56:46 +0100 oj r264901 : eof changed 2008-12-05 12:28:47 +0100 oj r264899 : wrong var used 2008-12-05 10:08:57 +0100 oj r264890 : token order reversed 2008-12-04 13:49:22 +0100 oc r264843 : #i96688: Adapt autotests because of outsourced functionwizard 2008-12-04 13:45:27 +0100 oc r264842 : #i96688: Adapt autotests because of outsourced functionwizard 2008-12-04 13:42:54 +0100 oc r264841 : #i96688: Adapt autotests because of outsourced functionwizard 2008-12-04 13:37:41 +0100 oc r264840 : #i96688: Adapt autotests because of outsourced functionwizard 2008-12-04 13:34:11 +0100 oc r264839 : #i96688: Adapt autotests because of outsourced functionwizard 2008-12-04 12:35:31 +0100 oj r264835 : new help ids for struct and function tabpage 2008-12-04 12:00:35 +0100 oj r264828 : set explicit help id 2008-12-03 14:53:27 +0100 oj r264786 : #i96845# change ref button 2008-12-03 14:51:49 +0100 oj r264785 : #i96845# change ref button 2008-12-03 08:51:57 +0100 oj r264746 : convert dos to unix lineends 2008-12-03 08:50:45 +0100 oj r264745 : convert dos to unix lineends 2008-12-03 08:50:05 +0100 oj r264744 : convert dos to unix lineends 2008-12-02 12:28:33 +0100 oj r264686 : clear help text when new helpid is set 2008-12-02 12:28:02 +0100 oj r264685 : set help id for listbox category 2008-12-02 07:15:56 +0100 oj r264655 : remove define to auto generate help ids 2008-12-01 14:36:43 +0100 oj r264604 : use temp var 2008-12-01 14:18:31 +0100 oj r264601 : moved ScJumpToken to formula 2008-12-01 14:18:11 +0100 oj r264600 : moved ScJumpToken to formula 2008-12-01 14:14:35 +0100 oj r264599 : moved ScJumpToken from sc 2008-12-01 10:48:51 +0100 oj r264589 : change quickhelptext from Shrink to Select 2008-12-01 10:28:41 +0100 oj r264588 : fix opcode data, has to be Any.Void 2008-11-28 11:16:48 +0100 oj r264532 : add help ids 2008-11-28 10:16:56 +0100 oj r264529 : set help id 2008-11-28 10:16:43 +0100 oj r264528 : set help id 2008-11-26 13:55:04 +0100 oj r264381 : #94535# use of optional instead of deleting a string myself and some small changes 2008-11-26 09:53:20 +0100 oj r264346 : compile error with debug/without debug 2008-11-25 07:41:28 +0100 oj r264271 : put static into the method which make use of them 2008-11-24 08:16:07 +0100 oj r264196 : removed not needed classes for op code 2008-11-24 08:13:44 +0100 oj r264195 : removed not needed classes for op code 2008-11-21 14:05:53 +0100 oj r264135 : make GetOpCode inline 2008-11-21 12:35:27 +0100 oj r264124 : hold symbols 2008-11-20 09:27:27 +0100 oj r264028 : merged code from DEV300_m35 which got lost 2008-11-19 20:42:12 +0100 oj r264022 : more changes for formula dialog remove 2008-11-19 20:37:41 +0100 oj r264021 : removed unused var 2008-11-19 20:35:35 +0100 oj r264020 : some more changes at token 2008-11-19 10:59:47 +0100 oj r263967 : deleted 2008-11-19 10:58:24 +0100 oj r263966 : add forui and for res files 2008-11-18 15:27:36 +0100 oj r263777 : unused para removed 2008-11-18 15:23:23 +0100 oj r263775 : add insert button to add field dlg 2008-11-18 13:39:53 +0100 oj r263764 : enable the formula dialog as well for conditional print as for conditional formatting 2008-11-18 12:03:25 +0100 oj r263760 : rename isRef in IsRef 2008-11-17 11:46:16 +0100 oj r263711 : patches for function handling 2008-11-17 11:36:22 +0100 oj r263710 : add new for forui and res file 2008-11-17 09:21:12 +0100 oj r263704 : patches for some resource for libformula 2008-11-15 12:45:30 +0100 oj r263701 : changes for formula editor extraction 2008-11-07 08:23:27 +0100 oj r263416 : merge from DEV300:m35 2008-11-07 08:22:35 +0100 oj r263415 : merge from DEV300:m35 2008-11-07 08:22:16 +0100 oj r263414 : merge from DEV300:m35 2008-11-07 08:21:41 +0100 oj r263413 : merge from DEV300:m35 2008-11-07 08:21:31 +0100 oj r263412 : merge from DEV300:m35 2008-11-07 08:20:38 +0100 oj r263411 : merge from DEV300:m35 2008-11-07 08:20:00 +0100 oj r263410 : merge from DEV300:m35 2008-11-07 08:18:50 +0100 oj r263409 : merge from DEV300:m35 2008-11-07 08:18:19 +0100 oj r263408 : merge from DEV300:m35 2008-11-07 08:10:27 +0100 oj r263407 : merge from DEV300:m35 2008-10-21 07:43:46 +0200 oj r262560 : some compile errors resolved 2008-10-17 16:40:01 +0200 oj r262291 : dep for 1st target 2008-10-07 10:08:39 +0200 oj r262077 : copy 2008-10-07 09:45:31 +0200 oj r262076 : #i94535# 2008-10-07 09:44:26 +0200 oj r262075 : #i94535# new base class 2008-10-07 09:43:21 +0200 oj r262074 : moved to formula 2008-10-07 09:41:51 +0200 oj r262073 : new images 2008-10-07 09:03:01 +0200 oj r262072 : new ids for formula 2008-10-02 08:46:27 +0200 oj r262024 : #i94535# move the formula compiler to formula 2008-10-02 08:08:54 +0200 oj r262023 : #i94535# 2008-10-02 08:06:28 +0200 oj r262022 : #i94535# 2008-10-02 08:05:52 +0200 oj r262021 : #i94535# 2008-10-01 17:15:29 +0200 oj r262014 : #i94535# 2008-10-01 17:12:40 +0200 oj r262013 : new module formula 2008-10-01 17:04:55 +0200 oj r262012 : #i94535# 2008-10-01 16:49:03 +0200 oj r262010 : #i94535# 2008-10-01 16:46:59 +0200 oj r262009 : #i94535#
2009-01-08 10:47:13 +00:00
formula::FormulaGrammar::AddressConvention eConv = pDoc->GetAddressConvention();
// test in same order as in SID_CURRENTCELL execute
ScRange aRange;
ScAddress aAddress;
ScRangeUtil aRangeUtil;
SCTAB nNameTab;
sal_Int32 nNumeric;
if (rText == ScGlobal::GetRscString(STR_MANAGE_NAMES))
eRet = SC_MANAGE_NAMES;
else if ( aRange.Parse( rText, pDoc, eConv ) & SCA_VALID )
eRet = SC_NAME_INPUT_RANGE;
else if ( aAddress.Parse( rText, pDoc, eConv ) & SCA_VALID )
eRet = SC_NAME_INPUT_CELL;
else if ( aRangeUtil.MakeRangeFromName( rText, pDoc, nTab, aRange, RUTL_NAMES, eConv ) )
eRet = SC_NAME_INPUT_NAMEDRANGE;
else if ( aRangeUtil.MakeRangeFromName( rText, pDoc, nTab, aRange, RUTL_DBASE, eConv ) )
eRet = SC_NAME_INPUT_DATABASE;
2011-08-28 01:03:37 +01:00
else if ( comphelper::string::isdigitAsciiString( rText ) &&
( nNumeric = rText.toInt32() ) > 0 && nNumeric <= MAXROW+1 )
eRet = SC_NAME_INPUT_ROW;
else if ( pDoc->GetTable( rText, nNameTab ) )
eRet = SC_NAME_INPUT_SHEET;
else if ( ScRangeData::IsNameValid( rText, pDoc ) ) // nothing found, create new range?
{
if ( pViewData->GetSimpleArea( aRange ) == SC_MARK_SIMPLE )
eRet = SC_NAME_INPUT_DEFINE;
else
eRet = SC_NAME_INPUT_BAD_SELECTION;
}
else
eRet = SC_NAME_INPUT_BAD_NAME;
}
return eRet;
}
void ScPosWnd::Modify()
{
ComboBox::Modify();
HideTip();
if ( !IsTravelSelect() && !bFormulaMode )
{
// determine the action that would be taken for the current input
ScNameInputType eType = lcl_GetInputType( GetText() ); // uses current view
sal_uInt16 nStrId = 0;
switch ( eType )
{
case SC_NAME_INPUT_CELL:
nStrId = STR_NAME_INPUT_CELL;
break;
case SC_NAME_INPUT_RANGE:
case SC_NAME_INPUT_NAMEDRANGE:
nStrId = STR_NAME_INPUT_RANGE; // named range or range reference
break;
case SC_NAME_INPUT_DATABASE:
nStrId = STR_NAME_INPUT_DBRANGE;
break;
case SC_NAME_INPUT_ROW:
nStrId = STR_NAME_INPUT_ROW;
break;
case SC_NAME_INPUT_SHEET:
nStrId = STR_NAME_INPUT_SHEET;
break;
case SC_NAME_INPUT_DEFINE:
nStrId = STR_NAME_INPUT_DEFINE;
break;
default:
// other cases (error): no tip help
break;
}
if ( nStrId )
{
// show the help tip at the text cursor position
Window* pWin = GetSubEdit();
if (!pWin)
pWin = this;
Point aPos;
Cursor* pCur = pWin->GetCursor();
if (pCur)
aPos = pWin->LogicToPixel( pCur->GetPos() );
aPos = pWin->OutputToScreenPixel( aPos );
Rectangle aRect( aPos, aPos );
OUString aText = ScGlobal::GetRscString( nStrId );
sal_uInt16 nAlign = QUICKHELP_LEFT|QUICKHELP_BOTTOM;
nTipVisible = Help::ShowTip(pWin, aRect, aText, nAlign);
}
}
}
2010-12-11 23:25:30 +01:00
void ScPosWnd::Select()
2000-09-18 16:07:07 +00:00
{
ComboBox::Select(); // in VCL gibt GetText() erst danach den ausgewaehlten Eintrag
HideTip();
2000-09-18 16:07:07 +00:00
if (!IsTravelSelect())
DoEnter();
}
void ScPosWnd::DoEnter()
{
OUString aText = GetText();
if ( !aText.isEmpty() )
2000-09-18 16:07:07 +00:00
{
if ( bFormulaMode )
{
ScModule* pScMod = SC_MOD();
if ( aText == ScGlobal::GetRscString(STR_FUNCTIONLIST_MORE) )
{
// Funktions-Autopilot
//! mit dem bisher eingegebenen Text weiterarbeiten !!!
//! new method at ScModule to query if function autopilot is open
SfxViewFrame* pViewFrm = SfxViewFrame::Current();
if ( pViewFrm && !pViewFrm->GetChildWindow( SID_OPENDLG_FUNCTION ) )
2000-09-22 17:57:10 +00:00
pViewFrm->GetDispatcher()->Execute( SID_OPENDLG_FUNCTION,
2000-09-18 16:07:07 +00:00
SFX_CALLMODE_SYNCHRON | SFX_CALLMODE_RECORD );
}
else
{
ScTabViewShell* pViewSh = PTR_CAST( ScTabViewShell, SfxViewShell::Current() );
ScInputHandler* pHdl = pScMod->GetInputHdl( pViewSh );
if (pHdl)
pHdl->InsertFunction( aText );
}
}
else
{
// depending on the input, select something or create a new named range
ScTabViewShell* pViewSh = ScTabViewShell::GetActiveViewShell();
if ( pViewSh )
{
ScViewData* pViewData = pViewSh->GetViewData();
ScDocShell* pDocShell = pViewData->GetDocShell();
ScDocument* pDoc = pDocShell->GetDocument();
ScNameInputType eType = lcl_GetInputType( aText );
if ( eType == SC_NAME_INPUT_BAD_NAME || eType == SC_NAME_INPUT_BAD_SELECTION )
{
sal_uInt16 nId = ( eType == SC_NAME_INPUT_BAD_NAME ) ? STR_NAME_ERROR_NAME : STR_NAME_ERROR_SELECTION;
pViewSh->ErrorMessage( nId );
}
else if ( eType == SC_NAME_INPUT_DEFINE )
{
ScRangeName* pNames = pDoc->GetRangeName();
ScRange aSelection;
if ( pNames && !pNames->findByUpperName(ScGlobal::pCharClass->uppercase(aText)) &&
(pViewData->GetSimpleArea( aSelection ) == SC_MARK_SIMPLE) )
{
ScRangeName aNewRanges( *pNames );
ScAddress aCursor( pViewData->GetCurX(), pViewData->GetCurY(), pViewData->GetTabNo() );
OUString aContent(aSelection.Format(SCR_ABS_3D, pDoc, pDoc->GetAddressConvention()));
ScRangeData* pNew = new ScRangeData( pDoc, aText, aContent, aCursor );
if ( aNewRanges.insert(pNew) )
{
pDocShell->GetDocFunc().ModifyRangeNames( aNewRanges );
pViewSh->UpdateInputHandler(true);
}
}
}
else if (eType == SC_MANAGE_NAMES)
{
sal_uInt16 nId = ScNameDlgWrapper::GetChildWindowId();
SfxViewFrame* pViewFrm = pViewSh->GetViewFrame();
SfxChildWindow* pWnd = pViewFrm->GetChildWindow( nId );
SC_MOD()->SetRefDialog( nId, pWnd ? false : sal_True );
}
else
{
// for all selection types, excecute the SID_CURRENTCELL slot.
if (eType == SC_NAME_INPUT_CELL || eType == SC_NAME_INPUT_RANGE)
{
// Note that SID_CURRENTCELL always expects address to
// be in Calc A1 format. Convert the text.
ScRange aRange(0,0,pViewData->GetTabNo());
aRange.ParseAny(aText, pDoc, pDoc->GetAddressConvention());
aText = aRange.Format(SCR_ABS_3D, pDoc, ::formula::FormulaGrammar::CONV_OOO);
}
SfxStringItem aPosItem( SID_CURRENTCELL, aText );
SfxBoolItem aUnmarkItem( FN_PARAM_1, sal_True ); // remove existing selection
pViewSh->GetViewData()->GetDispatcher().Execute( SID_CURRENTCELL,
SFX_CALLMODE_SYNCHRON | SFX_CALLMODE_RECORD,
&aPosItem, &aUnmarkItem, 0L );
}
}
2000-09-18 16:07:07 +00:00
}
}
else
SetText( aPosStr );
ReleaseFocus_Impl();
}
2010-12-11 23:25:30 +01:00
long ScPosWnd::Notify( NotifyEvent& rNEvt )
2000-09-18 16:07:07 +00:00
{
long nHandled = 0;
if ( rNEvt.GetType() == EVENT_KEYINPUT )
2000-09-18 16:07:07 +00:00
{
const KeyEvent* pKEvt = rNEvt.GetKeyEvent();
switch ( pKEvt->GetKeyCode().GetCode() )
{
case KEY_RETURN:
DoEnter();
nHandled = 1;
break;
case KEY_ESCAPE:
if (nTipVisible)
{
// escape when the tip help is shown: only hide the tip
HideTip();
}
else
{
if (!bFormulaMode)
SetText( aPosStr );
ReleaseFocus_Impl();
}
2000-09-18 16:07:07 +00:00
nHandled = 1;
break;
}
}
if ( !nHandled )
nHandled = ComboBox::Notify( rNEvt );
if ( rNEvt.GetType() == EVENT_LOSEFOCUS )
HideTip();
2000-09-18 16:07:07 +00:00
return nHandled;
}
void ScPosWnd::ReleaseFocus_Impl()
{
HideTip();
2000-09-18 16:07:07 +00:00
SfxViewShell* pCurSh = SfxViewShell::Current();
ScInputHandler* pHdl = SC_MOD()->GetInputHdl( PTR_CAST( ScTabViewShell, pCurSh ) );
if ( pHdl && pHdl->IsTopMode() )
{
// Focus wieder in die Eingabezeile?
ScInputWindow* pInputWin = pHdl->GetInputWindow();
if (pInputWin)
{
pInputWin->TextGrabFocus();
return;
}
}
// Focus auf die aktive View
if ( pCurSh )
{
Window* pShellWnd = pCurSh->GetWindow();
if ( pShellWnd )
pShellWnd->GrabFocus();
}
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */