2010-10-14 08:27:31 +02:00
|
|
|
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
re-base on ALv2 code. Includes (at least) relevant parts of:
linecap: Reintegrating finished LineCap feature
Patch contributed by Regina Henschel
http://svn.apache.org/viewvc?view=revision&revision=1232507
Patches contributed by Sven Jacobi
impress212: #i81610# fixed animation export
http://svn.apache.org/viewvc?view=revision&revision=1167620
impress212: drawinglayer gbuild environment changes
http://svn.apache.org/viewvc?view=revision&revision=1167627
http://svn.apache.org/viewvc?view=revision&revision=1167628
impress212: DffPropSet -> minor code improvements, removing table
http://svn.apache.org/viewvc?view=revision&revision=1167634
impress212: #158494# fixed excel import (text rotation)
http://svn.apache.org/viewvc?view=revision&revision=1167638
Patches contributed by Armin Le Grand
Svg: Reintegrated Svg replacement from /branches/alg/svgreplavement
http://svn.apache.org/viewvc?view=revision&revision=1220836
#118728# changed indentifying definitions for Svg file detection
http://svn.apache.org/viewvc?view=revision&revision=1229961
#118838# LineGeometry creation for complicated cases optimized to
create single Polygons
http://svn.apache.org/viewvc?view=revision&revision=1236232
#119176# corrected file type detection for SVG for svg files
without xml header
http://svn.apache.org/viewvc?view=revision&revision=1309445
#118728# Extended Svg file detection
http://svn.apache.org/viewvc?view=revision&revision=1230531
#118529# solve break converters and convert commands for OLEs and images
http://svn.apache.org/viewvc?view=revision&revision=1186168
svg: added WaE changes from branch svgreplacement to trunc
http://svn.apache.org/viewvc?view=revision&revision=1222974
svg: corrected missing member initialization
http://svn.apache.org/viewvc?view=revision&revision=1226134
fix for #118525#: Using primitives for chart sub-geometry visualisation
http://svn.apache.org/viewvc?view=revision&revision=1226879
#118898# Adapted ImpGraphic::ImplGetBitmap to correctly convert
metafiles to bitmapEx ...
http://svn.apache.org/viewvc?view=revision&revision=1293316
fix for #118525#: removed no longer used variable maOriginalMapMode, one
more exception eliminated
http://svn.apache.org/viewvc?view=revision&revision=1227097
#16758# Added buffering to the VDev usages of the VclProcessor2D derivates...
http://svn.apache.org/viewvc?view=revision&revision=1229521
#116758# Secured VDev buffer device to Vcl deinit
http://svn.apache.org/viewvc?view=revision&revision=1230574
#116758# added remembering allocated VDevs for VDevBuffer to be able to also
delete these when vcl goes down; it should never happen, but You never know
http://svn.apache.org/viewvc?view=revision&revision=1230927
#118730# Changed SvgClipPathNode to use MaskPrimitive2D for primitive
representation instead of TransparencePrimitive2D
http://svn.apache.org/viewvc?view=revision&revision=1231198
#118822# secured 3D geometry creation (slices) by subdividing the 2D
source polyPolygon early
http://svn.apache.org/viewvc?view=revision&revision=1234749
#118829# enhanced Svg gradient quality, obstacles avoided
http://svn.apache.org/viewvc?view=revision&revision=1235361
#118834# Unified usage of TextBreakupHelper as single tooling class
for i18n text primitive breakup
http://svn.apache.org/viewvc?view=revision&revision=1236110
#118853# added square pixel size limit to conversion of
TransparencePrimitive2D to Metafile action
http://svn.apache.org/viewvc?view=revision&revision=1237656
#118824# coreccted mirroring and boundrect when the graphicmanager
is used for bitmap output
http://svn.apache.org/viewvc?view=revision&revision=1240097
#115092# Corrected VclProcessor2D::RenderPolygonStrokePrimitive2D for
various optimization scenarios
http://svn.apache.org/viewvc?view=revision&revision=1241434
#118783# Corrected errors in ID strings, corrected Svg line/fill export,
corrected polygon close state
http://svn.apache.org/viewvc?view=revision&revision=1232006
#118796# corrected null-pointer usage in SVG text exporter
http://svn.apache.org/viewvc?view=revision&revision=1240262
#118729# Use GraphicStreamUrl and GraphicUrl to allow multi image
import with linked graphics, too
http://svn.apache.org/viewvc?view=revision&revision=1229962
#118898# corrected error in GDIMetaFile::GetBoundRect in handling
MetaFloatTransparentAction
http://svn.apache.org/viewvc?view=revision&revision=1293349
#118855# Corrected handling of possibly created empty clipRegions
after PolyPolygon clipping
http://svn.apache.org/viewvc?view=revision&revision=1237725
#115962# Better (but not yet optimal, see comments in task) handling
of MetaFloatTransparentAction in PDF export
http://svn.apache.org/viewvc?view=revision&revision=1241078
IP clearance: #118466# This patch removes librsvg, libcroco, libgsf, ...
http://svn.apache.org/viewvc?view=revision&revision=1200879
118779# Added svg content streaming in/out to ImpGraphic stream operators
http://svn.apache.org/viewvc?view=revision&revision=1231908
linecap: correctons for WaE and mac drawing
http://svn.apache.org/viewvc?view=revision&revision=1232793
svg: uses current system Dpi for Svg replacement image creation
http://svn.apache.org/viewvc?view=revision&revision=1233948
Patches contributed by Mathias Bauer (and others)
gnumake4 work variously
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
http://svn.apache.org/viewvc?view=revision&revision=1394326
Remove duplicate header includes.
cws mba34issues01: #i117720#: convert assertion into warning
http://svn.apache.org/viewvc?view=revision&revision=1172352
118485 - Styles for OLEs are not saved. Submitted by Armin Le Grand.
http://svn.apache.org/viewvc?view=revision&revision=1182166
cws mba34issues01: #i117714#: remove assertion
http://svn.apache.org/viewvc?view=revision&revision=1172357
Patch contributed by Jurgen Schmidt
add some additional checks to ensure proper reading operations
http://svn.apache.org/viewvc?view=revision&revision=1209022
mostly prefer our stream / bounds checking work.
Patches contributed by Herbert Duerr
#i118816# add clarifying comment regarding Font::*Color*() methods
http://svn.apache.org/viewvc?view=revision&revision=1233833
extend macro->string handling for empty strings
http://svn.apache.org/viewvc?view=revision&revision=1175801
avoid magic constants for SALCOLOR_NONE
http://svn.apache.org/viewvc?view=revision&revision=1177543
initialize slant properly in ImplFontMetricData constructor (author=iorsh)
http://svn.apache.org/viewvc?view=revision&revision=1177551
#i118675# make check for extension updates more stable
http://svn.apache.org/viewvc?view=revision&revision=1214797
#a118617# remove VBasicEventListener.dll binary
There are no known users depending on its CLSID
http://svn.apache.org/viewvc?view=revision&revision=1203697
Patches contributed by Ariel Constenla-Haile
Fix build breaker on Linux/gcc
http://svn.apache.org/viewvc?view=revision&revision=1221104
Fix crash when trying to instantiate css.graphic.GraphicRasterizer_RSVG
http://svn.apache.org/viewvc?view=revision&revision=1215559
Patches contributed by Oliver-Rainer Wittmann
sw34bf06: #i117962# - method <SwFlyFrm::IsPaint(..)> - consider
instances of <SwFlyDrawObj>
http://svn.apache.org/viewvc?view=revision&revision=1172120
sw34bf06: #i117783# - Writer's implementation of XPagePrintable -
apply print settings to new printing routines
http://svn.apache.org/viewvc?view=revision&revision=1172115
gnumake4 work variously from Hans-Joachim Lankenau
http://svn.apache.org/viewvc?view=revision&revision=1397315
http://svn.apache.org/viewvc?view=revision&revision=1396797
http://svn.apache.org/viewvc?view=revision&revision=1396782
http://svn.apache.org/viewvc?view=revision&revision=1394707
plus some amount of re-splitting of legacy headers.
Patch contributed by Pavel Janik
WaE: Remove unused variables.
http://svn.apache.org/viewvc?view=revision&revision=1230697
Patches contributed by Takashi Ono
mingwport35: i#117795: MinGW port fix for vcl2gnumake
http://svn.apache.org/viewvc?view=revision&revision=1172091
mingwport35: i#117795: MinGW port fix for vcl2gnumake
http://svn.apache.org/viewvc?view=revision&revision=1172091
Patch contributed by Christian Lippka
impress212: #i98044# re enable Text menu for outline and title shapes
http://svn.apache.org/viewvc?view=revision&revision=1167639
Patch contributed by Andre Fischer
118674: Made category B code optional and disabled by default.
http://svn.apache.org/viewvc?view=revision&revision=1215131
118881: Ignore empty paragraphs after bullets.
http://svn.apache.org/viewvc?view=revision&revision=1296205
Patches contributed by Philipp Lohmann
ooo340fixes: #i117780# use rtl allocator
http://svn.apache.org/viewvc?view=revision&revision=1172087
ooo34gsl02: #i117807# fix an off by one error (index actually
inside the pfb section header)
http://svn.apache.org/viewvc?view=revision&revision=1167576
various cleanups, related compilation fixes, warning cleanups, re-working
of obsolete stl template pieces to use boost instead, changed string
classes, re-adapt KDE about data, about dialog, fixing warnings,
and other fixes & improvements.
Disable svg import / render for about/ branding code-paths for now.
Restore full icon theme set.
Remove OS/2 conditionals and sources.
Remove conflicting gtk/full-screen monitors support.
Retain existing svg rasterizer files - temporarily disabled.
Standardize stringificaiton and fixup dllpostfix issues.
Rename SvgGradientHelper::== to equalTo to avoid overloading issues.
Use the flat GdiPlus API for LineCaps calls.
2012-10-09 12:22:23 +01: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
|
|
|
|
2011-01-24 16:34:14 +01:00
|
|
|
|
2000-09-18 16:07:07 +00:00
|
|
|
#include <tools/debug.hxx>
|
2011-01-24 16:34:14 +01:00
|
|
|
|
|
|
|
#include <svdata.hxx>
|
|
|
|
#include <window.h>
|
|
|
|
|
2007-06-27 19:29:34 +00:00
|
|
|
#include <vcl/event.hxx>
|
2013-01-22 10:20:15 +00:00
|
|
|
#include <vcl/fixed.hxx>
|
2012-03-21 11:26:30 +00:00
|
|
|
#include <vcl/layout.hxx>
|
2007-06-27 19:29:34 +00:00
|
|
|
#include <vcl/svapp.hxx>
|
|
|
|
#include <vcl/tabpage.hxx>
|
|
|
|
#include <vcl/tabctrl.hxx>
|
2009-12-16 19:57:15 +01:00
|
|
|
#include <vcl/tabdlg.hxx>
|
2007-06-27 19:29:34 +00:00
|
|
|
#include <vcl/button.hxx>
|
2000-09-18 16:07:07 +00:00
|
|
|
|
2007-06-27 19:29:34 +00:00
|
|
|
#include <vcl/unohelp.hxx>
|
2000-10-29 16:21:28 +00:00
|
|
|
#include <com/sun/star/i18n/XCharacterClassification.hpp>
|
2000-09-18 16:07:07 +00:00
|
|
|
|
|
|
|
using namespace ::com::sun::star;
|
|
|
|
|
|
|
|
// =======================================================================
|
|
|
|
|
2013-06-18 11:22:11 +09:00
|
|
|
static bool ImplHasIndirectTabParent( Window* pWindow )
|
2009-08-26 13:37:34 +00:00
|
|
|
{
|
|
|
|
// The window has inderect tab parent if it is included in tab hierarchy
|
|
|
|
// of the indirect parent window
|
|
|
|
|
2012-09-25 20:37:53 +01:00
|
|
|
Window* pNonLayoutParent = getNonLayoutParent(pWindow);
|
|
|
|
return ( pNonLayoutParent
|
|
|
|
&& ( pNonLayoutParent->ImplGetWindow()->GetStyle() & WB_CHILDDLGCTRL ) );
|
2009-08-26 13:37:34 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// -----------------------------------------------------------------------
|
|
|
|
|
|
|
|
static Window* ImplGetTopParentOfTabHierarchy( Window* pParent )
|
|
|
|
{
|
|
|
|
// The method allows to find the most close parent containing all the
|
|
|
|
// window from the current tab-hierarchy
|
|
|
|
// The direct parent should be provided as a parameter here
|
|
|
|
|
|
|
|
Window* pResult = pParent;
|
|
|
|
|
|
|
|
if ( pResult )
|
|
|
|
{
|
2012-09-25 20:37:53 +01:00
|
|
|
Window* pNonLayoutParent = getNonLayoutParent(pResult);
|
|
|
|
while ( pNonLayoutParent && ( pResult->ImplGetWindow()->GetStyle() & WB_CHILDDLGCTRL ) )
|
|
|
|
{
|
|
|
|
pResult = pNonLayoutParent;
|
|
|
|
pNonLayoutParent = getNonLayoutParent(pResult);
|
|
|
|
}
|
2009-08-26 13:37:34 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return pResult;
|
|
|
|
}
|
|
|
|
|
|
|
|
// -----------------------------------------------------------------------
|
|
|
|
|
2010-09-29 15:46:40 +08:00
|
|
|
static Window* ImplGetSubChildWindow( Window* pParent, sal_uInt16 n, sal_uInt16& nIndex )
|
2000-09-18 16:07:07 +00:00
|
|
|
{
|
|
|
|
Window* pTabPage = NULL;
|
|
|
|
Window* pFoundWindow = NULL;
|
2009-08-26 13:37:34 +00:00
|
|
|
|
2012-12-12 12:49:58 +00:00
|
|
|
Window* pWindow = firstLogicalChildOfParent(pParent);
|
2000-09-18 16:07:07 +00:00
|
|
|
Window* pNextWindow = pWindow;
|
|
|
|
while ( pWindow )
|
|
|
|
{
|
|
|
|
pWindow = pWindow->ImplGetWindow();
|
|
|
|
|
|
|
|
// Unsichtbare und disablte Fenster werden uebersprungen
|
2012-09-26 21:35:55 +01:00
|
|
|
if ( pTabPage || isVisibleInLayout(pWindow) )
|
2000-09-18 16:07:07 +00:00
|
|
|
{
|
|
|
|
// Wenn das letzte Control ein TabControl war, wird von
|
|
|
|
// diesem die TabPage genommen
|
|
|
|
if ( pTabPage )
|
|
|
|
{
|
|
|
|
pFoundWindow = ImplGetSubChildWindow( pTabPage, n, nIndex );
|
|
|
|
pTabPage = NULL;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
pFoundWindow = pWindow;
|
|
|
|
|
|
|
|
// Bei einem TabControl sich die aktuelle TabPage merken,
|
|
|
|
// damit diese dann genommen wird
|
|
|
|
if ( pWindow->GetType() == WINDOW_TABCONTROL )
|
|
|
|
{
|
|
|
|
TabControl* pTabControl = ((TabControl*)pWindow);
|
|
|
|
// Feststellen, ob TabPage Child vom TabControl ist
|
|
|
|
// und auch noch existiert (deshalb durch Vergleich,
|
|
|
|
// indem alle ChildFenster getestet werden). Denn es
|
|
|
|
// kann sein, das TabPages schon in einem Dialog-Dtor
|
|
|
|
// zerstoert wurden, obwohl das TabControl noch
|
|
|
|
// existiert.
|
|
|
|
TabPage* pTempTabPage = pTabControl->GetTabPage( pTabControl->GetCurPageId() );
|
|
|
|
if ( pTempTabPage )
|
|
|
|
{
|
|
|
|
Window* pTempWindow = pTabControl->GetWindow( WINDOW_FIRSTCHILD );
|
|
|
|
while ( pTempWindow )
|
|
|
|
{
|
|
|
|
if ( pTempWindow->ImplGetWindow() == pTempTabPage )
|
|
|
|
{
|
|
|
|
pTabPage = pTempTabPage;
|
|
|
|
break;
|
|
|
|
}
|
2012-03-21 11:26:30 +00:00
|
|
|
pTempWindow = nextLogicalChildOfParent(pTabControl, pTempWindow);
|
2000-09-18 16:07:07 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2009-08-26 13:37:34 +00:00
|
|
|
else if ( ( pWindow->GetStyle() & WB_DIALOGCONTROL )
|
|
|
|
|| ( pWindow->GetStyle() & WB_CHILDDLGCTRL ) )
|
2000-09-18 16:07:07 +00:00
|
|
|
pFoundWindow = ImplGetSubChildWindow( pWindow, n, nIndex );
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( n == nIndex )
|
|
|
|
return pFoundWindow;
|
|
|
|
nIndex++;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( pTabPage )
|
|
|
|
pWindow = pTabPage;
|
|
|
|
else
|
|
|
|
{
|
2012-03-21 11:26:30 +00:00
|
|
|
pWindow = nextLogicalChildOfParent(pParent, pNextWindow);
|
2000-09-18 16:07:07 +00:00
|
|
|
pNextWindow = pWindow;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
nIndex--;
|
|
|
|
return pFoundWindow;
|
|
|
|
}
|
|
|
|
|
|
|
|
// -----------------------------------------------------------------------
|
|
|
|
|
2010-09-29 15:46:40 +08:00
|
|
|
static Window* ImplGetChildWindow( Window* pParent, sal_uInt16 n, sal_uInt16& nIndex, sal_Bool bTestEnable )
|
2000-09-18 16:07:07 +00:00
|
|
|
{
|
2009-08-26 13:37:34 +00:00
|
|
|
pParent = ImplGetTopParentOfTabHierarchy( pParent );
|
|
|
|
|
2000-09-18 16:07:07 +00:00
|
|
|
nIndex = 0;
|
|
|
|
Window* pWindow = ImplGetSubChildWindow( pParent, n, nIndex );
|
|
|
|
if ( bTestEnable )
|
|
|
|
{
|
2010-09-29 15:46:40 +08:00
|
|
|
sal_uInt16 n2 = nIndex;
|
2012-09-26 21:35:55 +01:00
|
|
|
while ( pWindow && (!isEnabledInLayout(pWindow) || !pWindow->IsInputEnabled()) )
|
2000-09-18 16:07:07 +00:00
|
|
|
{
|
|
|
|
n2 = nIndex+1;
|
|
|
|
nIndex = 0;
|
|
|
|
pWindow = ImplGetSubChildWindow( pParent, n2, nIndex );
|
|
|
|
if ( nIndex < n2 )
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( (nIndex < n2) && n )
|
|
|
|
{
|
|
|
|
do
|
|
|
|
{
|
|
|
|
n--;
|
|
|
|
nIndex = 0;
|
|
|
|
pWindow = ImplGetSubChildWindow( pParent, n, nIndex );
|
|
|
|
}
|
2012-09-26 21:35:55 +01:00
|
|
|
while ( pWindow && n && (!isEnabledInLayout(pWindow) || !pWindow->IsInputEnabled()) );
|
2000-09-18 16:07:07 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
return pWindow;
|
|
|
|
}
|
|
|
|
|
|
|
|
// -----------------------------------------------------------------------
|
|
|
|
|
2010-09-29 15:46:40 +08:00
|
|
|
static Window* ImplGetNextWindow( Window* pParent, sal_uInt16 n, sal_uInt16& nIndex, sal_Bool bTestEnable )
|
2000-09-18 16:07:07 +00:00
|
|
|
{
|
|
|
|
Window* pWindow = ImplGetChildWindow( pParent, n+1, nIndex, bTestEnable );
|
|
|
|
if ( n == nIndex )
|
|
|
|
{
|
|
|
|
n = 0;
|
|
|
|
pWindow = ImplGetChildWindow( pParent, n, nIndex, bTestEnable );
|
|
|
|
}
|
|
|
|
return pWindow;
|
|
|
|
}
|
|
|
|
|
|
|
|
// -----------------------------------------------------------------------
|
|
|
|
|
2010-09-29 15:46:40 +08:00
|
|
|
Window* Window::ImplGetDlgWindow( sal_uInt16 nIndex, sal_uInt16 nType,
|
|
|
|
sal_uInt16 nFormStart, sal_uInt16 nFormEnd,
|
|
|
|
sal_uInt16* pIndex )
|
2000-09-18 16:07:07 +00:00
|
|
|
{
|
|
|
|
DBG_ASSERT( (nIndex >= nFormStart) && (nIndex <= nFormEnd),
|
|
|
|
"Window::ImplGetDlgWindow() - nIndex not in Form" );
|
|
|
|
|
|
|
|
Window* pWindow = NULL;
|
2010-09-29 15:46:40 +08:00
|
|
|
sal_uInt16 i;
|
|
|
|
sal_uInt16 nTemp;
|
|
|
|
sal_uInt16 nStartIndex;
|
2000-09-18 16:07:07 +00:00
|
|
|
|
|
|
|
if ( nType == DLGWINDOW_PREV )
|
|
|
|
{
|
|
|
|
i = nIndex;
|
|
|
|
do
|
|
|
|
{
|
|
|
|
if ( i > nFormStart )
|
|
|
|
i--;
|
|
|
|
else
|
|
|
|
i = nFormEnd;
|
2010-09-29 15:46:40 +08:00
|
|
|
pWindow = ImplGetChildWindow( this, i, nTemp, sal_True );
|
2000-09-18 16:07:07 +00:00
|
|
|
if ( !pWindow )
|
|
|
|
break;
|
|
|
|
if ( (i == nTemp) && (pWindow->GetStyle() & WB_TABSTOP) )
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
while ( i != nIndex );
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
i = nIndex;
|
|
|
|
pWindow = ImplGetChildWindow( this, i, i, (nType == DLGWINDOW_FIRST) );
|
|
|
|
if ( pWindow )
|
|
|
|
{
|
|
|
|
nStartIndex = i;
|
|
|
|
|
|
|
|
if ( nType == DLGWINDOW_NEXT )
|
|
|
|
{
|
|
|
|
if ( i < nFormEnd )
|
|
|
|
{
|
2010-09-29 15:46:40 +08:00
|
|
|
pWindow = ImplGetNextWindow( this, i, i, sal_True );
|
2000-09-18 16:07:07 +00:00
|
|
|
if ( (i > nFormEnd) || (i < nFormStart) )
|
2010-09-29 15:46:40 +08:00
|
|
|
pWindow = ImplGetChildWindow( this, nFormStart, i, sal_True );
|
2000-09-18 16:07:07 +00:00
|
|
|
}
|
|
|
|
else
|
2010-09-29 15:46:40 +08:00
|
|
|
pWindow = ImplGetChildWindow( this, nFormStart, i, sal_True );
|
2000-09-18 16:07:07 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if ( i <= nFormEnd )
|
|
|
|
{
|
|
|
|
// 2ten Index mitfuehren, falls alle Controls disablte
|
2010-09-29 15:46:40 +08:00
|
|
|
sal_uInt16 nStartIndex2 = i;
|
|
|
|
sal_uInt16 nOldIndex = i+1;
|
2000-09-18 16:07:07 +00:00
|
|
|
|
|
|
|
do
|
|
|
|
{
|
|
|
|
if ( pWindow->GetStyle() & WB_TABSTOP )
|
|
|
|
break;
|
2007-05-09 12:22:38 +00:00
|
|
|
if( i == nOldIndex ) // only disabled controls ?
|
|
|
|
{
|
|
|
|
i = nStartIndex2;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
nOldIndex = i;
|
2001-12-06 10:37:06 +00:00
|
|
|
if ( (i > nFormEnd) || (i < nFormStart) )
|
2010-09-29 15:46:40 +08:00
|
|
|
pWindow = ImplGetChildWindow( this, nFormStart, i, sal_True );
|
2000-09-18 16:07:07 +00:00
|
|
|
else
|
2010-09-29 15:46:40 +08:00
|
|
|
pWindow = ImplGetNextWindow( this, i, i, sal_True );
|
2000-09-18 16:07:07 +00:00
|
|
|
}
|
|
|
|
while ( (i != nStartIndex) && (i != nStartIndex2) );
|
|
|
|
|
|
|
|
if ( (i == nStartIndex2) &&
|
2012-09-26 21:35:55 +01:00
|
|
|
(!(pWindow->GetStyle() & WB_TABSTOP) || !isEnabledInLayout(pWindow)) )
|
2000-09-18 16:07:07 +00:00
|
|
|
i = nStartIndex;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( nType == DLGWINDOW_FIRST )
|
|
|
|
{
|
|
|
|
if ( pWindow )
|
|
|
|
{
|
|
|
|
if ( pWindow->GetType() == WINDOW_TABCONTROL )
|
|
|
|
{
|
|
|
|
Window* pNextWindow = ImplGetDlgWindow( i, DLGWINDOW_NEXT );
|
|
|
|
if ( pNextWindow )
|
|
|
|
{
|
|
|
|
if ( pWindow->IsChild( pNextWindow ) )
|
|
|
|
pWindow = pNextWindow;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( !(pWindow->GetStyle() & WB_TABSTOP) )
|
|
|
|
pWindow = NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( pIndex )
|
|
|
|
*pIndex = i;
|
|
|
|
|
|
|
|
return pWindow;
|
|
|
|
}
|
|
|
|
|
|
|
|
// -----------------------------------------------------------------------
|
|
|
|
|
2010-09-29 15:46:40 +08:00
|
|
|
static Window* ImplFindDlgCtrlWindow( Window* pParent, Window* pWindow, sal_uInt16& rIndex,
|
|
|
|
sal_uInt16& rFormStart, sal_uInt16& rFormEnd )
|
2000-09-18 16:07:07 +00:00
|
|
|
{
|
|
|
|
Window* pSWindow;
|
|
|
|
Window* pSecondWindow = NULL;
|
|
|
|
Window* pTempWindow = NULL;
|
2010-09-29 15:46:40 +08:00
|
|
|
sal_uInt16 i;
|
|
|
|
sal_uInt16 nSecond_i = 0;
|
|
|
|
sal_uInt16 nFormStart = 0;
|
|
|
|
sal_uInt16 nSecondFormStart = 0;
|
|
|
|
sal_uInt16 nFormEnd;
|
2000-09-18 16:07:07 +00:00
|
|
|
|
|
|
|
// Focus-Fenster in der Child-Liste suchen
|
2010-09-29 15:46:40 +08:00
|
|
|
Window* pFirstChildWindow = pSWindow = ImplGetChildWindow( pParent, 0, i, sal_False );
|
2009-02-11 10:53:35 +00:00
|
|
|
|
|
|
|
if( pWindow == NULL )
|
|
|
|
pWindow = pSWindow;
|
|
|
|
|
2000-09-18 16:07:07 +00:00
|
|
|
while ( pSWindow )
|
|
|
|
{
|
2009-08-26 13:37:34 +00:00
|
|
|
// the DialogControlStart mark is only accepted for the direct children
|
|
|
|
if ( !ImplHasIndirectTabParent( pSWindow )
|
|
|
|
&& pSWindow->ImplGetWindow()->IsDialogControlStart() )
|
2000-09-18 16:07:07 +00:00
|
|
|
nFormStart = i;
|
|
|
|
|
|
|
|
// SecondWindow wegen zusammengesetzten Controls wie
|
|
|
|
// ComboBoxen und Feldern
|
|
|
|
if ( pSWindow->ImplIsWindowOrChild( pWindow ) )
|
|
|
|
{
|
|
|
|
pSecondWindow = pSWindow;
|
|
|
|
nSecond_i = i;
|
|
|
|
nSecondFormStart = nFormStart;
|
|
|
|
if ( pSWindow == pWindow )
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2010-09-29 15:46:40 +08:00
|
|
|
pSWindow = ImplGetNextWindow( pParent, i, i, sal_False );
|
2000-09-18 16:07:07 +00:00
|
|
|
if ( !i )
|
|
|
|
pSWindow = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( !pSWindow )
|
|
|
|
{
|
|
|
|
// Fenster nicht gefunden, dann koennen wir auch keine
|
|
|
|
// Steuerung uebernehmen
|
|
|
|
if ( !pSecondWindow )
|
|
|
|
return NULL;
|
|
|
|
else
|
|
|
|
{
|
|
|
|
pSWindow = pSecondWindow;
|
|
|
|
i = nSecond_i;
|
|
|
|
nFormStart = nSecondFormStart;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Start-Daten setzen
|
|
|
|
rIndex = i;
|
|
|
|
rFormStart = nFormStart;
|
|
|
|
|
|
|
|
// Formularende suchen
|
|
|
|
nFormEnd = nFormStart;
|
|
|
|
pTempWindow = pSWindow;
|
2009-08-26 13:37:34 +00:00
|
|
|
sal_Int32 nIteration = 0;
|
2000-09-18 16:07:07 +00:00
|
|
|
do
|
|
|
|
{
|
|
|
|
nFormEnd = i;
|
2010-09-29 15:46:40 +08:00
|
|
|
pTempWindow = ImplGetNextWindow( pParent, i, i, sal_False );
|
2009-08-26 13:37:34 +00:00
|
|
|
|
|
|
|
// the DialogControlStart mark is only accepted for the direct children
|
|
|
|
if ( !i
|
|
|
|
|| ( pTempWindow && !ImplHasIndirectTabParent( pTempWindow )
|
|
|
|
&& pTempWindow->ImplGetWindow()->IsDialogControlStart() ) )
|
2000-09-18 16:07:07 +00:00
|
|
|
break;
|
2009-08-26 13:37:34 +00:00
|
|
|
|
|
|
|
if ( pTempWindow && pTempWindow == pFirstChildWindow )
|
|
|
|
{
|
|
|
|
// It is possible to go through the begin of hierarchy once
|
|
|
|
// while looking for DialogControlStart mark.
|
|
|
|
// If it happens second time, it looks like an endless loop,
|
|
|
|
// that should be impossible, but just for the case...
|
|
|
|
nIteration++;
|
|
|
|
if ( nIteration >= 2 )
|
|
|
|
{
|
|
|
|
// this is an unexpected scenario
|
2010-09-29 15:46:40 +08:00
|
|
|
DBG_ASSERT( sal_False, "It seems to be an endless loop!" );
|
2009-08-26 13:37:34 +00:00
|
|
|
rFormStart = 0;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2000-09-18 16:07:07 +00:00
|
|
|
}
|
|
|
|
while ( pTempWindow );
|
|
|
|
rFormEnd = nFormEnd;
|
|
|
|
|
|
|
|
return pSWindow;
|
|
|
|
}
|
|
|
|
|
|
|
|
// -----------------------------------------------------------------------
|
|
|
|
|
2012-10-19 05:34:48 -05:00
|
|
|
static Window* ImplFindAccelWindow( Window* pParent, sal_uInt16& rIndex, sal_Unicode cCharCode,
|
2010-09-29 15:46:40 +08:00
|
|
|
sal_uInt16 nFormStart, sal_uInt16 nFormEnd, sal_Bool bCheckEnable = sal_True )
|
2009-02-11 10:53:35 +00:00
|
|
|
{
|
|
|
|
DBG_ASSERT( (rIndex >= nFormStart) && (rIndex <= nFormEnd),
|
|
|
|
"Window::ImplFindAccelWindow() - rIndex not in Form" );
|
|
|
|
|
2012-10-19 05:34:48 -05:00
|
|
|
sal_Unicode cCompareChar;
|
2010-09-29 15:46:40 +08:00
|
|
|
sal_uInt16 nStart = rIndex;
|
|
|
|
sal_uInt16 i = rIndex;
|
|
|
|
int bSearch = sal_True;
|
2009-02-11 10:53:35 +00:00
|
|
|
Window* pWindow;
|
|
|
|
|
|
|
|
// MT: Where can we keep the CharClass?!
|
|
|
|
static uno::Reference< i18n::XCharacterClassification > xCharClass;
|
|
|
|
if ( !xCharClass.is() )
|
|
|
|
xCharClass = vcl::unohelper::CreateCharacterClassification();
|
|
|
|
|
2012-11-22 12:26:52 +01:00
|
|
|
const ::com::sun::star::lang::Locale& rLocale = Application::GetSettings().GetUILanguageTag().getLocale();
|
2013-04-07 12:06:47 +02:00
|
|
|
cCharCode = xCharClass->toUpper( OUString(cCharCode), 0, 1, rLocale )[0];
|
2009-02-11 10:53:35 +00:00
|
|
|
|
|
|
|
if ( i < nFormEnd )
|
2010-09-29 15:46:40 +08:00
|
|
|
pWindow = ImplGetNextWindow( pParent, i, i, sal_True );
|
2009-02-11 10:53:35 +00:00
|
|
|
else
|
2010-09-29 15:46:40 +08:00
|
|
|
pWindow = ImplGetChildWindow( pParent, nFormStart, i, sal_True );
|
2009-03-05 11:59:11 +00:00
|
|
|
while( bSearch && pWindow )
|
2009-02-11 10:53:35 +00:00
|
|
|
{
|
|
|
|
const XubString aStr = pWindow->GetText();
|
2010-09-29 15:46:40 +08:00
|
|
|
sal_uInt16 nPos = aStr.Search( '~' );
|
2009-02-11 10:53:35 +00:00
|
|
|
while ( nPos != STRING_NOTFOUND )
|
|
|
|
{
|
|
|
|
cCompareChar = aStr.GetChar( nPos+1 );
|
2013-04-07 12:06:47 +02:00
|
|
|
cCompareChar = xCharClass->toUpper( OUString(cCompareChar), 0, 1, rLocale )[0];
|
2009-02-11 10:53:35 +00:00
|
|
|
if ( cCompareChar == cCharCode )
|
|
|
|
{
|
2013-01-22 10:20:15 +00:00
|
|
|
if (pWindow->GetType() == WINDOW_FIXEDTEXT)
|
|
|
|
{
|
|
|
|
FixedText *pFixedText = static_cast<FixedText*>(pWindow);
|
|
|
|
Window *pMnemonicWidget = pFixedText->get_mnemonic_widget();
|
|
|
|
SAL_WARN_IF(isContainerWindow(pFixedText->GetParent()) && !pMnemonicWidget,
|
|
|
|
"vcl.a11y", "label missing mnemonic_widget?");
|
|
|
|
if (pMnemonicWidget)
|
|
|
|
return pMnemonicWidget;
|
|
|
|
}
|
|
|
|
|
2009-02-11 10:53:35 +00:00
|
|
|
// Bei Static-Controls auf das naechste Controlm weiterschalten
|
|
|
|
if ( (pWindow->GetType() == WINDOW_FIXEDTEXT) ||
|
|
|
|
(pWindow->GetType() == WINDOW_FIXEDLINE) ||
|
|
|
|
(pWindow->GetType() == WINDOW_GROUPBOX) )
|
|
|
|
pWindow = pParent->ImplGetDlgWindow( i, DLGWINDOW_NEXT );
|
|
|
|
rIndex = i;
|
|
|
|
return pWindow;
|
|
|
|
}
|
|
|
|
nPos = aStr.Search( '~', nPos+1 );
|
|
|
|
}
|
|
|
|
|
|
|
|
// #i93011# it would have made sense to have this really recursive
|
|
|
|
// right from the start. However this would cause unpredictable side effects now
|
|
|
|
// so instead we have a style bit for some child windows, that want their
|
|
|
|
// children checked for accelerators
|
|
|
|
if( (pWindow->GetStyle() & WB_CHILDDLGCTRL) != 0 )
|
|
|
|
{
|
2010-09-29 15:46:40 +08:00
|
|
|
sal_uInt16 nChildIndex;
|
|
|
|
sal_uInt16 nChildFormStart;
|
|
|
|
sal_uInt16 nChildFormEnd;
|
2009-02-11 10:53:35 +00:00
|
|
|
|
|
|
|
// get form start and end
|
|
|
|
::ImplFindDlgCtrlWindow( pWindow, NULL,
|
|
|
|
nChildIndex, nChildFormStart, nChildFormEnd );
|
|
|
|
Window* pAccelWin = ImplFindAccelWindow( pWindow, nChildIndex, cCharCode,
|
|
|
|
nChildFormStart, nChildFormEnd,
|
|
|
|
bCheckEnable );
|
|
|
|
if( pAccelWin )
|
|
|
|
return pAccelWin;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( i == nStart )
|
|
|
|
break;
|
|
|
|
|
|
|
|
if ( i < nFormEnd )
|
2009-03-05 11:59:11 +00:00
|
|
|
{
|
2009-02-11 10:53:35 +00:00
|
|
|
pWindow = ImplGetNextWindow( pParent, i, i, bCheckEnable );
|
2009-03-05 11:59:11 +00:00
|
|
|
if( ! pWindow )
|
|
|
|
pWindow = ImplGetChildWindow( pParent, nFormStart, i, bCheckEnable );
|
|
|
|
}
|
2009-02-11 10:53:35 +00:00
|
|
|
else
|
|
|
|
pWindow = ImplGetChildWindow( pParent, nFormStart, i, bCheckEnable );
|
|
|
|
}
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
// -----------------------------------------------------------------------
|
|
|
|
|
2010-09-29 15:46:40 +08:00
|
|
|
void Window::ImplControlFocus( sal_uInt16 nFlags )
|
2000-09-18 16:07:07 +00:00
|
|
|
{
|
|
|
|
if ( nFlags & GETFOCUS_MNEMONIC )
|
|
|
|
{
|
|
|
|
if ( GetType() == WINDOW_RADIOBUTTON )
|
|
|
|
{
|
|
|
|
if ( !((RadioButton*)this)->IsChecked() )
|
2010-09-29 15:46:40 +08:00
|
|
|
((RadioButton*)this)->ImplCallClick( sal_True, nFlags );
|
2000-09-18 16:07:07 +00:00
|
|
|
else
|
|
|
|
ImplGrabFocus( nFlags );
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
ImplGrabFocus( nFlags );
|
|
|
|
if ( nFlags & GETFOCUS_UNIQUEMNEMONIC )
|
|
|
|
{
|
|
|
|
if ( GetType() == WINDOW_CHECKBOX )
|
|
|
|
((CheckBox*)this)->ImplCheck();
|
2005-01-13 17:03:07 +00:00
|
|
|
else if ( mpWindowImpl->mbPushButton )
|
2000-09-18 16:07:07 +00:00
|
|
|
{
|
2010-09-29 15:46:40 +08:00
|
|
|
((PushButton*)this)->SetPressed( sal_True );
|
|
|
|
((PushButton*)this)->SetPressed( sal_False );
|
2000-09-18 16:07:07 +00:00
|
|
|
((PushButton*)this)->Click();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if ( GetType() == WINDOW_RADIOBUTTON )
|
|
|
|
{
|
|
|
|
if ( !((RadioButton*)this)->IsChecked() )
|
2010-09-29 15:46:40 +08:00
|
|
|
((RadioButton*)this)->ImplCallClick( sal_True, nFlags );
|
2000-09-18 16:07:07 +00:00
|
|
|
else
|
|
|
|
ImplGrabFocus( nFlags );
|
|
|
|
}
|
|
|
|
else
|
|
|
|
ImplGrabFocus( nFlags );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// -----------------------------------------------------------------------
|
|
|
|
|
2012-11-22 17:14:23 +00:00
|
|
|
namespace
|
|
|
|
{
|
|
|
|
bool isSuitableDestination(Window *pWindow)
|
|
|
|
{
|
|
|
|
return (pWindow && isVisibleInLayout(pWindow) && isEnabledInLayout(pWindow) && pWindow->IsInputEnabled());
|
|
|
|
}
|
|
|
|
|
2013-03-27 16:45:05 +00:00
|
|
|
bool focusNextInGroup(std::vector<RadioButton*>::iterator aStart, std::vector<RadioButton*> &rGroup)
|
2012-11-22 17:14:23 +00:00
|
|
|
{
|
2013-03-27 16:45:05 +00:00
|
|
|
std::vector<RadioButton*>::iterator aI(aStart);
|
2012-11-22 17:14:23 +00:00
|
|
|
|
2013-03-27 16:45:05 +00:00
|
|
|
if (aStart != rGroup.end())
|
|
|
|
++aI;
|
2012-11-22 17:14:23 +00:00
|
|
|
|
2013-03-27 16:45:05 +00:00
|
|
|
for (; aI != rGroup.end(); ++aI)
|
2012-11-22 17:14:23 +00:00
|
|
|
{
|
|
|
|
Window *pWindow = *aI;
|
|
|
|
|
|
|
|
if (isSuitableDestination(pWindow))
|
|
|
|
{
|
|
|
|
pWindow->ImplControlFocus( GETFOCUS_CURSOR | GETFOCUS_FORWARD );
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-03-27 16:45:05 +00:00
|
|
|
for (aI = rGroup.begin(); aI != aStart; ++aI)
|
2012-11-22 17:14:23 +00:00
|
|
|
{
|
|
|
|
Window *pWindow = *aI;
|
|
|
|
|
|
|
|
if (isSuitableDestination(pWindow))
|
|
|
|
{
|
|
|
|
pWindow->ImplControlFocus( GETFOCUS_CURSOR | GETFOCUS_FORWARD );
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool nextInGroup(RadioButton *pSourceWindow, bool bBackward)
|
|
|
|
{
|
|
|
|
std::vector<RadioButton*> aGroup(pSourceWindow->GetRadioButtonGroup(true));
|
|
|
|
|
|
|
|
if (aGroup.size() == 1) //only one button in group
|
|
|
|
return false;
|
|
|
|
|
2013-03-27 16:45:05 +00:00
|
|
|
if (bBackward)
|
|
|
|
std::reverse(aGroup.begin(), aGroup.end());
|
|
|
|
|
2012-11-22 17:14:23 +00:00
|
|
|
std::vector<RadioButton*>::iterator aStart(std::find(aGroup.begin(), aGroup.end(), pSourceWindow));
|
|
|
|
|
|
|
|
assert(aStart != aGroup.end());
|
|
|
|
|
2013-03-27 16:45:05 +00:00
|
|
|
return focusNextInGroup(aStart, aGroup);
|
2012-11-22 17:14:23 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-09-29 15:46:40 +08:00
|
|
|
sal_Bool Window::ImplDlgCtrl( const KeyEvent& rKEvt, sal_Bool bKeyInput )
|
2000-09-18 16:07:07 +00:00
|
|
|
{
|
|
|
|
KeyCode aKeyCode = rKEvt.GetKeyCode();
|
2010-09-29 15:46:40 +08:00
|
|
|
sal_uInt16 nKeyCode = aKeyCode.GetCode();
|
2000-09-18 16:07:07 +00:00
|
|
|
Window* pSWindow;
|
|
|
|
Window* pTempWindow;
|
|
|
|
Window* pButtonWindow;
|
2010-09-29 15:46:40 +08:00
|
|
|
sal_uInt16 i;
|
|
|
|
sal_uInt16 iButton;
|
|
|
|
sal_uInt16 iButtonStart;
|
|
|
|
sal_uInt16 iTemp;
|
|
|
|
sal_uInt16 nIndex;
|
|
|
|
sal_uInt16 nFormStart;
|
|
|
|
sal_uInt16 nFormEnd;
|
|
|
|
sal_uInt16 nDlgCtrlFlags;
|
2000-09-18 16:07:07 +00:00
|
|
|
|
|
|
|
// Ohne Focus-Window koennen wir auch keine Steuerung uebernehmen
|
|
|
|
Window* pFocusWindow = Application::GetFocusWindow();
|
|
|
|
if ( !pFocusWindow || !ImplIsWindowOrChild( pFocusWindow ) )
|
2010-09-29 15:46:40 +08:00
|
|
|
return sal_False;
|
2000-09-18 16:07:07 +00:00
|
|
|
|
|
|
|
// Focus-Fenster in der Child-Liste suchen
|
|
|
|
pSWindow = ::ImplFindDlgCtrlWindow( this, pFocusWindow,
|
|
|
|
nIndex, nFormStart, nFormEnd );
|
|
|
|
if ( !pSWindow )
|
2010-09-29 15:46:40 +08:00
|
|
|
return sal_False;
|
2000-09-18 16:07:07 +00:00
|
|
|
i = nIndex;
|
|
|
|
|
|
|
|
nDlgCtrlFlags = 0;
|
|
|
|
pTempWindow = pSWindow;
|
|
|
|
do
|
|
|
|
{
|
|
|
|
nDlgCtrlFlags |= pTempWindow->GetDialogControlFlags();
|
|
|
|
if ( pTempWindow == this )
|
|
|
|
break;
|
|
|
|
pTempWindow = pTempWindow->ImplGetParent();
|
|
|
|
}
|
|
|
|
while ( pTempWindow );
|
|
|
|
|
|
|
|
pButtonWindow = NULL;
|
|
|
|
|
|
|
|
if ( nKeyCode == KEY_RETURN )
|
|
|
|
{
|
|
|
|
// Wir suchen zuerst nach einem DefPushButton/CancelButton
|
2010-09-29 15:46:40 +08:00
|
|
|
pButtonWindow = ImplGetChildWindow( this, nFormStart, iButton, sal_True );
|
2000-09-18 16:07:07 +00:00
|
|
|
iButtonStart = iButton;
|
|
|
|
while ( pButtonWindow )
|
|
|
|
{
|
|
|
|
if ( (pButtonWindow->GetStyle() & WB_DEFBUTTON) &&
|
2005-01-13 17:03:07 +00:00
|
|
|
pButtonWindow->mpWindowImpl->mbPushButton )
|
2000-09-18 16:07:07 +00:00
|
|
|
break;
|
|
|
|
|
2010-09-29 15:46:40 +08:00
|
|
|
pButtonWindow = ImplGetNextWindow( this, iButton, iButton, sal_True );
|
2000-09-18 16:07:07 +00:00
|
|
|
if ( (iButton <= iButtonStart) || (iButton > nFormEnd) )
|
|
|
|
pButtonWindow = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( bKeyInput && !pButtonWindow && (nDlgCtrlFlags & WINDOW_DLGCTRL_RETURN) )
|
|
|
|
{
|
2010-09-29 15:46:40 +08:00
|
|
|
sal_uInt16 nType;
|
|
|
|
sal_uInt16 nGetFocusFlags = GETFOCUS_TAB;
|
|
|
|
sal_uInt16 nNewIndex;
|
|
|
|
sal_uInt16 iStart;
|
2000-09-18 16:07:07 +00:00
|
|
|
if ( aKeyCode.IsShift() )
|
|
|
|
{
|
|
|
|
nType = DLGWINDOW_PREV;
|
|
|
|
nGetFocusFlags |= GETFOCUS_BACKWARD;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
nType = DLGWINDOW_NEXT;
|
|
|
|
nGetFocusFlags |= GETFOCUS_FORWARD;
|
|
|
|
}
|
|
|
|
iStart = i;
|
|
|
|
pTempWindow = ImplGetDlgWindow( i, nType, nFormStart, nFormEnd, &nNewIndex );
|
|
|
|
while ( pTempWindow && (pTempWindow != pSWindow) )
|
|
|
|
{
|
2005-01-13 17:03:07 +00:00
|
|
|
if ( !pTempWindow->mpWindowImpl->mbPushButton )
|
2000-09-18 16:07:07 +00:00
|
|
|
{
|
|
|
|
// Around-Flag ermitteln
|
|
|
|
if ( nType == DLGWINDOW_PREV )
|
|
|
|
{
|
|
|
|
if ( nNewIndex > iStart )
|
|
|
|
nGetFocusFlags |= GETFOCUS_AROUND;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if ( nNewIndex < iStart )
|
|
|
|
nGetFocusFlags |= GETFOCUS_AROUND;
|
|
|
|
}
|
|
|
|
pTempWindow->ImplControlFocus( nGetFocusFlags );
|
2010-09-29 15:46:40 +08:00
|
|
|
return sal_True;
|
2000-09-18 16:07:07 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
i = nNewIndex;
|
|
|
|
pTempWindow = ImplGetDlgWindow( i, nType, nFormStart, nFormEnd, &nNewIndex );
|
|
|
|
}
|
|
|
|
if ( (i <= iStart) || (i > nFormEnd) )
|
|
|
|
pTempWindow = NULL;
|
|
|
|
}
|
|
|
|
// Wenn es das gleiche Fenster ist, ein Get/LoseFocus
|
|
|
|
// simulieren, falls AROUND ausgewertet wird
|
|
|
|
if ( pTempWindow && (pTempWindow == pSWindow) )
|
|
|
|
{
|
|
|
|
NotifyEvent aNEvt1( EVENT_LOSEFOCUS, pSWindow );
|
|
|
|
if ( !ImplCallPreNotify( aNEvt1 ) )
|
|
|
|
pSWindow->LoseFocus();
|
2005-01-13 17:03:07 +00:00
|
|
|
pSWindow->mpWindowImpl->mnGetFocusFlags = nGetFocusFlags | GETFOCUS_AROUND;
|
2000-09-18 16:07:07 +00:00
|
|
|
NotifyEvent aNEvt2( EVENT_GETFOCUS, pSWindow );
|
|
|
|
if ( !ImplCallPreNotify( aNEvt2 ) )
|
|
|
|
pSWindow->GetFocus();
|
2005-01-13 17:03:07 +00:00
|
|
|
pSWindow->mpWindowImpl->mnGetFocusFlags = 0;
|
2010-09-29 15:46:40 +08:00
|
|
|
return sal_True;
|
2000-09-18 16:07:07 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if ( nKeyCode == KEY_ESCAPE )
|
|
|
|
{
|
|
|
|
// Wir suchen zuerst nach einem DefPushButton/CancelButton
|
2010-09-29 15:46:40 +08:00
|
|
|
pButtonWindow = ImplGetChildWindow( this, nFormStart, iButton, sal_True );
|
2000-09-18 16:07:07 +00:00
|
|
|
iButtonStart = iButton;
|
|
|
|
while ( pButtonWindow )
|
|
|
|
{
|
|
|
|
if ( pButtonWindow->GetType() == WINDOW_CANCELBUTTON )
|
|
|
|
break;
|
|
|
|
|
2010-09-29 15:46:40 +08:00
|
|
|
pButtonWindow = ImplGetNextWindow( this, iButton, iButton, sal_True );
|
2000-09-18 16:07:07 +00:00
|
|
|
if ( (iButton <= iButtonStart) || (iButton > nFormEnd) )
|
|
|
|
pButtonWindow = NULL;
|
|
|
|
}
|
|
|
|
|
2005-01-13 17:03:07 +00:00
|
|
|
if ( bKeyInput && mpWindowImpl->mpDlgCtrlDownWindow )
|
2000-09-18 16:07:07 +00:00
|
|
|
{
|
2005-01-13 17:03:07 +00:00
|
|
|
if ( mpWindowImpl->mpDlgCtrlDownWindow != pButtonWindow )
|
2000-09-18 16:07:07 +00:00
|
|
|
{
|
2010-09-29 15:46:40 +08:00
|
|
|
((PushButton*)mpWindowImpl->mpDlgCtrlDownWindow)->SetPressed( sal_False );
|
2005-01-13 17:03:07 +00:00
|
|
|
mpWindowImpl->mpDlgCtrlDownWindow = NULL;
|
2010-09-29 15:46:40 +08:00
|
|
|
return sal_True;
|
2000-09-18 16:07:07 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if ( bKeyInput )
|
|
|
|
{
|
|
|
|
if ( nKeyCode == KEY_TAB )
|
|
|
|
{
|
|
|
|
// keine Alt-Taste abfangen, wegen Windows
|
|
|
|
if ( !aKeyCode.IsMod2() )
|
|
|
|
{
|
2010-09-29 15:46:40 +08:00
|
|
|
sal_uInt16 nType;
|
|
|
|
sal_uInt16 nGetFocusFlags = GETFOCUS_TAB;
|
|
|
|
sal_uInt16 nNewIndex;
|
2013-06-19 22:30:49 +09:00
|
|
|
bool bFormular = false;
|
2000-09-18 16:07:07 +00:00
|
|
|
|
|
|
|
// Bei Ctrl-Tab erstmal testen, ob zwischen Formularen
|
|
|
|
// gesprungen werden soll
|
|
|
|
if ( aKeyCode.IsMod1() )
|
|
|
|
{
|
|
|
|
// Gruppe suchen
|
|
|
|
Window* pFormularFirstWindow = NULL;
|
|
|
|
Window* pLastFormularFirstWindow = NULL;
|
2010-09-29 15:46:40 +08:00
|
|
|
pTempWindow = ImplGetChildWindow( this, 0, iTemp, sal_False );
|
2000-09-18 16:07:07 +00:00
|
|
|
Window* pPrevFirstFormularFirstWindow = NULL;
|
|
|
|
Window* pFirstFormularFirstWindow = pTempWindow;
|
|
|
|
while ( pTempWindow )
|
|
|
|
{
|
|
|
|
if ( pTempWindow->ImplGetWindow()->IsDialogControlStart() )
|
|
|
|
{
|
|
|
|
if ( iTemp != 0 )
|
2013-06-19 22:30:49 +09:00
|
|
|
bFormular = true;
|
2000-09-18 16:07:07 +00:00
|
|
|
if ( aKeyCode.IsShift() )
|
|
|
|
{
|
|
|
|
if ( iTemp <= nIndex )
|
|
|
|
pFormularFirstWindow = pPrevFirstFormularFirstWindow;
|
|
|
|
pPrevFirstFormularFirstWindow = pTempWindow;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if ( (iTemp > nIndex) && !pFormularFirstWindow )
|
|
|
|
pFormularFirstWindow = pTempWindow;
|
|
|
|
}
|
|
|
|
pLastFormularFirstWindow = pTempWindow;
|
|
|
|
}
|
|
|
|
|
2010-09-29 15:46:40 +08:00
|
|
|
pTempWindow = ImplGetNextWindow( this, iTemp, iTemp, sal_False );
|
2000-09-18 16:07:07 +00:00
|
|
|
if ( !iTemp )
|
|
|
|
pTempWindow = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( bFormular )
|
|
|
|
{
|
|
|
|
if ( !pFormularFirstWindow )
|
|
|
|
{
|
|
|
|
if ( aKeyCode.IsShift() )
|
|
|
|
pFormularFirstWindow = pLastFormularFirstWindow;
|
|
|
|
else
|
|
|
|
pFormularFirstWindow = pFirstFormularFirstWindow;
|
|
|
|
}
|
|
|
|
|
2010-09-29 15:46:40 +08:00
|
|
|
sal_uInt16 nFoundFormStart = 0;
|
|
|
|
sal_uInt16 nFoundFormEnd = 0;
|
|
|
|
sal_uInt16 nTempIndex = 0;
|
2000-09-18 16:07:07 +00:00
|
|
|
if ( ::ImplFindDlgCtrlWindow( this, pFormularFirstWindow, nTempIndex,
|
|
|
|
nFoundFormStart, nFoundFormEnd ) )
|
|
|
|
{
|
|
|
|
nTempIndex = nFoundFormStart;
|
|
|
|
pFormularFirstWindow = ImplGetDlgWindow( nTempIndex, DLGWINDOW_FIRST, nFoundFormStart, nFoundFormEnd );
|
|
|
|
if ( pFormularFirstWindow )
|
|
|
|
{
|
|
|
|
pFormularFirstWindow->ImplControlFocus();
|
2010-09-29 15:46:40 +08:00
|
|
|
return sal_True;
|
2000-09-18 16:07:07 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( !bFormular )
|
|
|
|
{
|
2002-10-14 13:26:35 +00:00
|
|
|
// Only use Ctrl-TAB if it was allowed for the whole
|
|
|
|
// dialog or for the current control (#103667#)
|
|
|
|
if ( !aKeyCode.IsMod1() || (nDlgCtrlFlags & WINDOW_DLGCTRL_MOD1TAB) ||
|
|
|
|
( pSWindow->GetStyle() & WINDOW_DLGCTRL_MOD1TAB) )
|
2000-09-18 16:07:07 +00:00
|
|
|
{
|
|
|
|
if ( aKeyCode.IsShift() )
|
|
|
|
{
|
|
|
|
nType = DLGWINDOW_PREV;
|
|
|
|
nGetFocusFlags |= GETFOCUS_BACKWARD;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
nType = DLGWINDOW_NEXT;
|
|
|
|
nGetFocusFlags |= GETFOCUS_FORWARD;
|
|
|
|
}
|
|
|
|
Window* pWindow = ImplGetDlgWindow( i, nType, nFormStart, nFormEnd, &nNewIndex );
|
|
|
|
// Wenn es das gleiche Fenster ist, ein Get/LoseFocus
|
|
|
|
// simulieren, falls AROUND ausgewertet wird
|
|
|
|
if ( pWindow == pSWindow )
|
|
|
|
{
|
|
|
|
NotifyEvent aNEvt1( EVENT_LOSEFOCUS, pSWindow );
|
|
|
|
if ( !ImplCallPreNotify( aNEvt1 ) )
|
|
|
|
pSWindow->LoseFocus();
|
2005-01-13 17:03:07 +00:00
|
|
|
pSWindow->mpWindowImpl->mnGetFocusFlags = nGetFocusFlags | GETFOCUS_AROUND;
|
2000-09-18 16:07:07 +00:00
|
|
|
NotifyEvent aNEvt2( EVENT_GETFOCUS, pSWindow );
|
|
|
|
if ( !ImplCallPreNotify( aNEvt2 ) )
|
|
|
|
pSWindow->GetFocus();
|
2005-01-13 17:03:07 +00:00
|
|
|
pSWindow->mpWindowImpl->mnGetFocusFlags = 0;
|
2010-09-29 15:46:40 +08:00
|
|
|
return sal_True;
|
2000-09-18 16:07:07 +00:00
|
|
|
}
|
|
|
|
else if ( pWindow )
|
|
|
|
{
|
|
|
|
// Around-Flag ermitteln
|
|
|
|
if ( nType == DLGWINDOW_PREV )
|
|
|
|
{
|
|
|
|
if ( nNewIndex > i )
|
|
|
|
nGetFocusFlags |= GETFOCUS_AROUND;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if ( nNewIndex < i )
|
|
|
|
nGetFocusFlags |= GETFOCUS_AROUND;
|
|
|
|
}
|
|
|
|
pWindow->ImplControlFocus( nGetFocusFlags );
|
2010-09-29 15:46:40 +08:00
|
|
|
return sal_True;
|
2000-09-18 16:07:07 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if ( (nKeyCode == KEY_LEFT) || (nKeyCode == KEY_UP) )
|
|
|
|
{
|
2012-11-22 17:14:23 +00:00
|
|
|
if (pSWindow->GetType() == WINDOW_RADIOBUTTON)
|
|
|
|
return nextInGroup(static_cast<RadioButton*>(pSWindow), true);
|
|
|
|
else
|
2000-09-18 16:07:07 +00:00
|
|
|
{
|
2012-11-22 17:14:23 +00:00
|
|
|
WinBits nStyle = pSWindow->GetStyle();
|
|
|
|
if ( !(nStyle & WB_GROUP) )
|
2000-09-18 16:07:07 +00:00
|
|
|
{
|
2012-11-22 17:14:23 +00:00
|
|
|
Window* pWindow = prevLogicalChildOfParent(this, pSWindow);
|
|
|
|
while ( pWindow )
|
|
|
|
{
|
|
|
|
pWindow = pWindow->ImplGetWindow();
|
2000-09-18 16:07:07 +00:00
|
|
|
|
2012-11-22 17:14:23 +00:00
|
|
|
nStyle = pWindow->GetStyle();
|
2000-09-18 16:07:07 +00:00
|
|
|
|
2012-11-22 17:14:23 +00:00
|
|
|
if ( isVisibleInLayout(pWindow) && isEnabledInLayout(pWindow) && pWindow->IsInputEnabled() )
|
|
|
|
{
|
|
|
|
if ( pWindow != pSWindow )
|
|
|
|
pWindow->ImplControlFocus( GETFOCUS_CURSOR | GETFOCUS_BACKWARD );
|
|
|
|
return sal_True;
|
|
|
|
}
|
2000-09-18 16:07:07 +00:00
|
|
|
|
2012-11-22 17:14:23 +00:00
|
|
|
if ( nStyle & WB_GROUP )
|
|
|
|
break;
|
2000-09-18 16:07:07 +00:00
|
|
|
|
2012-11-22 17:14:23 +00:00
|
|
|
pWindow = prevLogicalChildOfParent(this, pWindow);
|
|
|
|
}
|
2000-09-18 16:07:07 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if ( (nKeyCode == KEY_RIGHT) || (nKeyCode == KEY_DOWN) )
|
|
|
|
{
|
2012-11-22 17:14:23 +00:00
|
|
|
if (pSWindow->GetType() == WINDOW_RADIOBUTTON)
|
|
|
|
return nextInGroup(static_cast<RadioButton*>(pSWindow), false);
|
|
|
|
else
|
2000-09-18 16:07:07 +00:00
|
|
|
{
|
2012-11-22 17:14:23 +00:00
|
|
|
Window* pWindow = nextLogicalChildOfParent(this, pSWindow);
|
|
|
|
while ( pWindow )
|
|
|
|
{
|
|
|
|
pWindow = pWindow->ImplGetWindow();
|
2000-09-18 16:07:07 +00:00
|
|
|
|
2012-11-22 17:14:23 +00:00
|
|
|
WinBits nStyle = pWindow->GetStyle();
|
2000-09-18 16:07:07 +00:00
|
|
|
|
2012-11-22 17:14:23 +00:00
|
|
|
if ( nStyle & WB_GROUP )
|
|
|
|
break;
|
2000-09-18 16:07:07 +00:00
|
|
|
|
2012-11-22 17:14:23 +00:00
|
|
|
if (isSuitableDestination(pWindow))
|
|
|
|
{
|
|
|
|
pWindow->ImplControlFocus( GETFOCUS_CURSOR | GETFOCUS_BACKWARD );
|
|
|
|
return sal_True;
|
|
|
|
}
|
2000-09-18 16:07:07 +00:00
|
|
|
|
2012-11-22 17:14:23 +00:00
|
|
|
pWindow = nextLogicalChildOfParent(this, pWindow);
|
|
|
|
}
|
2000-09-18 16:07:07 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2012-10-19 05:34:48 -05:00
|
|
|
sal_Unicode c = rKEvt.GetCharCode();
|
2000-09-18 16:07:07 +00:00
|
|
|
if ( c )
|
|
|
|
{
|
|
|
|
pSWindow = ::ImplFindAccelWindow( this, i, c, nFormStart, nFormEnd );
|
|
|
|
if ( pSWindow )
|
|
|
|
{
|
2010-09-29 15:46:40 +08:00
|
|
|
sal_uInt16 nGetFocusFlags = GETFOCUS_MNEMONIC;
|
2000-09-18 16:07:07 +00:00
|
|
|
if ( pSWindow == ::ImplFindAccelWindow( this, i, c, nFormStart, nFormEnd ) )
|
|
|
|
nGetFocusFlags |= GETFOCUS_UNIQUEMNEMONIC;
|
|
|
|
pSWindow->ImplControlFocus( nGetFocusFlags );
|
2010-09-29 15:46:40 +08:00
|
|
|
return sal_True;
|
2000-09-18 16:07:07 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-11-22 17:14:23 +00:00
|
|
|
if (isSuitableDestination(pButtonWindow))
|
2000-09-18 16:07:07 +00:00
|
|
|
{
|
|
|
|
if ( bKeyInput )
|
|
|
|
{
|
2005-01-13 17:03:07 +00:00
|
|
|
if ( mpWindowImpl->mpDlgCtrlDownWindow && (mpWindowImpl->mpDlgCtrlDownWindow != pButtonWindow) )
|
2000-09-18 16:07:07 +00:00
|
|
|
{
|
2010-09-29 15:46:40 +08:00
|
|
|
((PushButton*)mpWindowImpl->mpDlgCtrlDownWindow)->SetPressed( sal_False );
|
2005-01-13 17:03:07 +00:00
|
|
|
mpWindowImpl->mpDlgCtrlDownWindow = NULL;
|
2000-09-18 16:07:07 +00:00
|
|
|
}
|
|
|
|
|
2010-09-29 15:46:40 +08:00
|
|
|
((PushButton*)pButtonWindow)->SetPressed( sal_True );
|
2005-01-13 17:03:07 +00:00
|
|
|
mpWindowImpl->mpDlgCtrlDownWindow = pButtonWindow;
|
2000-09-18 16:07:07 +00:00
|
|
|
}
|
2005-01-13 17:03:07 +00:00
|
|
|
else if ( mpWindowImpl->mpDlgCtrlDownWindow == pButtonWindow )
|
2000-09-18 16:07:07 +00:00
|
|
|
{
|
2005-01-13 17:03:07 +00:00
|
|
|
mpWindowImpl->mpDlgCtrlDownWindow = NULL;
|
2010-09-29 15:46:40 +08:00
|
|
|
((PushButton*)pButtonWindow)->SetPressed( sal_False );
|
2000-09-18 16:07:07 +00:00
|
|
|
((PushButton*)pButtonWindow)->Click();
|
|
|
|
}
|
|
|
|
|
2010-09-29 15:46:40 +08:00
|
|
|
return sal_True;
|
2000-09-18 16:07:07 +00:00
|
|
|
}
|
|
|
|
|
2010-09-29 15:46:40 +08:00
|
|
|
return sal_False;
|
2000-09-18 16:07:07 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// -----------------------------------------------------------------------
|
|
|
|
|
2003-05-28 11:32:21 +00:00
|
|
|
// checks if this window has dialog control
|
2010-09-29 15:46:40 +08:00
|
|
|
sal_Bool Window::ImplHasDlgCtrl()
|
2003-05-28 11:32:21 +00:00
|
|
|
{
|
|
|
|
Window* pDlgCtrlParent;
|
|
|
|
|
|
|
|
// lookup window for dialog control
|
|
|
|
pDlgCtrlParent = ImplGetParent();
|
|
|
|
while ( pDlgCtrlParent &&
|
|
|
|
!pDlgCtrlParent->ImplIsOverlapWindow() &&
|
|
|
|
((pDlgCtrlParent->GetStyle() & (WB_DIALOGCONTROL | WB_NODIALOGCONTROL)) != WB_DIALOGCONTROL) )
|
|
|
|
pDlgCtrlParent = pDlgCtrlParent->ImplGetParent();
|
|
|
|
|
|
|
|
if ( !pDlgCtrlParent || ((pDlgCtrlParent->GetStyle() & (WB_DIALOGCONTROL | WB_NODIALOGCONTROL)) != WB_DIALOGCONTROL) )
|
2010-09-29 15:46:40 +08:00
|
|
|
return sal_False;
|
2003-05-28 11:32:21 +00:00
|
|
|
else
|
2010-09-29 15:46:40 +08:00
|
|
|
return sal_True;
|
2003-05-28 11:32:21 +00:00
|
|
|
}
|
|
|
|
|
2000-09-18 16:07:07 +00:00
|
|
|
void Window::ImplDlgCtrlNextWindow()
|
|
|
|
{
|
|
|
|
Window* pDlgCtrlParent;
|
|
|
|
Window* pDlgCtrl;
|
|
|
|
Window* pSWindow;
|
2010-09-29 15:46:40 +08:00
|
|
|
sal_uInt16 nIndex;
|
|
|
|
sal_uInt16 nFormStart;
|
|
|
|
sal_uInt16 nFormEnd;
|
2000-09-18 16:07:07 +00:00
|
|
|
|
2003-05-28 11:32:21 +00:00
|
|
|
// lookup window for dialog control
|
2000-09-18 16:07:07 +00:00
|
|
|
pDlgCtrl = this;
|
|
|
|
pDlgCtrlParent = ImplGetParent();
|
|
|
|
while ( pDlgCtrlParent &&
|
|
|
|
!pDlgCtrlParent->ImplIsOverlapWindow() &&
|
|
|
|
((pDlgCtrlParent->GetStyle() & (WB_DIALOGCONTROL | WB_NODIALOGCONTROL)) != WB_DIALOGCONTROL) )
|
|
|
|
pDlgCtrlParent = pDlgCtrlParent->ImplGetParent();
|
|
|
|
|
2009-02-13 14:09:50 +00:00
|
|
|
if ( !pDlgCtrlParent || (GetStyle() & WB_NODIALOGCONTROL) || ((pDlgCtrlParent->GetStyle() & (WB_DIALOGCONTROL | WB_NODIALOGCONTROL)) != WB_DIALOGCONTROL) )
|
2000-09-18 16:07:07 +00:00
|
|
|
return;
|
|
|
|
|
2003-05-28 11:32:21 +00:00
|
|
|
// lookup window in child list
|
2000-09-18 16:07:07 +00:00
|
|
|
pSWindow = ::ImplFindDlgCtrlWindow( pDlgCtrlParent, pDlgCtrl,
|
|
|
|
nIndex, nFormStart, nFormEnd );
|
|
|
|
if ( !pSWindow )
|
|
|
|
return;
|
|
|
|
|
|
|
|
Window* pWindow = pDlgCtrlParent->ImplGetDlgWindow( nIndex, DLGWINDOW_NEXT, nFormStart, nFormEnd );
|
|
|
|
if ( pWindow && (pWindow != pSWindow) )
|
|
|
|
pWindow->ImplControlFocus();
|
|
|
|
}
|
|
|
|
|
|
|
|
// -----------------------------------------------------------------------
|
|
|
|
|
|
|
|
static void ImplDlgCtrlUpdateDefButton( Window* pParent, Window* pFocusWindow,
|
2010-09-29 15:46:40 +08:00
|
|
|
sal_Bool bGetFocus )
|
2000-09-18 16:07:07 +00:00
|
|
|
{
|
|
|
|
PushButton* pOldDefButton = NULL;
|
|
|
|
PushButton* pNewDefButton = NULL;
|
|
|
|
Window* pSWindow;
|
2010-09-29 15:46:40 +08:00
|
|
|
sal_uInt16 i;
|
|
|
|
sal_uInt16 nFormStart;
|
|
|
|
sal_uInt16 nFormEnd;
|
2000-09-18 16:07:07 +00:00
|
|
|
|
|
|
|
// Formular suchen
|
|
|
|
pSWindow = ::ImplFindDlgCtrlWindow( pParent, pFocusWindow, i, nFormStart, nFormEnd );
|
|
|
|
if ( !pSWindow )
|
|
|
|
{
|
|
|
|
nFormStart = 0;
|
|
|
|
nFormEnd = 0xFFFF;
|
|
|
|
}
|
|
|
|
|
2010-09-29 15:46:40 +08:00
|
|
|
pSWindow = ImplGetChildWindow( pParent, nFormStart, i, sal_False );
|
2000-09-18 16:07:07 +00:00
|
|
|
while ( pSWindow )
|
|
|
|
{
|
|
|
|
if ( pSWindow->ImplIsPushButton() )
|
|
|
|
{
|
|
|
|
PushButton* pPushButton = (PushButton*)pSWindow;
|
|
|
|
if ( pPushButton->ImplIsDefButton() )
|
|
|
|
pOldDefButton = pPushButton;
|
|
|
|
if ( pPushButton->HasChildPathFocus() )
|
|
|
|
pNewDefButton = pPushButton;
|
|
|
|
else if ( !pNewDefButton && (pPushButton->GetStyle() & WB_DEFBUTTON) )
|
|
|
|
pNewDefButton = pPushButton;
|
|
|
|
}
|
|
|
|
|
2010-09-29 15:46:40 +08:00
|
|
|
pSWindow = ImplGetNextWindow( pParent, i, i, sal_False );
|
2000-09-18 16:07:07 +00:00
|
|
|
if ( !i || (i > nFormEnd) )
|
|
|
|
pSWindow = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( !bGetFocus )
|
|
|
|
{
|
2010-09-29 15:46:40 +08:00
|
|
|
sal_uInt16 nDummy;
|
2000-09-18 16:07:07 +00:00
|
|
|
Window* pNewFocusWindow = Application::GetFocusWindow();
|
|
|
|
if ( !pNewFocusWindow || !pParent->ImplIsWindowOrChild( pNewFocusWindow ) )
|
|
|
|
pNewDefButton = NULL;
|
|
|
|
else if ( !::ImplFindDlgCtrlWindow( pParent, pNewFocusWindow, i, nDummy, nDummy ) ||
|
|
|
|
(i < nFormStart) || (i > nFormEnd) )
|
|
|
|
pNewDefButton = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( pOldDefButton != pNewDefButton )
|
|
|
|
{
|
|
|
|
if ( pOldDefButton )
|
2010-09-29 15:46:40 +08:00
|
|
|
pOldDefButton->ImplSetDefButton( sal_False );
|
2000-09-18 16:07:07 +00:00
|
|
|
if ( pNewDefButton )
|
2010-09-29 15:46:40 +08:00
|
|
|
pNewDefButton->ImplSetDefButton( sal_True );
|
2000-09-18 16:07:07 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// -----------------------------------------------------------------------
|
|
|
|
|
2010-09-29 15:46:40 +08:00
|
|
|
void Window::ImplDlgCtrlFocusChanged( Window* pWindow, sal_Bool bGetFocus )
|
2000-09-18 16:07:07 +00:00
|
|
|
{
|
2005-01-13 17:03:07 +00:00
|
|
|
if ( mpWindowImpl->mpDlgCtrlDownWindow && !bGetFocus )
|
2000-09-18 16:07:07 +00:00
|
|
|
{
|
2010-09-29 15:46:40 +08:00
|
|
|
((PushButton*)mpWindowImpl->mpDlgCtrlDownWindow)->SetPressed( sal_False );
|
2005-01-13 17:03:07 +00:00
|
|
|
mpWindowImpl->mpDlgCtrlDownWindow = NULL;
|
2000-09-18 16:07:07 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
ImplDlgCtrlUpdateDefButton( this, pWindow, bGetFocus );
|
|
|
|
}
|
|
|
|
|
|
|
|
// -----------------------------------------------------------------------
|
|
|
|
|
|
|
|
Window* Window::ImplFindDlgCtrlWindow( Window* pWindow )
|
|
|
|
{
|
2010-09-29 15:46:40 +08:00
|
|
|
sal_uInt16 nIndex;
|
|
|
|
sal_uInt16 nFormStart;
|
|
|
|
sal_uInt16 nFormEnd;
|
2000-09-18 16:07:07 +00:00
|
|
|
|
|
|
|
// Focus-Fenster in der Child-Liste suchen und zurueckgeben
|
|
|
|
return ::ImplFindDlgCtrlWindow( this, pWindow, nIndex, nFormStart, nFormEnd );
|
|
|
|
}
|
2002-04-17 17:06:16 +00:00
|
|
|
|
|
|
|
|
2002-11-06 10:52:49 +00:00
|
|
|
// -----------------------------------------------------------------------
|
|
|
|
|
2006-06-19 18:36:28 +00:00
|
|
|
Window* Window::GetParentLabelFor( const Window* ) const
|
2002-11-06 10:52:49 +00:00
|
|
|
{
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
// -----------------------------------------------------------------------
|
|
|
|
|
2006-06-19 18:36:28 +00:00
|
|
|
Window* Window::GetParentLabeledBy( const Window* ) const
|
2002-11-06 10:52:49 +00:00
|
|
|
{
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2002-04-17 17:06:16 +00:00
|
|
|
// -----------------------------------------------------------------------
|
|
|
|
|
|
|
|
static sal_Unicode getAccel( const String& rStr )
|
|
|
|
{
|
|
|
|
sal_Unicode nChar = 0;
|
2010-09-29 15:46:40 +08:00
|
|
|
sal_uInt16 nPos = 0;
|
2002-04-17 17:06:16 +00:00
|
|
|
do
|
|
|
|
{
|
|
|
|
nPos = rStr.Search( '~', nPos );
|
|
|
|
if( nPos != STRING_NOTFOUND && nPos < rStr.Len() )
|
|
|
|
nChar = rStr.GetChar( ++nPos );
|
|
|
|
else
|
|
|
|
nChar = 0;
|
|
|
|
} while( nChar == '~' );
|
|
|
|
return nChar;
|
|
|
|
}
|
|
|
|
|
2010-09-22 11:43:32 +02:00
|
|
|
static Window* ImplGetLabelFor( Window* pFrameWindow, WindowType nMyType, Window* pLabel, sal_Unicode nAccel )
|
2002-04-17 17:06:16 +00:00
|
|
|
{
|
|
|
|
Window* pWindow = NULL;
|
2002-11-06 10:52:49 +00:00
|
|
|
|
2010-02-19 10:44:47 +01:00
|
|
|
if( nMyType == WINDOW_FIXEDTEXT ||
|
|
|
|
nMyType == WINDOW_FIXEDLINE ||
|
|
|
|
nMyType == WINDOW_GROUPBOX )
|
2002-04-17 17:06:16 +00:00
|
|
|
{
|
2010-02-19 10:44:47 +01:00
|
|
|
// #i100833# MT 2010/02: Group box and fixed lines can also lable a fixed text.
|
|
|
|
// See tools/options/print for example.
|
2013-06-19 22:30:49 +09:00
|
|
|
bool bThisIsAGroupControl = (nMyType == WINDOW_GROUPBOX) || (nMyType == WINDOW_FIXEDLINE);
|
2002-07-22 14:29:44 +00:00
|
|
|
// get index, form start and form end
|
2010-09-29 15:46:40 +08:00
|
|
|
sal_uInt16 nIndex=0, nFormStart=0, nFormEnd=0;
|
2013-02-17 19:50:41 +01:00
|
|
|
Window* pSWindow = ::ImplFindDlgCtrlWindow( pFrameWindow,
|
2010-09-22 11:43:32 +02:00
|
|
|
pLabel,
|
2002-07-22 14:29:44 +00:00
|
|
|
nIndex,
|
|
|
|
nFormStart,
|
|
|
|
nFormEnd );
|
2002-04-17 17:06:16 +00:00
|
|
|
if( nAccel )
|
|
|
|
{
|
|
|
|
// find the accelerated window
|
2002-11-06 10:52:49 +00:00
|
|
|
pWindow = ::ImplFindAccelWindow( pFrameWindow,
|
2002-04-17 17:06:16 +00:00
|
|
|
nIndex,
|
|
|
|
nAccel,
|
|
|
|
nFormStart,
|
2002-06-11 12:52:15 +00:00
|
|
|
nFormEnd,
|
2010-09-29 15:46:40 +08:00
|
|
|
sal_False );
|
2002-04-17 17:06:16 +00:00
|
|
|
}
|
2002-07-22 14:29:44 +00:00
|
|
|
else
|
|
|
|
{
|
|
|
|
// find the next control; if that is a fixed text
|
|
|
|
// fixed line or group box, then return NULL
|
|
|
|
while( nIndex < nFormEnd )
|
|
|
|
{
|
|
|
|
nIndex++;
|
2002-11-06 10:52:49 +00:00
|
|
|
pSWindow = ::ImplGetChildWindow( pFrameWindow,
|
2002-07-22 14:29:44 +00:00
|
|
|
nIndex,
|
|
|
|
nIndex,
|
2010-09-29 15:46:40 +08:00
|
|
|
sal_False );
|
2012-09-26 21:35:55 +01:00
|
|
|
if( pSWindow && isVisibleInLayout(pSWindow) && ! (pSWindow->GetStyle() & WB_NOLABEL) )
|
2002-07-22 14:29:44 +00:00
|
|
|
{
|
2010-02-19 10:44:47 +01:00
|
|
|
WindowType nType = pSWindow->GetType();
|
|
|
|
if( nType != WINDOW_FIXEDTEXT &&
|
|
|
|
nType != WINDOW_FIXEDLINE &&
|
|
|
|
nType != WINDOW_GROUPBOX )
|
|
|
|
{
|
|
|
|
pWindow = pSWindow;
|
|
|
|
}
|
|
|
|
else if( bThisIsAGroupControl && ( nType == WINDOW_FIXEDTEXT ) )
|
2002-07-22 14:29:44 +00:00
|
|
|
{
|
|
|
|
pWindow = pSWindow;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2002-04-17 17:06:16 +00:00
|
|
|
}
|
2002-07-22 14:29:44 +00:00
|
|
|
|
2002-04-17 17:06:16 +00:00
|
|
|
return pWindow;
|
|
|
|
}
|
|
|
|
|
2013-01-22 10:20:15 +00:00
|
|
|
Window* Window::getLegacyNonLayoutAccessibleRelationLabelFor() const
|
2002-04-17 17:06:16 +00:00
|
|
|
{
|
|
|
|
Window* pWindow = NULL;
|
2002-11-06 10:52:49 +00:00
|
|
|
Window* pFrameWindow = ImplGetFrameWindow();
|
2002-04-17 17:06:16 +00:00
|
|
|
|
2010-09-22 11:43:32 +02:00
|
|
|
WinBits nFrameStyle = pFrameWindow->GetStyle();
|
|
|
|
if( ! ( nFrameStyle & WB_DIALOGCONTROL )
|
|
|
|
|| ( nFrameStyle & WB_NODIALOGCONTROL )
|
|
|
|
)
|
|
|
|
return NULL;
|
|
|
|
|
2005-01-13 17:03:07 +00:00
|
|
|
if ( mpWindowImpl->mpRealParent )
|
2010-09-22 11:43:32 +02:00
|
|
|
pWindow = mpWindowImpl->mpRealParent->GetParentLabelFor( this );
|
2002-11-25 09:06:59 +00:00
|
|
|
|
2002-11-06 10:52:49 +00:00
|
|
|
if( pWindow )
|
|
|
|
return pWindow;
|
|
|
|
|
2010-09-22 11:43:32 +02:00
|
|
|
sal_Unicode nAccel = getAccel( GetText() );
|
2006-05-05 08:01:03 +00:00
|
|
|
|
2010-09-22 11:43:32 +02:00
|
|
|
pWindow = ImplGetLabelFor( pFrameWindow, GetType(), const_cast<Window*>(this), nAccel );
|
|
|
|
if( ! pWindow && mpWindowImpl->mpRealParent )
|
|
|
|
pWindow = ImplGetLabelFor( mpWindowImpl->mpRealParent, GetType(), const_cast<Window*>(this), nAccel );
|
|
|
|
return pWindow;
|
|
|
|
}
|
|
|
|
|
|
|
|
// -----------------------------------------------------------------------
|
|
|
|
|
|
|
|
static Window* ImplGetLabeledBy( Window* pFrameWindow, WindowType nMyType, Window* pLabeled )
|
|
|
|
{
|
|
|
|
Window* pWindow = NULL;
|
2010-02-19 10:44:47 +01:00
|
|
|
if ( (nMyType != WINDOW_GROUPBOX) && (nMyType != WINDOW_FIXEDLINE) )
|
2002-04-17 17:06:16 +00:00
|
|
|
{
|
2002-07-22 14:29:44 +00:00
|
|
|
// search for a control that labels this window
|
|
|
|
// a label is considered the last fixed text, fixed line or group box
|
|
|
|
// that comes before this control; with the exception of push buttons
|
|
|
|
// which are labeled only if the fixed text, fixed line or group box
|
|
|
|
// is directly before the control
|
|
|
|
|
|
|
|
// get form start and form end and index of this control
|
2010-09-29 15:46:40 +08:00
|
|
|
sal_uInt16 nIndex, nFormStart, nFormEnd;
|
2002-11-06 10:52:49 +00:00
|
|
|
Window* pSWindow = ::ImplFindDlgCtrlWindow( pFrameWindow,
|
2010-09-22 11:43:32 +02:00
|
|
|
pLabeled,
|
2002-07-22 14:29:44 +00:00
|
|
|
nIndex,
|
|
|
|
nFormStart,
|
|
|
|
nFormEnd );
|
|
|
|
if( pSWindow && nIndex != nFormStart )
|
2002-04-17 17:06:16 +00:00
|
|
|
{
|
2010-09-22 11:43:32 +02:00
|
|
|
if( nMyType == WINDOW_PUSHBUTTON ||
|
|
|
|
nMyType == WINDOW_HELPBUTTON ||
|
|
|
|
nMyType == WINDOW_OKBUTTON ||
|
|
|
|
nMyType == WINDOW_CANCELBUTTON )
|
2002-07-22 14:29:44 +00:00
|
|
|
{
|
|
|
|
nFormStart = nIndex-1;
|
|
|
|
}
|
2010-09-29 15:46:40 +08:00
|
|
|
for( sal_uInt16 nSearchIndex = nIndex-1; nSearchIndex >= nFormStart; nSearchIndex-- )
|
2002-04-17 17:06:16 +00:00
|
|
|
{
|
2010-09-29 15:46:40 +08:00
|
|
|
sal_uInt16 nFoundIndex = 0;
|
2002-11-06 10:52:49 +00:00
|
|
|
pSWindow = ::ImplGetChildWindow( pFrameWindow,
|
2002-07-22 14:29:44 +00:00
|
|
|
nSearchIndex,
|
2002-07-31 07:40:21 +00:00
|
|
|
nFoundIndex,
|
2010-09-29 15:46:40 +08:00
|
|
|
sal_False );
|
2012-09-26 21:35:55 +01:00
|
|
|
if( pSWindow && isVisibleInLayout(pSWindow) && !(pSWindow->GetStyle() & WB_NOLABEL) )
|
2002-04-17 17:06:16 +00:00
|
|
|
{
|
2010-02-19 10:44:47 +01:00
|
|
|
WindowType nType = pSWindow->GetType();
|
|
|
|
if ( ( nType == WINDOW_FIXEDTEXT ||
|
|
|
|
nType == WINDOW_FIXEDLINE ||
|
|
|
|
nType == WINDOW_GROUPBOX ) )
|
|
|
|
{
|
|
|
|
// a fixed text can't be labeld by a fixed text.
|
|
|
|
if ( ( nMyType != WINDOW_FIXEDTEXT ) || ( nType != WINDOW_FIXEDTEXT ) )
|
|
|
|
pWindow = pSWindow;
|
|
|
|
break;
|
|
|
|
}
|
2002-04-17 17:06:16 +00:00
|
|
|
}
|
2002-07-31 07:40:21 +00:00
|
|
|
if( nFoundIndex > nSearchIndex || nSearchIndex == 0 )
|
|
|
|
break;
|
2002-04-17 17:06:16 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return pWindow;
|
|
|
|
}
|
|
|
|
|
2013-01-22 10:20:15 +00:00
|
|
|
Window* Window::getLegacyNonLayoutAccessibleRelationLabeledBy() const
|
2010-09-22 11:43:32 +02:00
|
|
|
{
|
|
|
|
Window* pWindow = NULL;
|
|
|
|
Window* pFrameWindow = ImplGetFrameWindow();
|
|
|
|
|
|
|
|
if ( mpWindowImpl->mpRealParent )
|
|
|
|
{
|
|
|
|
pWindow = mpWindowImpl->mpRealParent->GetParentLabeledBy( this );
|
|
|
|
|
|
|
|
if( pWindow )
|
|
|
|
return pWindow;
|
|
|
|
}
|
|
|
|
|
|
|
|
// #i62723#, #104191# checkboxes and radiobuttons are not supposed to have labels
|
|
|
|
if( GetType() == WINDOW_CHECKBOX || GetType() == WINDOW_RADIOBUTTON )
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
// if( ! ( GetType() == WINDOW_FIXEDTEXT ||
|
|
|
|
// GetType() == WINDOW_FIXEDLINE ||
|
|
|
|
// GetType() == WINDOW_GROUPBOX ) )
|
|
|
|
// #i100833# MT 2010/02: Group box and fixed lines can also lable a fixed text.
|
|
|
|
// See tools/options/print for example.
|
|
|
|
|
|
|
|
pWindow = ImplGetLabeledBy( pFrameWindow, GetType(), const_cast<Window*>(this) );
|
|
|
|
if( ! pWindow && mpWindowImpl->mpRealParent )
|
|
|
|
pWindow = ImplGetLabeledBy( mpWindowImpl->mpRealParent, GetType(), const_cast<Window*>(this) );
|
|
|
|
|
|
|
|
return pWindow;
|
|
|
|
}
|
|
|
|
|
2013-01-22 10:20:15 +00:00
|
|
|
Window* Window::getLegacyNonLayoutAccessibleRelationMemberOf() const
|
2013-01-21 10:04:47 +00:00
|
|
|
{
|
|
|
|
Window* pWindow = NULL;
|
|
|
|
Window* pFrameWindow = GetParent();
|
|
|
|
if ( !pFrameWindow )
|
|
|
|
{
|
|
|
|
pFrameWindow = ImplGetFrameWindow();
|
|
|
|
}
|
|
|
|
// if( ! ( GetType() == WINDOW_FIXEDTEXT ||
|
|
|
|
if( !( GetType() == WINDOW_FIXEDLINE ||
|
|
|
|
GetType() == WINDOW_GROUPBOX ) )
|
|
|
|
{
|
|
|
|
// search for a control that makes member of this window
|
|
|
|
// it is considered the last fixed line or group box
|
|
|
|
// that comes before this control; with the exception of push buttons
|
|
|
|
// which are labeled only if the fixed line or group box
|
|
|
|
// is directly before the control
|
|
|
|
// get form start and form end and index of this control
|
|
|
|
sal_uInt16 nIndex, nFormStart, nFormEnd;
|
|
|
|
Window* pSWindow = ::ImplFindDlgCtrlWindow( pFrameWindow,
|
|
|
|
const_cast<Window*>(this),
|
|
|
|
nIndex,
|
|
|
|
nFormStart,
|
|
|
|
nFormEnd );
|
|
|
|
if( pSWindow && nIndex != nFormStart )
|
|
|
|
{
|
|
|
|
if( GetType() == WINDOW_PUSHBUTTON ||
|
|
|
|
GetType() == WINDOW_HELPBUTTON ||
|
|
|
|
GetType() == WINDOW_OKBUTTON ||
|
|
|
|
GetType() == WINDOW_CANCELBUTTON )
|
|
|
|
{
|
|
|
|
nFormStart = nIndex-1;
|
|
|
|
}
|
|
|
|
for( sal_uInt16 nSearchIndex = nIndex-1; nSearchIndex >= nFormStart; nSearchIndex-- )
|
|
|
|
{
|
|
|
|
sal_uInt16 nFoundIndex = 0;
|
|
|
|
pSWindow = ::ImplGetChildWindow( pFrameWindow,
|
|
|
|
nSearchIndex,
|
|
|
|
nFoundIndex,
|
|
|
|
sal_False );
|
|
|
|
if( pSWindow && pSWindow->IsVisible() &&
|
|
|
|
( pSWindow->GetType() == WINDOW_FIXEDLINE ||
|
|
|
|
pSWindow->GetType() == WINDOW_GROUPBOX ) )
|
|
|
|
{
|
|
|
|
pWindow = pSWindow;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
if( nFoundIndex > nSearchIndex || nSearchIndex == 0 )
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return pWindow;
|
|
|
|
}
|
|
|
|
|
2002-04-17 17:06:16 +00:00
|
|
|
// -----------------------------------------------------------------------
|
|
|
|
|
|
|
|
KeyEvent Window::GetActivationKey() const
|
|
|
|
{
|
|
|
|
KeyEvent aKeyEvent;
|
|
|
|
|
2002-07-22 14:29:44 +00:00
|
|
|
sal_Unicode nAccel = getAccel( GetText() );
|
|
|
|
if( ! nAccel )
|
|
|
|
{
|
2011-01-19 18:15:46 +01:00
|
|
|
Window* pWindow = GetAccessibleRelationLabeledBy();
|
2002-07-22 14:29:44 +00:00
|
|
|
if( pWindow )
|
|
|
|
nAccel = getAccel( pWindow->GetText() );
|
|
|
|
}
|
|
|
|
if( nAccel )
|
2002-04-17 17:06:16 +00:00
|
|
|
{
|
2010-09-29 15:46:40 +08:00
|
|
|
sal_uInt16 nCode = 0;
|
2002-04-17 17:06:16 +00:00
|
|
|
if( nAccel >= 'a' && nAccel <= 'z' )
|
|
|
|
nCode = KEY_A + (nAccel-'a');
|
|
|
|
else if( nAccel >= 'A' && nAccel <= 'Z' )
|
|
|
|
nCode = KEY_A + (nAccel-'A');
|
|
|
|
else if( nAccel >= '0' && nAccel <= '9' )
|
|
|
|
nCode = KEY_0 + (nAccel-'0');
|
2011-01-19 18:15:46 +01:00
|
|
|
else if( nAccel == '.' )
|
|
|
|
nCode = KEY_POINT;
|
|
|
|
else if( nAccel == '-' )
|
|
|
|
nCode = KEY_SUBTRACT;
|
2010-09-29 15:46:40 +08:00
|
|
|
KeyCode aKeyCode( nCode, sal_False, sal_False, sal_True, sal_False );
|
2002-04-17 17:06:16 +00:00
|
|
|
aKeyEvent = KeyEvent( nAccel, aKeyCode );
|
|
|
|
}
|
|
|
|
return aKeyEvent;
|
|
|
|
}
|
2010-10-14 08:27:31 +02:00
|
|
|
|
|
|
|
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|