mirror of
https://git.lyx.org/repos/lyx.git
synced 2024-11-21 17:51:03 +00:00
Merge branch '2.3.2-staging' into 2.3.x
This commit is contained in:
commit
bcb002039b
2
3rdparty/hunspell/Makefile.am
vendored
2
3rdparty/hunspell/Makefile.am
vendored
@ -16,7 +16,7 @@ EXTRA_DIST = \
|
||||
1.6.2/src/hunspell/hunvisapi.h.in \
|
||||
1.6.2/src/hunspell/utf_info.cxx
|
||||
|
||||
AM_CPPFLAGS += -DHUNSPELL_STATIC
|
||||
AM_CPPFLAGS += -DHUNSPELL_STATIC @STDLIB_DEBUG@
|
||||
|
||||
liblyxhunspell_a_SOURCES = \
|
||||
1.6.2/src/hunspell/affentry.cxx \
|
||||
|
3
INSTALL
3
INSTALL
@ -228,6 +228,9 @@ The following options allow you to tweak the generated code more precisely (see
|
||||
--without-included-boost is specified). You may have to use
|
||||
--disable-stdlib-debug when linking development versions against
|
||||
your system's boost library.
|
||||
The same problem applies to hunspell (as of hunspell 1.5). So either
|
||||
compile --with-included-hunspell or --disable-stdlib-debug when
|
||||
linking development versions against your system's hunspell library.
|
||||
|
||||
o --enable-monolithic-build[=boost,client,insets,mathed,core,tex2lyx,frontend-qt4]
|
||||
that enables monolithic build of the given parts of the source
|
||||
|
@ -420,6 +420,7 @@ if test x$GXX = xyes; then
|
||||
lyx_flags="$lyx_flags stdlib-debug"
|
||||
AC_DEFINE(_GLIBCXX_DEBUG, 1, [libstdc++ debug mode])
|
||||
AC_DEFINE(_GLIBCXX_DEBUG_PEDANTIC, 1, [libstdc++ pedantic debug mode])
|
||||
AC_SUBST(STDLIB_DEBUG, "-D_GLIBCXX_DEBUG -D_GLIBCXX_DEBUG_PEDANTIC")
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
|
@ -60,6 +60,24 @@ AC_DEFUN([CHECK_WITH_ENCHANT],
|
||||
fi
|
||||
])
|
||||
|
||||
AC_DEFUN([LYX_HAVE_HUNSPELL_CXXABI],
|
||||
[
|
||||
AC_MSG_CHECKING([whether hunspell C++ (rather than C) ABI is provided])
|
||||
save_CXXFLAGS=$CXXFLAGS
|
||||
CXXFLAGS="$ENCHANT_CFLAGS $AM_CXXFLAGS $CXXFLAGS"
|
||||
|
||||
# in the C++ ABI, stem() returns a vector, in the C ABI, it returns an int
|
||||
AC_TRY_COMPILE([#include <hunspell/hunspell.hxx>],
|
||||
[Hunspell sp("foo", "bar");
|
||||
int i = sp.stem("test").size();],
|
||||
[AC_MSG_RESULT(yes)
|
||||
AC_DEFINE(HAVE_HUNSPELL_CXXABI, 1, [Define to 1 if hunspell C++ (rather than C) ABI is detected])
|
||||
have_hunspell_cxx_abi=yes
|
||||
],
|
||||
[AC_MSG_RESULT(no)])
|
||||
CXXFLAGS=$save_CXXFLAGS
|
||||
])
|
||||
|
||||
# Macro to add for using hunspell spellchecker libraries! -*- sh -*-
|
||||
AC_DEFUN([CHECK_WITH_HUNSPELL],
|
||||
[
|
||||
@ -83,6 +101,12 @@ AC_DEFUN([CHECK_WITH_HUNSPELL],
|
||||
AC_MSG_RESULT(no)
|
||||
fi
|
||||
fi
|
||||
LYX_HAVE_HUNSPELL_CXXABI
|
||||
if test $enable_stdlib_debug = "yes" -a -n "$have_hunspell_cxx_abi" ; then
|
||||
LYX_WARNING([Compiling LyX with stdlib-debug and system hunspell libraries may lead to
|
||||
crashes. Consider using --disable-stdlib-debug or --with-included-hunspell.])
|
||||
fi
|
||||
|
||||
])
|
||||
|
||||
dnl Usage: LYX_USE_INCLUDED_HUNSPELL : select if the included hunspell should
|
||||
@ -113,6 +137,7 @@ AC_DEFUN([LYX_CHECK_SPELL_ENGINES],
|
||||
dnl the user wanted to use the included hunspell, so do not check for external hunspell
|
||||
lyx_use_hunspell=true
|
||||
AC_DEFINE(USE_HUNSPELL, 1, [Define as 1 to use the hunspell library])
|
||||
AC_DEFINE(HAVE_HUNSPELL_CXXABI, 1, [Define to 1 if hunspell C++ (rather than C) ABI is detected])
|
||||
lyx_flags="$lyx_flags use-hunspell"
|
||||
else
|
||||
CHECK_WITH_HUNSPELL
|
||||
|
@ -60,38 +60,43 @@ cursor.
|
||||
|
||||
* Clean-up of drawing code
|
||||
|
||||
The goal is to make painting with drawing disable fast enough that it
|
||||
can be used after every metrics computation. Then we can separate real
|
||||
drawing from metrics.
|
||||
** Make SinglePar update flag useful again.
|
||||
|
||||
Other changes are only clean-ups.
|
||||
The current code can be very expensive when moving cursor inside a
|
||||
huge table, for example. We should test the flag again, although this
|
||||
will probably lead to some glitches here and there.
|
||||
|
||||
** Set Row::changed() in a finer way
|
||||
|
||||
*** singleParUpdate
|
||||
|
||||
When the height of the current paragraph changes, there is no need for
|
||||
a full screen update. Only the rows after the current one need to have
|
||||
their position recomputed.
|
||||
|
||||
This is also true when scrolling (how to do that?)
|
||||
|
||||
*** redoParagraph
|
||||
|
||||
It should be possible to check whether the new row is the same as the
|
||||
old one and keep its changed() status in this case. This would reduce
|
||||
a lot the amount of stuff to redraw.
|
||||
|
||||
** Put labels and friends in the Row as elements
|
||||
|
||||
It should not be necessary to access the Paragraph object to draw.
|
||||
Adding the static elements to Row is a lot of work, but worth it IMO.
|
||||
|
||||
** Create a unique row by paragraph and break it afterwards
|
||||
|
||||
This should be a performance gain (only if paragraph breaking still
|
||||
shows as expensive after the rest is done)
|
||||
|
||||
** do not add the vertical margin of main text to first/last row
|
||||
|
||||
Would make code cleaner. Probably no so difficult.
|
||||
|
||||
** When a paragraph ends with a newline, compute correctly the height of the extra row.
|
||||
** Rewrite TextMetrics::editXY, checkInsetHit using row information (getPosNearX)?
|
||||
|
||||
The helper version should return a Row::Element instead of an InsetTable.
|
||||
|
||||
** Set inset position during metrics phase
|
||||
|
||||
In order to do that, a no-paint drawing will be initiated after every
|
||||
redoParagraph. This code path will need to be made as fast as possible.
|
||||
|
||||
Effect: avoid depending on actual drawing having taken place. In turn,
|
||||
it will allow to do drawing on paint events, like any reasonable
|
||||
application would do.
|
||||
|
||||
** Cleanup after complete metrics
|
||||
Then the following can be done:
|
||||
+ remove hack in InsetMathNest::drawSelection
|
||||
+ remove painting when not inside in drawParagraph
|
||||
+ remove Cursor::inCoordCache?
|
||||
|
||||
** Paint directly to screen
|
||||
|
||||
Instead of using an intermediary pixmap. I have no idea of how
|
||||
difficult it will prove.
|
||||
One benefit will be that subpixel aliasing will work again (#9972)
|
||||
|
||||
** Merging bv::updateMetrics and tm::metrics
|
||||
|
||||
While the full metrics computation tries hard to limit the number of
|
||||
@ -101,25 +106,25 @@ insets. We should re-use the bv::updateMetrics logic:
|
||||
+ transfer all the logic of bv::updateMetrics to tm.
|
||||
+ Main InsetText should not be special.
|
||||
|
||||
The difficuly for a tall table cell for example, is that it may be
|
||||
The difficulty for a tall table cell for example, is that it may be
|
||||
necessary to break the whole contents to know the width of the cell.
|
||||
|
||||
|
||||
* Description of current drawing mechanism
|
||||
|
||||
** Two stage drawing
|
||||
** Three-stage drawing
|
||||
|
||||
There are two parts to drawing the work area:
|
||||
There are three parts to drawing the work area:
|
||||
|
||||
+ the metrics phase computes the size of insets and breaks the
|
||||
paragraphs into rows. It stores the dimension of insets (both
|
||||
normal and math) in bv::coordCache.
|
||||
|
||||
+ the drawing phase draws the contents and caches the inset
|
||||
positions. Since the caching of positions is useful in itself,
|
||||
there is a provision for drawing "without" drawing when the only
|
||||
thing we want is to cache inset positions
|
||||
(Painter::setDrawingEnabled).
|
||||
+ the nodraw drawing phase paints the screen (see below) with a null
|
||||
painter. The only useful effect is to store the inset positions.
|
||||
|
||||
+ an update() signal is sent. This in turn will trigger a paint
|
||||
event, and the actual screen painting will happen then.
|
||||
|
||||
The machinery is controlled via bv::processUpdateFlags. This method is
|
||||
called at the end of bv::mouseEventDispatch and in
|
||||
@ -138,25 +143,37 @@ DecorationUpdate). It triggers a recomputation of the metrics when either:
|
||||
existing metrics. Note that the Update::SinglePar flag is *never*
|
||||
taken into account.
|
||||
|
||||
If a computation of metrics has taken place, Force is removed from the
|
||||
flags and ForceDraw is added instead.
|
||||
|
||||
It is OK to call processUptateFlags several times before an update. In
|
||||
this case, the effects are cumulative.processUpdateFlags execute the
|
||||
metrics-related actions, but defers the actual drawing to the next
|
||||
paint event.
|
||||
|
||||
The screen is drawn (with appropriate update strategy), except when
|
||||
update flag is Update::None.
|
||||
|
||||
|
||||
** Metrics computation
|
||||
** Metrics computation (and nodraw drawing phase)
|
||||
|
||||
This is triggered by bv::updateMetrics, which calls tm::redoParagraph for
|
||||
all visible paragraphs. Paragraphs above or below the screen (needed
|
||||
all visible paragraphs. Some Paragraphs above or below the screen (needed
|
||||
for page up/down) and computed as needed.
|
||||
|
||||
tm::redoParagraph will call Inset::metrics for each inset. In the case
|
||||
of text insets, this will invoke recursively tm::metrics, which redoes
|
||||
all the paragraphs of the inset.
|
||||
|
||||
At the end of the function, bv::updatePosCache is called. It triggers
|
||||
a repaint of the document with a NullPainter (a painter that does
|
||||
nothing). This has the effect of caching all insets positions.
|
||||
|
||||
** Drawing the work area.
|
||||
|
||||
This is done in bv::draw. This method is triggered mainly by
|
||||
Buffer::changed, which draws all the work areas that show the given buffer.
|
||||
This is done in bv::draw. This method is triggered by a paint event,
|
||||
mainly called through Buffer::changed, which draws all the work areas
|
||||
that show the given buffer.
|
||||
|
||||
Note that, When Buffer::changed is called outside of
|
||||
bv::processUpdateFlags, it is not clear whether the update strategy
|
||||
@ -186,3 +203,6 @@ The action depends on the update strategy:
|
||||
|
||||
+ SingleParUpdate: only tries to repaint current paragraph in a way
|
||||
that is not yet very clear to me.
|
||||
|
||||
BufferView::draw can also be called with a null painter from
|
||||
BufferView::updateMetrics().
|
||||
|
@ -72,6 +72,36 @@ check_type_size("long long" HAVE_LONG_LONG)
|
||||
check_type_size(wchar_t HAVE_WCHAR_T)
|
||||
check_type_size(wint_t HAVE_WINT_T)
|
||||
|
||||
if(HUNSPELL_FOUND)
|
||||
# check whether hunspell C++ (rather than C) ABI is provided
|
||||
set(HunspellTestFile "${CMAKE_BINARY_DIR}/hunspelltest.cpp")
|
||||
file(WRITE "${HunspellTestFile}"
|
||||
"
|
||||
#include <hunspell/hunspell.hxx>
|
||||
|
||||
int main()
|
||||
{
|
||||
Hunspell sp(\"foo\", \"bar\");
|
||||
int i = sp.stem(\"test\").size();
|
||||
return(0);
|
||||
}
|
||||
"
|
||||
)
|
||||
|
||||
try_compile(HAVE_HUNSPELL_CXXABI
|
||||
"${CMAKE_BINARY_DIR}"
|
||||
"${HunspellTestFile}"
|
||||
CMAKE_FLAGS
|
||||
"-DINCLUDE_DIRECTORIES:STRING=${HUNSPELL_INCLUDE_DIR}"
|
||||
"-DCMAKE_CXX_LINK_EXECUTABLE='${CMAKE_COMMAD} echo not linking now...'"
|
||||
OUTPUT_VARIABLE LOG2)
|
||||
|
||||
message(STATUS "HAVE_HUNSPELL_CXXABI = ${HAVE_HUNSPELL_CXXABI}")
|
||||
#message(STATUS "LOG2 = ${LOG2}")
|
||||
if(LYX_EXTERNAL_HUNSPELL AND LYX_STDLIB_DEBUG AND HAVE_HUNSPELL_CXXABI)
|
||||
message(WARNING "Compiling LyX with stdlib-debug and system hunspell libraries may lead to crashes. Consider using -DLYX_STDLIB_DEBUG=OFF or -DLYX_EXTERNAL_HUNSPELL=OFF.")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
#check_cxx_source_compiles(
|
||||
# "
|
||||
|
@ -66,6 +66,9 @@
|
||||
#define HAVE_ALLOCA
|
||||
#endif
|
||||
|
||||
/* whether hunspell C++ (rather than C) ABI is provided */
|
||||
#cmakedefine HAVE_HUNSPELL_CXXABI 1
|
||||
|
||||
#cmakedefine HAVE_ICONV_CONST 1
|
||||
#ifdef HAVE_ICONV_CONST
|
||||
#define ICONV_CONST const
|
||||
|
@ -118,6 +118,9 @@
|
||||
@bMin Ding
|
||||
@iE-mail: u5032331 () uds ! anu ! edu ! au
|
||||
Chinese (simplified) translations
|
||||
@bAlexander Dunlap
|
||||
@iE-mail: alexander.dunlap () gmail ! com
|
||||
Improvement to recent files support
|
||||
@bAnders Ekberg
|
||||
@iE-mail: anek () chalmers ! se
|
||||
Improvements to the Swedish translation of the Windows Installer
|
||||
|
@ -111,6 +111,10 @@
|
||||
opened in editable mode. This state used to be hardcoded at compile
|
||||
time.
|
||||
|
||||
* buffer-anonymize (2.3.2)
|
||||
Replace all text n the document by streams of `a'. This is useful
|
||||
for sharing private documents in a bug report.
|
||||
|
||||
* font-crossout
|
||||
Cross out characters.
|
||||
|
||||
|
@ -768,10 +768,10 @@ def checkFormatEntries(dtl_tools):
|
||||
def checkConverterEntries():
|
||||
''' Check all converters (\converter entries) '''
|
||||
checkProg('the pdflatex program', ['pdflatex $$i'],
|
||||
rc_entry = [ r'\converter pdflatex pdf2 "%%" "latex=pdflatex"' ])
|
||||
rc_entry = [ r'\converter pdflatex pdf2 "%%" "latex=pdflatex,hyperref-driver=pdftex"' ])
|
||||
|
||||
checkProg('XeTeX', ['xelatex $$i'],
|
||||
rc_entry = [ r'\converter xetex pdf4 "%%" "latex=xelatex"' ])
|
||||
rc_entry = [ r'\converter xetex pdf4 "%%" "latex=xelatex,hyperref-driver=xetex"' ])
|
||||
|
||||
checkLuatex()
|
||||
|
||||
@ -923,7 +923,7 @@ def checkConverterEntries():
|
||||
rc_entry = [ r'\converter rtf html "%%" ""' ])
|
||||
# Do not define a converter to pdf6, ps is a pure export format
|
||||
checkProg('a PS to PDF converter', ['ps2pdf $$i $$o'],
|
||||
rc_entry = [ r'\converter ps pdf "%%" ""' ])
|
||||
rc_entry = [ r'\converter ps pdf "%%" "hyperref-driver=dvips"' ])
|
||||
#
|
||||
checkProg('a PS to TXT converter', ['pstotext $$i > $$o'],
|
||||
rc_entry = [ r'\converter ps text2 "%%" ""' ])
|
||||
@ -973,13 +973,13 @@ def checkConverterEntries():
|
||||
rc_entry = [ r'\converter dvi text4 "%%" ""' ])
|
||||
#
|
||||
checkProg('a DVI to PS converter', ['dvips -o $$o $$i'],
|
||||
rc_entry = [ r'\converter dvi ps "%%" ""' ])
|
||||
rc_entry = [ r'\converter dvi ps "%%" "hyperref-driver=dvips"' ])
|
||||
#
|
||||
checkProg('a DVI to cropped EPS converter', ['dvips -E -o $$o $$i'],
|
||||
rc_entry = [ r'\converter dvi eps3 "%%" ""' ])
|
||||
#
|
||||
checkProg('a DVI to PDF converter', ['dvipdfmx -o $$o $$i', 'dvipdfm -o $$o $$i'],
|
||||
rc_entry = [ r'\converter dvi pdf3 "%%" ""' ])
|
||||
checkProg('a DVI to PDF converter', ['dvipdfmx', 'dvipdfm'],
|
||||
rc_entry = [ r'\converter dvi pdf3 "%% -o $$o $$i" "hyperref-driver=%%"' ])
|
||||
#
|
||||
checkProg('a fax program', ['kdeprintfax $$i', 'ksendfax $$i', 'hylapex $$i'],
|
||||
rc_entry = [ r'\converter ps fax "%%" ""'])
|
||||
|
@ -124,11 +124,12 @@ logicalmkup
|
||||
\papercolumns 1
|
||||
\papersides 2
|
||||
\paperpagestyle headings
|
||||
\tracking_changes false
|
||||
\tracking_changes true
|
||||
\output_changes false
|
||||
\html_math_output 0
|
||||
\html_css_as_file 0
|
||||
\html_be_strict true
|
||||
\author -712698321 "Jürgen Spitzmüller"
|
||||
\end_header
|
||||
|
||||
\begin_body
|
||||
@ -2515,6 +2516,35 @@ value
|
||||
format:
|
||||
\end_layout
|
||||
|
||||
\begin_layout Labeling
|
||||
\labelwidthstring 00.00.0000
|
||||
|
||||
\change_inserted -712698321 1523206314
|
||||
\begin_inset Flex Code
|
||||
status collapsed
|
||||
|
||||
\begin_layout Plain Layout
|
||||
|
||||
\change_inserted -712698321 1523206193
|
||||
hyperref-driver
|
||||
\end_layout
|
||||
|
||||
\end_inset
|
||||
|
||||
The name of the driver that needs to be loaded with the
|
||||
\family sans
|
||||
hyperref
|
||||
\family default
|
||||
package for this converter.
|
||||
The loading of the correct driver is necessary to get some PDF-specific
|
||||
features.
|
||||
See the
|
||||
\family sans
|
||||
hyperref
|
||||
\family default
|
||||
manual for details.
|
||||
\end_layout
|
||||
|
||||
\begin_layout Labeling
|
||||
\labelwidthstring 00.00.0000
|
||||
\begin_inset Flex Code
|
||||
@ -2622,8 +2652,34 @@ $$b
|
||||
\end_layout
|
||||
|
||||
\begin_layout Standard
|
||||
None of these last three are presently used in any of the converters that
|
||||
are installed with \SpecialChar LyX
|
||||
|
||||
\change_inserted -712698321 1523206384
|
||||
A suitable hyperref-driver is set for some converters that are installed
|
||||
with \SpecialChar LyX
|
||||
.
|
||||
|
||||
\change_deleted -712698321 1523206388
|
||||
None of these
|
||||
\change_inserted -712698321 1523206389
|
||||
The
|
||||
\change_unchanged
|
||||
last three
|
||||
\change_inserted -712698321 1523206400
|
||||
flags, however,
|
||||
\change_unchanged
|
||||
are presently
|
||||
\change_inserted -712698321 1523206407
|
||||
not
|
||||
\change_unchanged
|
||||
used in any of the
|
||||
\change_inserted -712698321 1523206437
|
||||
pre-installed
|
||||
\change_unchanged
|
||||
converters
|
||||
\change_deleted -712698321 1523206442
|
||||
that are installed with \SpecialChar LyX
|
||||
|
||||
\change_unchanged
|
||||
.
|
||||
|
||||
\end_layout
|
||||
|
@ -145,6 +145,7 @@ enumitem
|
||||
\html_math_output 0
|
||||
\html_css_as_file 0
|
||||
\html_be_strict true
|
||||
\author 5863208 "ab"
|
||||
\end_header
|
||||
|
||||
\begin_body
|
||||
@ -19952,6 +19953,24 @@ LyX options
|
||||
tab.
|
||||
Joining an existing group can be done using the context menu of the image
|
||||
and checking the name of the desired group.
|
||||
|
||||
\change_inserted 5863208 1518729806
|
||||
If there are too many images which need to be assigned to a single group
|
||||
you can simply put all of them into single selection and choose
|
||||
\family sans
|
||||
Unify
|
||||
\begin_inset space ~
|
||||
\end_inset
|
||||
|
||||
Graphics
|
||||
\begin_inset space ~
|
||||
\end_inset
|
||||
|
||||
Groups
|
||||
\family default
|
||||
in context menu.
|
||||
\change_unchanged
|
||||
|
||||
\end_layout
|
||||
|
||||
\begin_layout Section
|
||||
|
@ -1989,6 +1989,25 @@ key=value
|
||||
\begin_layout Labeling
|
||||
\labelwidthstring 00.00.0000
|
||||
|
||||
\family typewriter
|
||||
hyperref-driver
|
||||
\family default
|
||||
Der Name der Treiberdatei, die für diesen Konverter mit dem
|
||||
\family sans
|
||||
Hyperref
|
||||
\family default
|
||||
-Paket geladen werden soll.
|
||||
Dies ist nötig, um bestimmte PDF-Features verwenden zu können.
|
||||
Konsultieren Sie das
|
||||
\family sans
|
||||
Hyperref
|
||||
\family default
|
||||
-Handbuch für Einzelheiten.
|
||||
\end_layout
|
||||
|
||||
\begin_layout Labeling
|
||||
\labelwidthstring 00.00.0000
|
||||
|
||||
\family typewriter
|
||||
parselog
|
||||
\family default
|
||||
@ -2082,9 +2101,11 @@ index
|
||||
\end_layout
|
||||
|
||||
\begin_layout Standard
|
||||
Keines dieser Flags wird zur Zeit in einem Konverter benutzt, der zusammen
|
||||
mit \SpecialChar LyX
|
||||
installiert wird.
|
||||
Ein passender Hyperref-Treiber wird für einige mit \SpecialChar LyX
|
||||
installierten Konverter
|
||||
definiert.
|
||||
Die zuletzt aufgeführten drei Flags hingegen werden zurzeit von keinem
|
||||
der vorinstallierten Konverter verwendet.
|
||||
\end_layout
|
||||
|
||||
\begin_layout Standard
|
||||
|
@ -647,6 +647,14 @@ contributors = [
|
||||
"27 April 2014",
|
||||
u"Chinese (simplified) translations"),
|
||||
|
||||
contributor(u"Alexander Dunlap",
|
||||
"alexander.dunlap () gmail ! com",
|
||||
"GPL",
|
||||
"licensing statement",
|
||||
"m=151914230920804",
|
||||
"20 February 2018",
|
||||
u"Improvement to recent files support"),
|
||||
|
||||
contributor(u"Anders Ekberg",
|
||||
"anek () chalmers ! se",
|
||||
"GPL",
|
||||
|
@ -364,6 +364,7 @@ Style Bibliography
|
||||
Size Larger
|
||||
EndFont
|
||||
TocLevel 1
|
||||
IsTocCaption 0
|
||||
End
|
||||
|
||||
|
||||
|
@ -177,6 +177,7 @@ Style Bibliography
|
||||
Size Huge
|
||||
EndFont
|
||||
TocLevel 1
|
||||
IsTocCaption 0
|
||||
End
|
||||
|
||||
|
||||
|
@ -228,5 +228,6 @@ Style Bibliography
|
||||
Size Larger
|
||||
EndFont
|
||||
TocLevel 1
|
||||
IsTocCaption 0
|
||||
End
|
||||
|
||||
|
@ -226,4 +226,5 @@ Style Bibliography
|
||||
Shape Smallcaps
|
||||
EndFont
|
||||
TocLevel 1
|
||||
IsTocCaption 0
|
||||
End
|
||||
|
@ -1126,6 +1126,7 @@ Style Bibliography
|
||||
Size Larger
|
||||
EndFont
|
||||
TocLevel 1
|
||||
IsTocCaption 0
|
||||
End
|
||||
|
||||
|
||||
|
@ -126,6 +126,7 @@ Style Bibliography
|
||||
Size Larger
|
||||
EndFont
|
||||
TocLevel 1
|
||||
IsTocCaption 0
|
||||
End
|
||||
|
||||
|
||||
|
@ -596,6 +596,7 @@ Style Bibliography
|
||||
Series Bold
|
||||
EndFont
|
||||
TocLevel 1
|
||||
IsTocCaption 0
|
||||
End
|
||||
|
||||
|
||||
|
@ -326,5 +326,6 @@ Style Bibliography
|
||||
Size Larger
|
||||
EndFont
|
||||
TocLevel 1
|
||||
IsTocCaption 0
|
||||
End
|
||||
|
||||
|
@ -468,4 +468,5 @@ Style Bibliography
|
||||
Size Larger
|
||||
EndFont
|
||||
TocLevel 1
|
||||
IsTocCaption 0
|
||||
End
|
||||
|
@ -481,4 +481,5 @@ Style Bibliography
|
||||
Size Larger
|
||||
EndFont
|
||||
TocLevel 1
|
||||
IsTocCaption 0
|
||||
End
|
||||
|
@ -288,6 +288,7 @@ Style "Bibliography (plain)"
|
||||
Size Larger
|
||||
EndFont
|
||||
TocLevel 1
|
||||
IsTocCaption 0
|
||||
End
|
||||
|
||||
|
||||
|
@ -289,5 +289,6 @@ Style Bibliography
|
||||
Size Larger
|
||||
EndFont
|
||||
TocLevel 1
|
||||
IsTocCaption 0
|
||||
End
|
||||
|
||||
|
@ -367,4 +367,5 @@ Style References
|
||||
Series Bold
|
||||
EndFont
|
||||
TocLevel 1
|
||||
IsTocCaption 0
|
||||
End
|
||||
|
@ -288,6 +288,7 @@ Style Bibliography
|
||||
Series Bold
|
||||
EndFont
|
||||
TocLevel 0
|
||||
IsTocCaption 0
|
||||
End
|
||||
|
||||
|
||||
|
@ -520,6 +520,7 @@ Style Bibliography
|
||||
Family Sans
|
||||
EndFont
|
||||
TocLevel 1
|
||||
IsTocCaption 0
|
||||
End
|
||||
|
||||
Style Recipient
|
||||
|
@ -371,7 +371,8 @@ Style Bibliography
|
||||
LabelType Bibliography
|
||||
LabelString ""
|
||||
LabelBottomSep 0
|
||||
TocLevel 1
|
||||
TocLevel 1
|
||||
IsTocCaption 0
|
||||
End
|
||||
|
||||
###
|
||||
|
@ -349,6 +349,7 @@ Style Bibliography
|
||||
Shape Smallcaps
|
||||
EndFont
|
||||
TocLevel 1
|
||||
IsTocCaption 0
|
||||
End
|
||||
|
||||
NoStyle Chapter
|
||||
|
@ -165,4 +165,5 @@ Style Bibliography
|
||||
Size Tiny
|
||||
EndFont
|
||||
TocLevel 1
|
||||
IsTocCaption 0
|
||||
End
|
||||
|
@ -82,4 +82,5 @@ Style Bibliography
|
||||
span.bibitemlabel:after { content: "] "; }
|
||||
EndHTMLStyle
|
||||
TocLevel 1
|
||||
ISTocCaption 0
|
||||
End
|
||||
|
@ -594,6 +594,7 @@ Style Bibliography
|
||||
Series Bold
|
||||
EndFont
|
||||
TocLevel 0
|
||||
IsTocCaption 0
|
||||
End
|
||||
|
||||
Style Description
|
||||
|
@ -705,7 +705,6 @@ $$
|
||||
\vspace{}
|
||||
\vspace*{}
|
||||
\whiledo{}{}
|
||||
\xymatrix{} % this is basically an array => the contents would be parsed badly (bug 8396)
|
||||
|
||||
% LaTeX environments.
|
||||
% They have always one extra "argument":
|
||||
|
@ -358,6 +358,7 @@ Menuset
|
||||
Item "Apply Last Text Style|A" "textstyle-apply"
|
||||
Submenu "Text Style|x" "edit_textstyles"
|
||||
Item "Paragraph Settings...|P" "layout-paragraph"
|
||||
OptItem "Unify Graphics Groups|U" "graphics-unify"
|
||||
LanguageSelector
|
||||
Separator
|
||||
Item "Fullscreen Mode" "ui-toggle fullscreen"
|
||||
|
@ -2626,15 +2626,16 @@ bool Buffer::getStatus(FuncRequest const & cmd, FuncStatus & flag)
|
||||
flag.setOnOff(params().output_changes);
|
||||
break;
|
||||
|
||||
case LFUN_BUFFER_TOGGLE_COMPRESSION: {
|
||||
case LFUN_BUFFER_TOGGLE_COMPRESSION:
|
||||
flag.setOnOff(params().compressed);
|
||||
break;
|
||||
}
|
||||
|
||||
case LFUN_BUFFER_TOGGLE_OUTPUT_SYNC: {
|
||||
case LFUN_BUFFER_TOGGLE_OUTPUT_SYNC:
|
||||
flag.setOnOff(params().output_sync);
|
||||
break;
|
||||
}
|
||||
|
||||
case LFUN_BUFFER_ANONYMIZE:
|
||||
break;
|
||||
|
||||
default:
|
||||
return false;
|
||||
@ -2664,7 +2665,8 @@ void Buffer::dispatch(FuncRequest const & func, DispatchResult & dr)
|
||||
string const argument = to_utf8(func.argument());
|
||||
// We'll set this back to false if need be.
|
||||
bool dispatched = true;
|
||||
undo().beginUndoGroup();
|
||||
// This handles undo groups automagically
|
||||
UndoGroupHelper ugh(this);
|
||||
|
||||
switch (func.action()) {
|
||||
case LFUN_BUFFER_TOGGLE_READ_ONLY:
|
||||
@ -2907,12 +2909,20 @@ void Buffer::dispatch(FuncRequest const & func, DispatchResult & dr)
|
||||
params().output_sync = !params().output_sync;
|
||||
break;
|
||||
|
||||
case LFUN_BUFFER_ANONYMIZE: {
|
||||
undo().recordUndoFullBuffer(CursorData());
|
||||
CursorData cur(doc_iterator_begin(this));
|
||||
for ( ; cur ; cur.forwardPar())
|
||||
cur.paragraph().anonymize();
|
||||
dr.forceBufferUpdate();
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
dispatched = false;
|
||||
break;
|
||||
}
|
||||
dr.dispatched(dispatched);
|
||||
undo().endUndoGroup();
|
||||
}
|
||||
|
||||
|
||||
@ -3185,9 +3195,27 @@ vector<docstring> const Buffer::prepareBibFilePaths(OutputParams const & runpara
|
||||
string utf8input = to_utf8(it->first);
|
||||
string database =
|
||||
prepareFileNameForLaTeX(utf8input, ".bib", runparams.nice);
|
||||
FileName const try_in_file =
|
||||
FileName try_in_file =
|
||||
makeAbsPath(database + ".bib", filePath());
|
||||
bool const not_from_texmf = try_in_file.isReadableFile();
|
||||
bool not_from_texmf = try_in_file.isReadableFile();
|
||||
// If the file has not been found, try with the real file name
|
||||
// (it might come from a child in a sub-directory)
|
||||
if (!not_from_texmf) {
|
||||
try_in_file = it->second;
|
||||
if (try_in_file.isReadableFile()) {
|
||||
// Check if the file is in texmf
|
||||
FileName kpsefile(findtexfile(changeExtension(utf8input, "bib"), "bib", true));
|
||||
not_from_texmf = kpsefile.empty()
|
||||
|| kpsefile.absFileName() != try_in_file.absFileName();
|
||||
if (not_from_texmf)
|
||||
// If this exists, make path relative to the master
|
||||
// FIXME Unicode
|
||||
database = removeExtension(
|
||||
prepareFileNameForLaTeX(to_utf8(makeRelPath(from_utf8(try_in_file.absFileName()),
|
||||
from_utf8(filePath()))),
|
||||
".bib", runparams.nice));
|
||||
}
|
||||
}
|
||||
|
||||
if (!runparams.inComment && !runparams.dryrun && !runparams.nice &&
|
||||
not_from_texmf) {
|
||||
@ -4301,6 +4329,7 @@ Buffer::ExportStatus Buffer::doExport(string const & target, bool put_in_tempdir
|
||||
return ExportNoPathToFormat;
|
||||
}
|
||||
runparams.flavor = converters.getFlavor(path, this);
|
||||
runparams.hyperref_driver = converters.getHyperrefDriver(path);
|
||||
Graph::EdgePath::const_iterator it = path.begin();
|
||||
Graph::EdgePath::const_iterator en = path.end();
|
||||
for (; it != en; ++it)
|
||||
@ -5360,7 +5389,6 @@ void Buffer::Impl::fileExternallyModified(bool const exists)
|
||||
"checksum unchanged: " << filename);
|
||||
return;
|
||||
}
|
||||
lyx_clean = bak_clean = false;
|
||||
// If the file has been deleted, only mark the file as dirty since it is
|
||||
// pointless to prompt for reloading. If later a file is moved into this
|
||||
// location, then the externally modified warning will appear then.
|
||||
|
@ -394,7 +394,7 @@ BufferParams::BufferParams()
|
||||
papersize = PAPER_DEFAULT;
|
||||
orientation = ORIENTATION_PORTRAIT;
|
||||
use_geometry = false;
|
||||
biblio_style = "plain";
|
||||
biblio_style = string();
|
||||
use_bibtopic = false;
|
||||
multibib = string();
|
||||
use_indices = false;
|
||||
@ -2094,8 +2094,8 @@ bool BufferParams::writeLaTeX(otexstream & os, LaTeXFeatures & features,
|
||||
OutputParams tmp_params = features.runparams();
|
||||
pdfoptions().writeLaTeX(tmp_params, os,
|
||||
features.isProvided("hyperref"));
|
||||
// correctly break URLs with hyperref and dvi output
|
||||
if (features.runparams().flavor == OutputParams::LATEX
|
||||
// correctly break URLs with hyperref and dvi/ps output
|
||||
if (features.runparams().hyperref_driver == "dvips"
|
||||
&& features.isAvailable("breakurl"))
|
||||
os << "\\usepackage{breakurl}\n";
|
||||
} else if (features.isRequired("nameref"))
|
||||
@ -3426,6 +3426,9 @@ bool BufferParams::addCiteEngine(vector<string> const & engine)
|
||||
|
||||
string const & BufferParams::defaultBiblioStyle() const
|
||||
{
|
||||
if (!biblio_style.empty())
|
||||
return biblio_style;
|
||||
|
||||
map<string, string> const & bs = documentClass().defaultBiblioStyle();
|
||||
auto cit = bs.find(theCiteEnginesList.getTypeAsString(citeEngineType()));
|
||||
if (cit != bs.end())
|
||||
|
@ -70,6 +70,7 @@
|
||||
#include "frontends/Application.h"
|
||||
#include "frontends/Delegates.h"
|
||||
#include "frontends/FontMetrics.h"
|
||||
#include "frontends/NullPainter.h"
|
||||
#include "frontends/Painter.h"
|
||||
#include "frontends/Selection.h"
|
||||
|
||||
@ -227,14 +228,15 @@ enum ScreenUpdateStrategy {
|
||||
|
||||
struct BufferView::Private
|
||||
{
|
||||
Private(BufferView & bv) : update_strategy_(NoScreenUpdate),
|
||||
Private(BufferView & bv) : update_strategy_(FullScreenUpdate),
|
||||
update_flags_(Update::Force),
|
||||
wh_(0), cursor_(bv),
|
||||
anchor_pit_(0), anchor_ypos_(0),
|
||||
inlineCompletionUniqueChars_(0),
|
||||
last_inset_(0), clickable_inset_(false),
|
||||
mouse_position_cache_(),
|
||||
bookmark_edit_position_(-1), gui_(0),
|
||||
horiz_scroll_offset_(0)
|
||||
horiz_scroll_offset_(0), repaint_caret_row_(false)
|
||||
{
|
||||
xsel_cache_.set = false;
|
||||
}
|
||||
@ -244,6 +246,8 @@ struct BufferView::Private
|
||||
///
|
||||
ScreenUpdateStrategy update_strategy_;
|
||||
///
|
||||
Update::flags update_flags_;
|
||||
///
|
||||
CoordCache coord_cache_;
|
||||
|
||||
/// Estimated average par height for scrollbar.
|
||||
@ -311,6 +315,12 @@ struct BufferView::Private
|
||||
/// a slice pointing to the start of the row where cursor was
|
||||
/// at previous draw event
|
||||
CursorSlice last_row_slice_;
|
||||
|
||||
/// a slice pointing to where the cursor has been drawn after the current
|
||||
/// draw() call.
|
||||
CursorSlice caret_slice_;
|
||||
/// indicates whether the caret slice needs to be repainted in this draw() run.
|
||||
bool repaint_caret_row_;
|
||||
};
|
||||
|
||||
|
||||
@ -438,79 +448,85 @@ bool BufferView::needsFitCursor() const
|
||||
}
|
||||
|
||||
|
||||
namespace {
|
||||
|
||||
// this is for debugging only.
|
||||
string flagsAsString(Update::flags flags)
|
||||
{
|
||||
if (flags == Update::None)
|
||||
return "None ";
|
||||
return string((flags & Update::FitCursor) ? "FitCursor " : "")
|
||||
+ ((flags & Update::Force) ? "Force " : "")
|
||||
+ ((flags & Update::ForceDraw) ? "ForceDraw " : "")
|
||||
+ ((flags & Update::SinglePar) ? "SinglePar " : "");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void BufferView::processUpdateFlags(Update::flags flags)
|
||||
{
|
||||
// This is close to a hot-path.
|
||||
LYXERR(Debug::PAINTING, "BufferView::processUpdateFlags()"
|
||||
<< "[fitcursor = " << (flags & Update::FitCursor)
|
||||
<< ", forceupdate = " << (flags & Update::Force)
|
||||
<< ", singlepar = " << (flags & Update::SinglePar)
|
||||
<< "] buffer: " << &buffer_);
|
||||
|
||||
// FIXME Does this really need doing here? It's done in updateBuffer, and
|
||||
// if the Buffer doesn't need updating, then do the macros?
|
||||
buffer_.updateMacros();
|
||||
|
||||
// Now do the first drawing step if needed. This consists on updating
|
||||
// the CoordCache in updateMetrics().
|
||||
// The second drawing step is done in WorkArea::redraw() if needed.
|
||||
// FIXME: is this still true now that Buffer::changed() is used all over?
|
||||
LYXERR(Debug::PAINTING, "BufferView::processUpdateFlags( "
|
||||
<< flagsAsString(flags) << ") buffer: " << &buffer_);
|
||||
|
||||
// Case when no explicit update is requested.
|
||||
if (!flags) {
|
||||
if (flags == Update::None)
|
||||
return;
|
||||
|
||||
// SinglePar is ignored for now (this should probably change). We
|
||||
// set it ourselves below, at the price of always rebreaking the
|
||||
// paragraph at cursor. This can be expensive for large tables.
|
||||
flags = flags & ~Update::SinglePar;
|
||||
|
||||
// First check whether the metrics and inset positions should be updated
|
||||
if (flags & Update::Force) {
|
||||
// This will update the CoordCache items and replace Force
|
||||
// with ForceDraw in flags.
|
||||
updateMetrics(flags);
|
||||
}
|
||||
|
||||
// Then make sure that the screen contains the cursor if needed
|
||||
if (flags & Update::FitCursor) {
|
||||
if (needsFitCursor()) {
|
||||
scrollToCursor(d->cursor_, false);
|
||||
// Metrics have to be recomputed (maybe again)
|
||||
updateMetrics(flags);
|
||||
}
|
||||
flags = flags & ~Update::FitCursor;
|
||||
}
|
||||
|
||||
// Finally detect whether we can only repaint a single paragraph
|
||||
if (!(flags & Update::ForceDraw)) {
|
||||
if (singleParUpdate())
|
||||
flags = flags | Update::SinglePar;
|
||||
else
|
||||
updateMetrics(flags);
|
||||
}
|
||||
|
||||
// Add flags to the the update flags. These will be reset to None
|
||||
// after the redraw is actually done
|
||||
d->update_flags_ = d->update_flags_ | flags;
|
||||
LYXERR(Debug::PAINTING, "Cumulative flags: " << flagsAsString(flags));
|
||||
|
||||
// Now compute the update strategy
|
||||
// Possibly values in flag are None, Decoration, ForceDraw
|
||||
LATTEST((d->update_flags_ & ~(Update::None | Update::SinglePar
|
||||
| Update::Decoration | Update::ForceDraw)) == 0);
|
||||
|
||||
if (d->update_flags_ & Update::ForceDraw)
|
||||
d->update_strategy_ = FullScreenUpdate;
|
||||
else if (d->update_flags_ & Update::Decoration)
|
||||
d->update_strategy_ = DecorationUpdate;
|
||||
else if (d->update_flags_ & Update::SinglePar)
|
||||
d->update_strategy_ = SingleParUpdate;
|
||||
else {
|
||||
// no need to redraw anything.
|
||||
d->update_strategy_ = NoScreenUpdate;
|
||||
return;
|
||||
}
|
||||
|
||||
if (flags == Update::Decoration) {
|
||||
d->update_strategy_ = DecorationUpdate;
|
||||
buffer_.changed(false);
|
||||
return;
|
||||
}
|
||||
|
||||
if (flags == Update::FitCursor
|
||||
|| flags == (Update::Decoration | Update::FitCursor)) {
|
||||
// tell the frontend to update the screen if needed.
|
||||
if (needsFitCursor()) {
|
||||
showCursor();
|
||||
return;
|
||||
}
|
||||
if (flags & Update::Decoration) {
|
||||
d->update_strategy_ = DecorationUpdate;
|
||||
buffer_.changed(false);
|
||||
return;
|
||||
}
|
||||
// no screen update is needed in principle, but this
|
||||
// could change if cursor row needs horizontal scrolling.
|
||||
d->update_strategy_ = NoScreenUpdate;
|
||||
buffer_.changed(false);
|
||||
return;
|
||||
}
|
||||
|
||||
bool const full_metrics = flags & Update::Force || !singleParUpdate();
|
||||
|
||||
if (full_metrics)
|
||||
// We have to update the full screen metrics.
|
||||
updateMetrics();
|
||||
|
||||
if (!(flags & Update::FitCursor)) {
|
||||
// Nothing to do anymore. Trigger a redraw and return
|
||||
buffer_.changed(false);
|
||||
return;
|
||||
}
|
||||
|
||||
// updateMetrics() does not update paragraph position
|
||||
// This is done at draw() time. So we need a redraw!
|
||||
buffer_.changed(false);
|
||||
|
||||
if (needsFitCursor()) {
|
||||
// The cursor is off screen so ensure it is visible.
|
||||
// refresh it:
|
||||
showCursor();
|
||||
}
|
||||
|
||||
updateHoveredInset();
|
||||
|
||||
// Trigger a redraw.
|
||||
buffer_.changed(false);
|
||||
}
|
||||
|
||||
|
||||
@ -625,8 +641,7 @@ void BufferView::scrollDocView(int const value, bool update)
|
||||
// If the offset is less than 2 screen height, prefer to scroll instead.
|
||||
if (abs(value) <= 2 * height_) {
|
||||
d->anchor_ypos_ -= value;
|
||||
buffer_.changed(true);
|
||||
updateHoveredInset();
|
||||
processUpdateFlags(Update::Force);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -823,12 +838,7 @@ bool BufferView::moveToPosition(pit_type bottom_pit, pos_type bottom_pos,
|
||||
d->cursor_.setCurrentFont();
|
||||
// Do not forget to reset the anchor (see #9912)
|
||||
d->cursor_.resetAnchor();
|
||||
// To center the screen on this new position we need the
|
||||
// paragraph position which is computed at draw() time.
|
||||
// So we need a redraw!
|
||||
buffer_.changed(false);
|
||||
if (needsFitCursor())
|
||||
showCursor();
|
||||
processUpdateFlags(Update::FitCursor);
|
||||
}
|
||||
|
||||
return success;
|
||||
@ -870,19 +880,15 @@ void BufferView::showCursor()
|
||||
void BufferView::showCursor(DocIterator const & dit,
|
||||
bool recenter, bool update)
|
||||
{
|
||||
if (scrollToCursor(dit, recenter) && update) {
|
||||
buffer_.changed(true);
|
||||
updateHoveredInset();
|
||||
}
|
||||
if (scrollToCursor(dit, recenter) && update)
|
||||
processUpdateFlags(Update::Force);
|
||||
}
|
||||
|
||||
|
||||
void BufferView::scrollToCursor()
|
||||
{
|
||||
if (scrollToCursor(d->cursor_, false)) {
|
||||
buffer_.changed(true);
|
||||
updateHoveredInset();
|
||||
}
|
||||
if (scrollToCursor(d->cursor_, false))
|
||||
processUpdateFlags(Update::Force);
|
||||
}
|
||||
|
||||
|
||||
@ -1128,6 +1134,10 @@ bool BufferView::getStatus(FuncRequest const & cmd, FuncStatus & flag)
|
||||
flag.setEnabled(true);
|
||||
break;
|
||||
|
||||
case LFUN_GRAPHICS_UNIFY:
|
||||
flag.setEnabled(cur.selection());
|
||||
break;
|
||||
|
||||
case LFUN_WORD_FINDADV: {
|
||||
FindAndReplaceOptions opt;
|
||||
istringstream iss(to_utf8(cmd.argument()));
|
||||
@ -1649,6 +1659,45 @@ void BufferView::dispatch(FuncRequest const & cmd, DispatchResult & dr)
|
||||
break;
|
||||
}
|
||||
|
||||
case LFUN_GRAPHICS_UNIFY: {
|
||||
|
||||
cur.recordUndoFullBuffer();
|
||||
|
||||
DocIterator from, to;
|
||||
from = cur.selectionBegin();
|
||||
to = cur.selectionEnd();
|
||||
|
||||
string const newId = cmd.getArg(0);
|
||||
bool fetchId = newId.empty(); //if we wait for groupId from first graphics inset
|
||||
|
||||
InsetGraphicsParams grp_par;
|
||||
if (!fetchId)
|
||||
InsetGraphics::string2params(graphics::getGroupParams(buffer_, newId), buffer_, grp_par);
|
||||
|
||||
if (!from.nextInset()) //move to closest inset
|
||||
from.forwardInset();
|
||||
|
||||
while (!from.empty() && from < to) {
|
||||
Inset * inset = from.nextInset();
|
||||
if (!inset)
|
||||
break;
|
||||
if (inset->lyxCode() == GRAPHICS_CODE) {
|
||||
InsetGraphics & ig = static_cast<InsetGraphics &>(*inset);
|
||||
InsetGraphicsParams inspar = ig.getParams();
|
||||
if (fetchId) {
|
||||
grp_par = inspar;
|
||||
fetchId = false;
|
||||
} else {
|
||||
grp_par.filename = inspar.filename;
|
||||
ig.setParams(grp_par);
|
||||
}
|
||||
}
|
||||
from.forwardInset();
|
||||
}
|
||||
dr.screenUpdate(Update::Force); //needed if triggered from context menu
|
||||
break;
|
||||
}
|
||||
|
||||
case LFUN_STATISTICS: {
|
||||
DocIterator from, to;
|
||||
if (cur.selection()) {
|
||||
@ -1708,8 +1757,8 @@ void BufferView::dispatch(FuncRequest const & cmd, DispatchResult & dr)
|
||||
bool const in_texted = cur.inTexted();
|
||||
cur.setCursor(doc_iterator_begin(cur.buffer()));
|
||||
cur.selHandle(false);
|
||||
buffer_.changed(true);
|
||||
updateHoveredInset();
|
||||
// Force an immediate computation of metrics because we need it below
|
||||
processUpdateFlags(Update::Force);
|
||||
|
||||
d->text_metrics_[&buffer_.text()].editXY(cur, p.x_, p.y_,
|
||||
true, act == LFUN_SCREEN_UP);
|
||||
@ -1743,8 +1792,7 @@ void BufferView::dispatch(FuncRequest const & cmd, DispatchResult & dr)
|
||||
if (scroll_value)
|
||||
scroll(scroll_step * scroll_value);
|
||||
}
|
||||
buffer_.changed(true);
|
||||
updateHoveredInset();
|
||||
dr.screenUpdate(Update::ForceDraw);
|
||||
dr.forceBufferUpdate();
|
||||
break;
|
||||
}
|
||||
@ -1974,6 +2022,8 @@ void BufferView::dispatch(FuncRequest const & cmd, DispatchResult & dr)
|
||||
icp["key"] = from_utf8(arg);
|
||||
if (!opt1.empty())
|
||||
icp["before"] = from_utf8(opt1);
|
||||
icp["literal"] =
|
||||
from_ascii(InsetCitation::last_literal ? "true" : "false");
|
||||
string icstr = InsetCommand::params2string(icp);
|
||||
FuncRequest fr(LFUN_INSET_INSERT, icstr);
|
||||
lyx::dispatch(fr);
|
||||
@ -2638,7 +2688,7 @@ bool BufferView::singleParUpdate()
|
||||
// the singlePar optimisation.
|
||||
return false;
|
||||
|
||||
d->update_strategy_ = SingleParUpdate;
|
||||
tm.updatePosCache(bottom_pit);
|
||||
|
||||
LYXERR(Debug::PAINTING, "\ny1: " << pm.position() - pm.ascent()
|
||||
<< " y2: " << pm.position() + pm.descent()
|
||||
@ -2649,6 +2699,13 @@ bool BufferView::singleParUpdate()
|
||||
|
||||
|
||||
void BufferView::updateMetrics()
|
||||
{
|
||||
updateMetrics(d->update_flags_);
|
||||
d->update_strategy_ = FullScreenUpdate;
|
||||
}
|
||||
|
||||
|
||||
void BufferView::updateMetrics(Update::flags & update_flags)
|
||||
{
|
||||
if (height_ == 0 || width_ == 0)
|
||||
return;
|
||||
@ -2691,6 +2748,7 @@ void BufferView::updateMetrics()
|
||||
}
|
||||
}
|
||||
anchor_pm.setPosition(d->anchor_ypos_);
|
||||
tm.updatePosCache(d->anchor_pit_);
|
||||
|
||||
LYXERR(Debug::PAINTING, "metrics: "
|
||||
<< " anchor pit = " << d->anchor_pit_
|
||||
@ -2706,6 +2764,7 @@ void BufferView::updateMetrics()
|
||||
y1 -= pm.descent();
|
||||
// Save the paragraph position in the cache.
|
||||
pm.setPosition(y1);
|
||||
tm.updatePosCache(pit1);
|
||||
y1 -= pm.ascent();
|
||||
}
|
||||
|
||||
@ -2719,6 +2778,7 @@ void BufferView::updateMetrics()
|
||||
y2 += pm.ascent();
|
||||
// Save the paragraph position in the cache.
|
||||
pm.setPosition(y2);
|
||||
tm.updatePosCache(pit2);
|
||||
y2 += pm.descent();
|
||||
}
|
||||
|
||||
@ -2730,7 +2790,11 @@ void BufferView::updateMetrics()
|
||||
<< " pit1 = " << pit1
|
||||
<< " pit2 = " << pit2);
|
||||
|
||||
d->update_strategy_ = FullScreenUpdate;
|
||||
// metrics is done, full drawing is necessary now
|
||||
update_flags = (update_flags & ~Update::Force) | Update::ForceDraw;
|
||||
|
||||
// Now update the positions of insets in the cache.
|
||||
updatePosCache();
|
||||
|
||||
if (lyxerr.debugging(Debug::WORKAREA)) {
|
||||
LYXERR(Debug::WORKAREA, "BufferView::updateMetrics");
|
||||
@ -2739,6 +2803,15 @@ void BufferView::updateMetrics()
|
||||
}
|
||||
|
||||
|
||||
void BufferView::updatePosCache()
|
||||
{
|
||||
// this is the "nodraw" drawing stage: only set the positions of the
|
||||
// insets in metrics cache.
|
||||
frontend::NullPainter np;
|
||||
draw(np, false);
|
||||
}
|
||||
|
||||
|
||||
void BufferView::insertLyXFile(FileName const & fname)
|
||||
{
|
||||
LASSERT(d->cursor_.inTexted(), return);
|
||||
@ -2873,7 +2946,7 @@ bool BufferView::paragraphVisible(DocIterator const & dit) const
|
||||
}
|
||||
|
||||
|
||||
void BufferView::cursorPosAndHeight(Point & p, int & h) const
|
||||
void BufferView::caretPosAndHeight(Point & p, int & h) const
|
||||
{
|
||||
Cursor const & cur = cursor();
|
||||
Font const font = cur.real_current_font;
|
||||
@ -2946,7 +3019,30 @@ void BufferView::setCurrentRowSlice(CursorSlice const & rowSlice)
|
||||
}
|
||||
|
||||
|
||||
void BufferView::checkCursorScrollOffset(PainterInfo & pi)
|
||||
namespace {
|
||||
|
||||
bool sliceInRow(CursorSlice const & cs, Text const * text, Row const & row)
|
||||
{
|
||||
/* The normal case is the last line. The previous line takes care
|
||||
* of empty rows (e.g. empty paragraphs). Cursor boundary issues
|
||||
* are taken care of when setting caret_slice_ in
|
||||
* BufferView::draw.
|
||||
*/
|
||||
return !cs.empty() && cs.text() == text && cs.pit() == row.pit()
|
||||
&& ((row.pos() == row.endpos() && row.pos() == cs.pos())
|
||||
|| (row.pos() <= cs.pos() && cs.pos() < row.endpos()));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
bool BufferView::needRepaint(Text const * text, Row const & row) const
|
||||
{
|
||||
return d->repaint_caret_row_ && sliceInRow(d->caret_slice_, text, row);
|
||||
}
|
||||
|
||||
|
||||
void BufferView::checkCursorScrollOffset()
|
||||
{
|
||||
CursorSlice rowSlice = d->cursor_.bottom();
|
||||
TextMetrics const & tm = textMetrics(rowSlice.text());
|
||||
@ -2963,35 +3059,6 @@ void BufferView::checkCursorScrollOffset(PainterInfo & pi)
|
||||
// Set the row on which the cursor lives.
|
||||
setCurrentRowSlice(rowSlice);
|
||||
|
||||
// If insets referred to by cursor are not all in the cache, the positions
|
||||
// need to be recomputed.
|
||||
if (!d->cursor_.inCoordCache()) {
|
||||
/** FIXME: the code below adds an extraneous computation of
|
||||
* inset positions, and can therefore be bad for performance
|
||||
* (think for example about a very large tabular inset.
|
||||
* Redawing the row where it is means redrawing the whole
|
||||
* screen).
|
||||
*
|
||||
* The bug that this fixes is the following: assume that there
|
||||
* is a very large math inset. Upon entering the inset, when
|
||||
* pressing `End', the row is not scrolled and the cursor is
|
||||
* not visible. The extra row computation makes sure that the
|
||||
* inset positions are correctly computed and set in the
|
||||
* cache. This would not happen if we did not have two-stage
|
||||
* drawing.
|
||||
*
|
||||
* A proper fix would be to always have proper inset positions
|
||||
* at this point.
|
||||
*/
|
||||
// Force the recomputation of inset positions
|
||||
bool const drawing = pi.pain.isDrawingEnabled();
|
||||
pi.pain.setDrawingEnabled(false);
|
||||
// No need to care about vertical position.
|
||||
RowPainter rp(pi, buffer().text(), row, -d->horiz_scroll_offset_, 0);
|
||||
rp.paintText();
|
||||
pi.pain.setDrawingEnabled(drawing);
|
||||
}
|
||||
|
||||
// Current x position of the cursor in pixels
|
||||
int cur_x = getPos(d->cursor_).x_;
|
||||
|
||||
@ -3035,30 +3102,46 @@ void BufferView::checkCursorScrollOffset(PainterInfo & pi)
|
||||
}
|
||||
|
||||
|
||||
void BufferView::draw(frontend::Painter & pain)
|
||||
void BufferView::draw(frontend::Painter & pain, bool paint_caret)
|
||||
{
|
||||
if (height_ == 0 || width_ == 0)
|
||||
return;
|
||||
LYXERR(Debug::PAINTING, "\t\t*** START DRAWING ***");
|
||||
|
||||
LYXERR(Debug::PAINTING, (pain.isNull() ? "\t\t--- START NODRAW ---"
|
||||
: "\t\t*** START DRAWING ***"));
|
||||
Text & text = buffer_.text();
|
||||
TextMetrics const & tm = d->text_metrics_[&text];
|
||||
int const y = tm.first().second->position();
|
||||
PainterInfo pi(this, pain);
|
||||
|
||||
/** A repaint of the previous caret row is needed if there is
|
||||
* caret painted on screen and either
|
||||
* 1/ a new caret has to be painted at a place different from
|
||||
* the existing one;
|
||||
* 2/ there is no need for a caret anymore.
|
||||
*/
|
||||
d->repaint_caret_row_ = !d->caret_slice_.empty() &&
|
||||
((paint_caret && d->cursor_.top() != d->caret_slice_)
|
||||
|| ! paint_caret);
|
||||
|
||||
// Check whether the row where the cursor lives needs to be scrolled.
|
||||
// Update the drawing strategy if needed.
|
||||
checkCursorScrollOffset(pi);
|
||||
checkCursorScrollOffset();
|
||||
|
||||
switch (d->update_strategy_) {
|
||||
|
||||
case NoScreenUpdate:
|
||||
// If no screen painting is actually needed, only some the different
|
||||
// coordinates of insets and paragraphs needs to be updated.
|
||||
// no screen painting is actually needed. In nodraw stage
|
||||
// however, the different coordinates of insets and paragraphs
|
||||
// needs to be updated.
|
||||
LYXERR(Debug::PAINTING, "Strategy: NoScreenUpdate");
|
||||
pi.full_repaint = true;
|
||||
pi.pain.setDrawingEnabled(false);
|
||||
tm.draw(pi, 0, y);
|
||||
pi.full_repaint = false;
|
||||
if (pain.isNull()) {
|
||||
pi.full_repaint = true;
|
||||
tm.draw(pi, 0, y);
|
||||
} else if (d->repaint_caret_row_) {
|
||||
pi.full_repaint = false;
|
||||
tm.draw(pi, 0, y);
|
||||
}
|
||||
break;
|
||||
|
||||
case SingleParUpdate:
|
||||
@ -3103,7 +3186,8 @@ void BufferView::draw(frontend::Painter & pain)
|
||||
}
|
||||
break;
|
||||
}
|
||||
LYXERR(Debug::PAINTING, "\n\t\t*** END DRAWING ***");
|
||||
LYXERR(Debug::PAINTING, (pain.isNull() ? "\t\t --- END NODRAW ---"
|
||||
: "\t\t *** END DRAWING ***"));
|
||||
|
||||
// The scrollbar needs an update.
|
||||
updateScrollbar();
|
||||
@ -3114,13 +3198,29 @@ void BufferView::draw(frontend::Painter & pain)
|
||||
for (pit_type pit = firstpm.first; pit <= lastpm.first; ++pit) {
|
||||
ParagraphMetrics const & pm = tm.parMetrics(pit);
|
||||
if (pm.position() + pm.descent() > 0) {
|
||||
if (d->anchor_pit_ != pit
|
||||
|| d->anchor_ypos_ != pm.position())
|
||||
LYXERR(Debug::PAINTING, "Found new anchor pit = " << d->anchor_pit_
|
||||
<< " anchor ypos = " << d->anchor_ypos_);
|
||||
d->anchor_pit_ = pit;
|
||||
d->anchor_ypos_ = pm.position();
|
||||
break;
|
||||
}
|
||||
}
|
||||
LYXERR(Debug::PAINTING, "Found new anchor pit = " << d->anchor_pit_
|
||||
<< " anchor ypos = " << d->anchor_ypos_);
|
||||
if (!pain.isNull()) {
|
||||
// reset the update flags, everything has been done
|
||||
d->update_flags_ = Update::None;
|
||||
}
|
||||
|
||||
// Remember what has just been done for the next draw() step
|
||||
if (paint_caret) {
|
||||
d->caret_slice_ = d->cursor_.top();
|
||||
if (d->caret_slice_.pos() > 0
|
||||
&& (d->cursor_.boundary()
|
||||
|| d->caret_slice_.pos() == d->caret_slice_.lastpos()))
|
||||
--d->caret_slice_.pos();
|
||||
} else
|
||||
d->caret_slice_ = CursorSlice();
|
||||
}
|
||||
|
||||
|
||||
|
@ -42,10 +42,10 @@ class FuncStatus;
|
||||
class Intl;
|
||||
class Inset;
|
||||
class Length;
|
||||
class PainterInfo;
|
||||
class ParIterator;
|
||||
class ParagraphMetrics;
|
||||
class Point;
|
||||
class Row;
|
||||
class TexRow;
|
||||
class Text;
|
||||
class TextMetrics;
|
||||
@ -120,11 +120,12 @@ public:
|
||||
/// \return true if the BufferView is at the bottom of the document.
|
||||
bool isBottomScreen() const;
|
||||
|
||||
/// perform pending metrics updates.
|
||||
/** \c Update::FitCursor means first to do a FitCursor, and to
|
||||
/// Add \p flags to current update flags and trigger an update.
|
||||
/* If this method is invoked several times before the update
|
||||
* actually takes place, the effect is cumulative.
|
||||
* \c Update::FitCursor means first to do a FitCursor, and to
|
||||
* force an update if screen position changes.
|
||||
* \c Update::Force means to force an update in any case.
|
||||
* \retval true if a screen redraw is needed
|
||||
*/
|
||||
void processUpdateFlags(Update::flags flags);
|
||||
|
||||
@ -132,6 +133,9 @@ public:
|
||||
/// Only to be called with good y coordinates (after a bv::metrics)
|
||||
bool needsFitCursor() const;
|
||||
|
||||
/// returns true if this row needs to be repainted (to erase caret)
|
||||
bool needRepaint(Text const * text, Row const & row) const;
|
||||
|
||||
// Returns the amount of horizontal scrolling applied to the
|
||||
// top-level row where the cursor lies
|
||||
int horizScrollOffset() const;
|
||||
@ -283,6 +287,10 @@ public:
|
||||
/// update the internal \c ViewMetricsInfo.
|
||||
void updateMetrics();
|
||||
|
||||
// this is the "nodraw" drawing stage: only set the positions of the
|
||||
// insets in metrics cache.
|
||||
void updatePosCache();
|
||||
|
||||
///
|
||||
TextMetrics const & textMetrics(Text const * t) const;
|
||||
TextMetrics & textMetrics(Text const * t);
|
||||
@ -300,12 +308,11 @@ public:
|
||||
bool paragraphVisible(DocIterator const & dit) const;
|
||||
/// is the cursor currently visible in the view
|
||||
bool cursorInView(Point const & p, int h) const;
|
||||
/// get the position and height of the cursor
|
||||
void cursorPosAndHeight(Point & p, int & h) const;
|
||||
|
||||
/// get the position and height of the caret
|
||||
void caretPosAndHeight(Point & p, int & h) const;
|
||||
|
||||
///
|
||||
void draw(frontend::Painter & pain);
|
||||
void draw(frontend::Painter & pain, bool paint_caret);
|
||||
|
||||
/// get this view's keyboard map handler.
|
||||
Intl & getIntl();
|
||||
@ -361,13 +368,15 @@ private:
|
||||
/// Update current paragraph metrics.
|
||||
/// \return true if no further update is needed.
|
||||
bool singleParUpdate();
|
||||
/// do the work for the public updateMetrics()
|
||||
void updateMetrics(Update::flags & update_flags);
|
||||
|
||||
// Set the row on which the cursor lives.
|
||||
void setCurrentRowSlice(CursorSlice const & rowSlice);
|
||||
|
||||
// Check whether the row where the cursor lives needs to be scrolled.
|
||||
// Update the drawing strategy if needed.
|
||||
void checkCursorScrollOffset(PainterInfo & pi);
|
||||
void checkCursorScrollOffset();
|
||||
|
||||
/// The minimal size of the document that is visible. Used
|
||||
/// when it is allowed to scroll below the document.
|
||||
|
@ -136,6 +136,8 @@ void Converter::readFlags()
|
||||
nice_ = true;
|
||||
else if (flag_name == "needauth")
|
||||
need_auth_ = true;
|
||||
else if (flag_name == "hyperref-driver")
|
||||
href_driver_ = flag_value;
|
||||
}
|
||||
if (!result_dir_.empty() && result_file_.empty())
|
||||
result_file_ = "index." + theFormats().extension(to_);
|
||||
@ -283,6 +285,18 @@ OutputParams::FLAVOR Converters::getFlavor(Graph::EdgePath const & path,
|
||||
}
|
||||
|
||||
|
||||
string Converters::getHyperrefDriver(Graph::EdgePath const & path)
|
||||
{
|
||||
for (Graph::EdgePath::const_iterator cit = path.begin();
|
||||
cit != path.end(); ++cit) {
|
||||
Converter const & conv = converterlist_[*cit];
|
||||
if (!conv.hyperref_driver().empty())
|
||||
return conv.hyperref_driver();
|
||||
}
|
||||
return string();
|
||||
}
|
||||
|
||||
|
||||
bool Converters::checkAuth(Converter const & conv, string const & doc_fname,
|
||||
bool use_shell_escape)
|
||||
{
|
||||
|
@ -79,6 +79,8 @@ public:
|
||||
std::string const result_file() const { return result_file_; }
|
||||
///
|
||||
std::string const parselog() const { return parselog_; }
|
||||
///
|
||||
std::string const hyperref_driver() const { return href_driver_; }
|
||||
|
||||
private:
|
||||
///
|
||||
@ -114,6 +116,8 @@ private:
|
||||
trivstring result_file_;
|
||||
/// Command to convert the program output to a LaTeX log file format
|
||||
trivstring parselog_;
|
||||
/// The hyperref driver
|
||||
trivstring href_driver_;
|
||||
};
|
||||
|
||||
|
||||
@ -159,6 +163,8 @@ public:
|
||||
///
|
||||
OutputParams::FLAVOR getFlavor(Graph::EdgePath const & path,
|
||||
Buffer const * buffer = 0);
|
||||
///
|
||||
std::string getHyperrefDriver(Graph::EdgePath const & path);
|
||||
/// Flags for converting files
|
||||
enum ConversionFlags {
|
||||
/// No special flags
|
||||
|
@ -453,19 +453,6 @@ int Cursor::currentMode()
|
||||
}
|
||||
|
||||
|
||||
bool Cursor::inCoordCache() const
|
||||
{
|
||||
// the root inset is not in cache, but we do not need it.
|
||||
if (depth() == 1)
|
||||
return true;
|
||||
CoordCache::Insets const & icache = bv_->coordCache().getInsets();
|
||||
for (size_t i = 1 ; i < depth() ; ++i)
|
||||
if (!icache.has(&(*this)[i].inset()))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void Cursor::getPos(int & x, int & y) const
|
||||
{
|
||||
Point p = bv().getPos(*this);
|
||||
|
@ -215,8 +215,6 @@ public:
|
||||
/// are we entering a macro name?
|
||||
bool & macromode() { return macromode_; }
|
||||
|
||||
/// returns true when all insets in cursor stack are in cache
|
||||
bool inCoordCache() const;
|
||||
/// returns x,y position
|
||||
void getPos(int & x, int & y) const;
|
||||
/// return logical positions between which the cursor is situated
|
||||
|
@ -40,6 +40,7 @@
|
||||
|
||||
#include "insets/InsetBibitem.h"
|
||||
#include "insets/InsetBranch.h"
|
||||
#include "insets/InsetCitation.h"
|
||||
#include "insets/InsetCommand.h"
|
||||
#include "insets/InsetFlex.h"
|
||||
#include "insets/InsetGraphics.h"
|
||||
@ -360,6 +361,16 @@ pasteSelectionHelper(DocIterator const & cur, ParagraphList const & parlist,
|
||||
break;
|
||||
}
|
||||
|
||||
case CITE_CODE: {
|
||||
InsetCitation & cit = static_cast<InsetCitation &>(*it);
|
||||
// This actually only needs to be done if the cite engine
|
||||
// differs, but we do it in general.
|
||||
cit.redoLabel();
|
||||
// We need to update the list of citations.
|
||||
need_update = true;
|
||||
break;
|
||||
}
|
||||
|
||||
case BIBITEM_CODE: {
|
||||
// check for duplicates
|
||||
InsetBibitem & bib = static_cast<InsetBibitem &>(*it);
|
||||
|
16
src/Font.cpp
16
src/Font.cpp
@ -349,9 +349,11 @@ int Font::latexWriteStartChanges(odocstream & os, BufferParams const & bparams,
|
||||
|
||||
// If the current language is Hebrew, Arabic, or Farsi
|
||||
// the numbers are written Left-to-Right. ArabTeX package
|
||||
// reorders the number automatically but the packages used
|
||||
// for Hebrew and Farsi (Arabi) do not.
|
||||
if (!runparams.pass_thru && bits_.number() == FONT_ON
|
||||
// and bidi (polyglossia) reorder the number automatically
|
||||
// but the packages used for Hebrew and Farsi (Arabi) do not.
|
||||
if (!runparams.use_polyglossia
|
||||
&& !runparams.pass_thru
|
||||
&& bits_.number() == FONT_ON
|
||||
&& prev.fontInfo().number() != FONT_ON
|
||||
&& (language()->lang() == "hebrew"
|
||||
|| language()->lang() == "farsi"
|
||||
@ -552,9 +554,11 @@ int Font::latexWriteEndChanges(otexstream & os, BufferParams const & bparams,
|
||||
|
||||
// If the current language is Hebrew, Arabic, or Farsi
|
||||
// the numbers are written Left-to-Right. ArabTeX package
|
||||
// reorders the number automatically but the packages used
|
||||
// for Hebrew and Farsi (Arabi) do not.
|
||||
if (!runparams.pass_thru && bits_.number() == FONT_ON
|
||||
// and bidi (polyglossia) reorder the number automatically
|
||||
// but the packages used for Hebrew and Farsi (Arabi) do not.
|
||||
if (!runparams.use_polyglossia
|
||||
&& !runparams.pass_thru
|
||||
&& bits_.number() == FONT_ON
|
||||
&& next.fontInfo().number() != FONT_ON
|
||||
&& (language()->lang() == "hebrew"
|
||||
|| language()->lang() == "farsi"
|
||||
|
@ -474,6 +474,10 @@ enum FuncCode
|
||||
LFUN_TOOLBAR_MOVABLE, // daniel, 20160712
|
||||
LFUN_FONT_CROSSOUT, // uwestoehr 20170404
|
||||
LFUN_DEVEL_MODE_TOGGLE, // lasgouttes 20170723
|
||||
//370
|
||||
LFUN_EXPORT_CANCEL, // rgh, 20171227
|
||||
LFUN_BUFFER_ANONYMIZE, // sanda, 20180201
|
||||
LFUN_GRAPHICS_UNIFY, // sanda, 20180207
|
||||
LFUN_LASTACTION // end of the table
|
||||
};
|
||||
|
||||
|
@ -356,7 +356,11 @@ SpellChecker::Result HunspellChecker::check(WordLangTuple const & wl)
|
||||
|
||||
LYXERR(Debug::GUI, "spellCheck: \"" <<
|
||||
wl.word() << "\", lang = " << wl.lang()->lang()) ;
|
||||
#ifdef HAVE_HUNSPELL_CXXABI
|
||||
if (h->spell(word_to_check, &info))
|
||||
#else
|
||||
if (h->spell(word_to_check.c_str(), &info))
|
||||
#endif
|
||||
return d->learned(wl) ? LEARNED_WORD : WORD_OK;
|
||||
|
||||
if (info & SPELL_COMPOUND) {
|
||||
@ -411,6 +415,11 @@ void HunspellChecker::suggest(WordLangTuple const & wl,
|
||||
return;
|
||||
string const encoding = h->get_dic_encoding();
|
||||
string const word_to_check = to_iconv_encoding(wl.word(), encoding);
|
||||
#ifdef HAVE_HUNSPELL_CXXABI
|
||||
vector<string> wlst = h->suggest(word_to_check);
|
||||
for (auto const s : wlst)
|
||||
suggestions.push_back(from_iconv_encoding(s, encoding));
|
||||
#else
|
||||
char ** suggestion_list;
|
||||
int const suggestion_number = h->suggest(&suggestion_list, word_to_check.c_str());
|
||||
if (suggestion_number <= 0)
|
||||
@ -418,6 +427,7 @@ void HunspellChecker::suggest(WordLangTuple const & wl,
|
||||
for (int i = 0; i != suggestion_number; ++i)
|
||||
suggestions.push_back(from_iconv_encoding(suggestion_list[i], encoding));
|
||||
h->free_list(&suggestion_list, suggestion_number);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@ -430,6 +440,11 @@ void HunspellChecker::stem(WordLangTuple const & wl,
|
||||
return;
|
||||
string const encoding = h->get_dic_encoding();
|
||||
string const word_to_check = to_iconv_encoding(wl.word(), encoding);
|
||||
#ifdef HAVE_HUNSPELL_CXXABI
|
||||
vector<string> wlst = h->stem(word_to_check);
|
||||
for (auto const s : wlst)
|
||||
suggestions.push_back(from_iconv_encoding(s, encoding));
|
||||
#else
|
||||
char ** suggestion_list;
|
||||
int const suggestion_number = h->stem(&suggestion_list, word_to_check.c_str());
|
||||
if (suggestion_number <= 0)
|
||||
@ -437,6 +452,7 @@ void HunspellChecker::stem(WordLangTuple const & wl,
|
||||
for (int i = 0; i != suggestion_number; ++i)
|
||||
suggestions.push_back(from_iconv_encoding(suggestion_list[i], encoding));
|
||||
h->free_list(&suggestion_list, suggestion_number);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
@ -120,7 +120,7 @@ enum LayoutTags {
|
||||
/////////////////////
|
||||
|
||||
Layout::Layout()
|
||||
: add_to_toc_(false), is_toc_caption_(false)
|
||||
: add_to_toc_(false), is_toc_caption_(true)
|
||||
{
|
||||
unknown_ = false;
|
||||
margintype = MARGIN_STATIC;
|
||||
|
@ -1950,8 +1950,10 @@ void LyXAction::init()
|
||||
/*!
|
||||
* \var lyx::FuncCode lyx::LFUN_INSET_BEGIN
|
||||
* \li Action: Move the cursor to the beginning of the current inset
|
||||
if it is not already there, or at the beginning of the
|
||||
enclosing inset otherwise
|
||||
if it is not already there. If the cursor is already at
|
||||
the beginning of the current inset, move it to the
|
||||
beginning of the enclosing inset or the main work area,
|
||||
respectively, if there is no enclosing inset.
|
||||
* \li Syntax: inset-begin
|
||||
* \li Origin: lasgouttes, 16 Mar 2009
|
||||
* \endvar
|
||||
@ -1961,8 +1963,10 @@ void LyXAction::init()
|
||||
/*!
|
||||
* \var lyx::FuncCode lyx::LFUN_INSET_BEGIN_SELECT
|
||||
* \li Action: Move the cursor to the beginning of the current inset
|
||||
if it is not already there, or at the beginning of the
|
||||
enclosing inset otherwise (adding the
|
||||
if it is not already there. If the cursor is already at
|
||||
the beginning of the current inset, move it to the
|
||||
beginning of the enclosing inset or the main work area,
|
||||
respectively, if there is no enclosing inset (adding the
|
||||
traversed text to the selection).
|
||||
* \li Syntax: inset-begin-select
|
||||
* \li Origin: lasgouttes, 16 Mar 2009
|
||||
@ -2021,9 +2025,11 @@ void LyXAction::init()
|
||||
|
||||
/*!
|
||||
* \var lyx::FuncCode lyx::LFUN_INSET_END
|
||||
* \li Action: Move the cursor to the end of the current inset
|
||||
if it is not already there, or at the end of the
|
||||
enclosing inset otherwise
|
||||
* \li Action: Move the cursor to the end of the current inset if it
|
||||
is not already there. If the cursor is already at the
|
||||
end of the current inset, move it to the end of the
|
||||
enclosing inset or the main work area, respectively, if
|
||||
there is no enclosing inset.
|
||||
* \li Syntax: inset-end
|
||||
* \li Origin: lasgouttes, 16 Mar 2009
|
||||
* \endvar
|
||||
@ -2032,9 +2038,11 @@ void LyXAction::init()
|
||||
|
||||
/*!
|
||||
* \var lyx::FuncCode lyx::LFUN_INSET_END_SELECT
|
||||
* \li Action: Move the cursor to the end of the current inset
|
||||
if it is not already there, or at the end of the
|
||||
enclosing inset otherwise (adding the
|
||||
* \li Action: Move the cursor to the end of the current inset if it
|
||||
is not already there. If the cursor is already at the
|
||||
end of the current inset, move it to the end of the
|
||||
enclosing inset or the main work area, respectively, if
|
||||
there is no enclosing inset (adding the
|
||||
traversed text to the selection).
|
||||
* \li Syntax: inset-end-select
|
||||
* \li Origin: lasgouttes, 16 Mar 2009
|
||||
@ -3545,6 +3553,17 @@ void LyXAction::init()
|
||||
*/
|
||||
{ LFUN_SET_GRAPHICS_GROUP, "set-graphics-group", Noop, Edit },
|
||||
|
||||
/*!
|
||||
* \var lyx::FuncCode lyx::LFUN_GRAPHICS_UNIFY
|
||||
* \li Action: Set the same group for all graphics insets in the marked block.
|
||||
* \li Syntax: graphics-unify [<GROUP>]
|
||||
* \li Params: <GROUP>: Id for an existing group. In case the Id is an empty string,
|
||||
the group Id from the first graphics inset will be used.
|
||||
* \li Origin: sanda, 7 Feb 2018
|
||||
* \endvar
|
||||
*/
|
||||
{ LFUN_GRAPHICS_UNIFY, "graphics-unify", Noop, Edit },
|
||||
|
||||
|
||||
/*!
|
||||
* \var lyx::FuncCode lyx::LFUN_SPACE_INSERT
|
||||
@ -4209,6 +4228,16 @@ void LyXAction::init()
|
||||
*/
|
||||
{ LFUN_WORD_REPLACE, "word-replace", Noop, Edit },
|
||||
|
||||
/*!
|
||||
* \var lyx::FuncCode lyx::LFUN_BUFFER_ANONYMIZE
|
||||
* \li Action: For debug purposes only. Convert all [a-zA-Z0-1] characters to
|
||||
single character. Useful when submitting docs to list or bugzilla.
|
||||
* \li Syntax: buffer-anonymize
|
||||
* \li Origin: sanda, Feb 1 2018
|
||||
* \endvar
|
||||
*/
|
||||
{ LFUN_BUFFER_ANONYMIZE, "buffer-anonymize", Noop, Edit },
|
||||
|
||||
/*!
|
||||
* \var lyx::FuncCode lyx::LFUN_WORD_RIGHT
|
||||
* \li Action: Moves the cursor to the next beginning of a word "on the right".
|
||||
|
@ -195,6 +195,7 @@ LexerKeyword lyxrcTags[] = {
|
||||
{ "\\use_converter_needauth", LyXRC::RC_USE_CONVERTER_NEEDAUTH },
|
||||
{ "\\use_converter_needauth_forbidden", LyXRC::RC_USE_CONVERTER_NEEDAUTH_FORBIDDEN },
|
||||
{ "\\use_lastfilepos", LyXRC::RC_USELASTFILEPOS },
|
||||
{ "\\use_native_filedialog", LyXRC::RC_USE_NATIVE_FILEDIALOG },
|
||||
{ "\\use_pixmap_cache", LyXRC::RC_USE_PIXMAP_CACHE },
|
||||
{ "\\use_qimage", LyXRC::RC_USE_QIMAGE },
|
||||
// compatibility with versions older than 1.4.0 only
|
||||
@ -273,6 +274,7 @@ void LyXRC::setDefaults()
|
||||
num_lastfiles = 20;
|
||||
check_lastfiles = true;
|
||||
use_lastfilepos = true;
|
||||
use_native_filedialog = true;
|
||||
load_session = false;
|
||||
make_backup = true;
|
||||
save_compressed = false;
|
||||
@ -875,6 +877,9 @@ LyXRC::ReturnValues LyXRC::read(Lexer & lexrc, bool check_format)
|
||||
case RC_ACCEPT_COMPOUND:
|
||||
lexrc >> spellchecker_accept_compound;
|
||||
break;
|
||||
case RC_USE_NATIVE_FILEDIALOG:
|
||||
lexrc >> use_native_filedialog;
|
||||
break;
|
||||
case RC_USE_SYSTEM_COLORS:
|
||||
lexrc >> use_system_colors;
|
||||
break;
|
||||
@ -2412,6 +2417,16 @@ void LyXRC::write(ostream & os, bool ignore_system_lyxrc, string const & name) c
|
||||
if (tag != RC_LAST)
|
||||
break;
|
||||
// fall through
|
||||
case RC_USE_NATIVE_FILEDIALOG:
|
||||
if (ignore_system_lyxrc ||
|
||||
use_native_filedialog != system_lyxrc.use_native_filedialog) {
|
||||
os << "\\use_native_filedialog "
|
||||
<< convert<string>(use_native_filedialog)
|
||||
<< '\n';
|
||||
}
|
||||
if (tag != RC_LAST)
|
||||
break;
|
||||
// fall through
|
||||
case RC_USE_SYSTEM_COLORS:
|
||||
if (ignore_system_lyxrc ||
|
||||
use_system_colors != system_lyxrc.use_system_colors) {
|
||||
@ -3031,6 +3046,7 @@ void actOnUpdatedPrefs(LyXRC const & lyxrc_orig, LyXRC const & lyxrc_new)
|
||||
case LyXRC::RC_USE_CONVERTER_CACHE:
|
||||
case LyXRC::RC_USE_CONVERTER_NEEDAUTH_FORBIDDEN:
|
||||
case LyXRC::RC_USE_CONVERTER_NEEDAUTH:
|
||||
case LyXRC::RC_USE_NATIVE_FILEDIALOG:
|
||||
case LyXRC::RC_USE_SYSTEM_COLORS:
|
||||
case LyXRC::RC_USE_TOOLTIP:
|
||||
case LyXRC::RC_USE_PIXMAP_CACHE:
|
||||
|
@ -172,6 +172,7 @@ public:
|
||||
RC_USE_CONVERTER_CACHE,
|
||||
RC_USE_CONVERTER_NEEDAUTH_FORBIDDEN,
|
||||
RC_USE_CONVERTER_NEEDAUTH,
|
||||
RC_USE_NATIVE_FILEDIALOG,
|
||||
RC_USE_SYSTEM_COLORS,
|
||||
RC_USE_TOOLTIP,
|
||||
RC_USE_PIXMAP_CACHE,
|
||||
@ -333,6 +334,8 @@ public:
|
||||
bool use_tooltip;
|
||||
/// Use the colors from current system theme?
|
||||
bool use_system_colors;
|
||||
/// use native file dialog or our own ?
|
||||
bool use_native_filedialog;
|
||||
/// Use pixmap cache?
|
||||
bool use_pixmap_cache;
|
||||
/// Use QImage backend?
|
||||
|
@ -130,7 +130,7 @@ public:
|
||||
bool selected;
|
||||
/// Whether the spell checker is enabled for the parent
|
||||
bool do_spellcheck;
|
||||
///
|
||||
/// True when it can be assumed that the screen has been cleared
|
||||
bool full_repaint;
|
||||
/// Current background color
|
||||
ColorCode background_color;
|
||||
|
@ -172,6 +172,10 @@ public:
|
||||
*/
|
||||
std::string index_command;
|
||||
|
||||
/** Hyperref driver
|
||||
*/
|
||||
std::string hyperref_driver;
|
||||
|
||||
/** Line length to use with plaintext or LaTeX export.
|
||||
*/
|
||||
size_type linelen;
|
||||
|
@ -97,6 +97,10 @@ void PDFOptions::writeLaTeX(OutputParams & runparams, otexstream & os,
|
||||
string opt;
|
||||
string hyperset;
|
||||
|
||||
// Driver needed by specific converters
|
||||
if (!runparams.hyperref_driver.empty())
|
||||
opt += runparams.hyperref_driver + ",";
|
||||
|
||||
// since LyX uses unicode, also set the PDF strings to unicode strings with the
|
||||
// hyperref option "unicode"
|
||||
opt += "unicode=true,";
|
||||
|
@ -1437,43 +1437,18 @@ bool Paragraph::Private::latexSpecialT3(char_type const c, otexstream & os,
|
||||
void Paragraph::Private::validate(LaTeXFeatures & features) const
|
||||
{
|
||||
if (layout_->inpreamble && inset_owner_) {
|
||||
bool const is_command = layout_->latextype == LATEX_COMMAND;
|
||||
Font f;
|
||||
// Using a string stream here circumvents the encoding
|
||||
// FIXME: Using a string stream here circumvents the encoding
|
||||
// switching machinery of odocstream. Therefore the
|
||||
// output is wrong if this paragraph contains content
|
||||
// that needs to switch encoding.
|
||||
Buffer const & buf = inset_owner_->buffer();
|
||||
BufferParams const & bp = features.runparams().is_child
|
||||
? buf.masterParams() : buf.params();
|
||||
otexstringstream os;
|
||||
os << layout_->preamble();
|
||||
if (is_command) {
|
||||
os << '\\' << from_ascii(layout_->latexname());
|
||||
// we have to provide all the optional arguments here, even though
|
||||
// the last one is the only one we care about.
|
||||
// Separate handling of optional argument inset.
|
||||
if (!layout_->latexargs().empty()) {
|
||||
OutputParams rp = features.runparams();
|
||||
rp.local_font = &owner_->getFirstFontSettings(bp);
|
||||
latexArgInsets(*owner_, os, rp, layout_->latexargs());
|
||||
}
|
||||
os << from_ascii(layout_->latexparam());
|
||||
}
|
||||
size_t const length = os.length();
|
||||
// this will output "{" at the beginning, but not at the end
|
||||
owner_->latex(bp, f, os, features.runparams(), 0, -1, true);
|
||||
if (os.length() > length) {
|
||||
if (is_command) {
|
||||
os << '}';
|
||||
if (!layout_->postcommandargs().empty()) {
|
||||
OutputParams rp = features.runparams();
|
||||
rp.local_font = &owner_->getFirstFontSettings(bp);
|
||||
latexArgInsets(*owner_, os, rp, layout_->postcommandargs(), "post:");
|
||||
}
|
||||
}
|
||||
TeXOnePar(buf, buf.text(), buf.getParFromID(owner_->id()).pit(), os,
|
||||
features.runparams(), string(), 0, -1, true);
|
||||
if (os.length() > length)
|
||||
features.addPreambleSnippet(os.release(), true);
|
||||
}
|
||||
}
|
||||
|
||||
if (features.runparams().flavor == OutputParams::HTML
|
||||
@ -2426,7 +2401,9 @@ void Paragraph::latex(BufferParams const & bparams,
|
||||
|
||||
// if the paragraph is empty, the loop will not be entered at all
|
||||
if (empty()) {
|
||||
if (style.isCommand()) {
|
||||
// For InTitle commands, we have already opened a group
|
||||
// in output_latex::TeXOnePar.
|
||||
if (style.isCommand() && !style.intitle) {
|
||||
os << '{';
|
||||
++column;
|
||||
}
|
||||
@ -2464,7 +2441,9 @@ void Paragraph::latex(BufferParams const & bparams,
|
||||
os << "}] ";
|
||||
column +=3;
|
||||
}
|
||||
if (style.isCommand()) {
|
||||
// For InTitle commands, we have already opened a group
|
||||
// in output_latex::TeXOnePar.
|
||||
if (style.isCommand() && !style.intitle) {
|
||||
os << '{';
|
||||
++column;
|
||||
}
|
||||
@ -3531,6 +3510,8 @@ void Paragraph::forOutliner(docstring & os, size_t const maxlen,
|
||||
size_t tmplen = shorten ? maxlen + 1 : maxlen;
|
||||
if (label && !labelString().empty())
|
||||
os += labelString() + ' ';
|
||||
if (!layout().isTocCaption())
|
||||
return;
|
||||
for (pos_type i = 0; i < size() && os.length() < tmplen; ++i) {
|
||||
if (isDeleted(i))
|
||||
continue;
|
||||
@ -4176,6 +4157,15 @@ SpellChecker::Result Paragraph::spellCheck(pos_type & from, pos_type & to,
|
||||
}
|
||||
|
||||
|
||||
void Paragraph::anonymize()
|
||||
{
|
||||
// This is a very crude anonymization for now
|
||||
for (char_type & c : d->text_)
|
||||
if (isLetterChar(c) || isNumber(c))
|
||||
c = 'a';
|
||||
}
|
||||
|
||||
|
||||
void Paragraph::Private::markMisspelledWords(
|
||||
pos_type const & first, pos_type const & last,
|
||||
SpellChecker::Result result,
|
||||
|
@ -505,6 +505,10 @@ public:
|
||||
/// presently used only in the XHTML output routines.
|
||||
std::string magicLabel() const;
|
||||
|
||||
/// anonymizes the paragraph contents (but not the paragraphs
|
||||
/// contained inside it. Does not handle undo.
|
||||
void anonymize();
|
||||
|
||||
private:
|
||||
/// Expand the counters for the labelstring of \c layout
|
||||
docstring expandParagraphLabel(Layout const &, BufferParams const &,
|
||||
|
@ -47,8 +47,6 @@
|
||||
#include "support/lstrings.h"
|
||||
#include "support/textutils.h"
|
||||
|
||||
#include <boost/crc.hpp>
|
||||
|
||||
#include <algorithm>
|
||||
#include <list>
|
||||
#include <stack>
|
||||
@ -84,42 +82,6 @@ void ParagraphMetrics::reset(Paragraph const & par)
|
||||
}
|
||||
|
||||
|
||||
size_t ParagraphMetrics::computeRowSignature(Row const & row,
|
||||
BufferView const & bv) const
|
||||
{
|
||||
boost::crc_32_type crc;
|
||||
for (pos_type i = row.pos(); i < row.endpos(); ++i) {
|
||||
if (par_->isInset(i)) {
|
||||
Inset const * in = par_->getInset(i);
|
||||
Dimension const d = in->dimension(bv);
|
||||
int const b[] = { d.wid, d.asc, d.des };
|
||||
crc.process_bytes(b, sizeof(b));
|
||||
} else {
|
||||
char_type const b[] = { par_->getChar(i) };
|
||||
crc.process_bytes(b, sizeof(char_type));
|
||||
}
|
||||
if (bv.buffer().params().track_changes) {
|
||||
Change change = par_->lookupChange(i);
|
||||
char_type const b[] = { static_cast<char_type>(change.type) };
|
||||
// 1 byte is enough to encode Change::Type
|
||||
crc.process_bytes(b, 1);
|
||||
}
|
||||
}
|
||||
|
||||
pos_type const b1[] = { row.sel_beg, row.sel_end };
|
||||
crc.process_bytes(b1, sizeof(b1));
|
||||
|
||||
Dimension const & d = row.dimension();
|
||||
int const b2[] = { row.begin_margin_sel,
|
||||
row.end_margin_sel,
|
||||
d.wid, d.asc, d.des };
|
||||
crc.process_bytes(b2, sizeof(b2));
|
||||
crc.process_bytes(&row.separator, sizeof(row.separator));
|
||||
|
||||
return crc.checksum();
|
||||
}
|
||||
|
||||
|
||||
void ParagraphMetrics::setPosition(int position)
|
||||
{
|
||||
position_ = position;
|
||||
|
@ -85,9 +85,6 @@ public:
|
||||
///
|
||||
bool hfillExpansion(Row const & row, pos_type pos) const;
|
||||
|
||||
///
|
||||
size_t computeRowSignature(Row const &, BufferView const & bv) const;
|
||||
|
||||
///
|
||||
int position() const { return position_; }
|
||||
void setPosition(int position);
|
||||
|
30
src/Row.cpp
30
src/Row.cpp
@ -162,19 +162,13 @@ Row::Row()
|
||||
: separator(0), label_hfill(0), left_margin(0), right_margin(0),
|
||||
sel_beg(-1), sel_end(-1),
|
||||
begin_margin_sel(false), end_margin_sel(false),
|
||||
changed_(false), crc_(0),
|
||||
changed_(true),
|
||||
pit_(0), pos_(0), end_(0),
|
||||
right_boundary_(false), flushed_(false), rtl_(false)
|
||||
right_boundary_(false), flushed_(false), rtl_(false),
|
||||
changebar_(false)
|
||||
{}
|
||||
|
||||
|
||||
void Row::setCrc(size_type crc) const
|
||||
{
|
||||
changed_ = crc != crc_;
|
||||
crc_ = crc;
|
||||
}
|
||||
|
||||
|
||||
bool Row::isMarginSelected(bool left_margin, DocIterator const & beg,
|
||||
DocIterator const & end) const
|
||||
{
|
||||
@ -209,8 +203,8 @@ void Row::setSelectionAndMargins(DocIterator const & beg,
|
||||
setSelection(beg.pos(), end.pos());
|
||||
|
||||
if (selection()) {
|
||||
end_margin_sel = isMarginSelected(false, beg, end);
|
||||
begin_margin_sel = isMarginSelected(true, beg, end);
|
||||
change(end_margin_sel, isMarginSelected(false, beg, end));
|
||||
change(begin_margin_sel, isMarginSelected(true, beg, end));
|
||||
}
|
||||
}
|
||||
|
||||
@ -218,18 +212,18 @@ void Row::setSelectionAndMargins(DocIterator const & beg,
|
||||
void Row::setSelection(pos_type beg, pos_type end) const
|
||||
{
|
||||
if (pos_ >= beg && pos_ <= end)
|
||||
sel_beg = pos_;
|
||||
change(sel_beg, pos_);
|
||||
else if (beg > pos_ && beg <= end_)
|
||||
sel_beg = beg;
|
||||
change(sel_beg, beg);
|
||||
else
|
||||
sel_beg = -1;
|
||||
change(sel_beg, -1);
|
||||
|
||||
if (end_ >= beg && end_ <= end)
|
||||
sel_end = end_;
|
||||
change(sel_end,end_);
|
||||
else if (end < end_ && end >= pos_)
|
||||
sel_end = end;
|
||||
change(sel_end, end);
|
||||
else
|
||||
sel_end = -1;
|
||||
change(sel_end, -1);
|
||||
}
|
||||
|
||||
|
||||
@ -371,6 +365,8 @@ void Row::finalizeLast()
|
||||
if (elt.final)
|
||||
return;
|
||||
elt.final = true;
|
||||
if (elt.change.changed())
|
||||
changebar_ = true;
|
||||
|
||||
if (elt.type == STRING) {
|
||||
dim_.wid -= elt.dim.wid;
|
||||
|
36
src/Row.h
36
src/Row.h
@ -136,12 +136,33 @@ public:
|
||||
|
||||
///
|
||||
Row();
|
||||
/**
|
||||
* Helper function: set variable \c var to value \c val, and mark
|
||||
* row as changed is the values were different. This is intended
|
||||
* for use when changing members of the row object.
|
||||
*/
|
||||
template<class T1, class T2>
|
||||
void change(T1 & var, T2 const val) {
|
||||
if (var != val)
|
||||
changed(true);
|
||||
var = val;
|
||||
}
|
||||
/**
|
||||
* Helper function: set variable \c var to value \c val, and mark
|
||||
* row as changed is the values were different. This is intended
|
||||
* for use when changing members of the row object.
|
||||
* This is the const version, useful for mutable members.
|
||||
*/
|
||||
template<class T1, class T2>
|
||||
void change(T1 & var, T2 const val) const {
|
||||
if (var != val)
|
||||
changed(true);
|
||||
var = val;
|
||||
}
|
||||
///
|
||||
bool changed() const { return changed_; }
|
||||
///
|
||||
void setChanged(bool c) { changed_ = c; }
|
||||
///
|
||||
void setCrc(size_type crc) const;
|
||||
void changed(bool c) const { changed_ = c; }
|
||||
/// Set the selection begin and end.
|
||||
/**
|
||||
* This is const because we update the selection status only at draw()
|
||||
@ -266,6 +287,11 @@ public:
|
||||
void reverseRTL(bool rtl_par);
|
||||
///
|
||||
bool isRTL() const { return rtl_; }
|
||||
///
|
||||
bool needsChangeBar() const { return changebar_; }
|
||||
///
|
||||
void needsChangeBar(bool ncb) { changebar_ = ncb; }
|
||||
|
||||
/// Find row element that contains \c pos, and compute x offset.
|
||||
const_iterator const findElement(pos_type pos, bool boundary, double & x) const;
|
||||
|
||||
@ -310,8 +336,6 @@ private:
|
||||
|
||||
/// has the Row appearance changed since last drawing?
|
||||
mutable bool changed_;
|
||||
/// CRC of row contents.
|
||||
mutable size_type crc_;
|
||||
/// Index of the paragraph that contains this row
|
||||
pit_type pit_;
|
||||
/// first pos covered by this row
|
||||
@ -326,6 +350,8 @@ private:
|
||||
Dimension dim_;
|
||||
/// true when this row lives in a right-to-left paragraph
|
||||
bool rtl_;
|
||||
/// true when a changebar should be drawn in the margin
|
||||
bool changebar_;
|
||||
};
|
||||
|
||||
|
||||
|
@ -247,18 +247,6 @@ void RowPainter::paintChange(Row::Element const & e) const
|
||||
|
||||
void RowPainter::paintChangeBar() const
|
||||
{
|
||||
pos_type const start = row_.pos();
|
||||
pos_type end = row_.endpos();
|
||||
|
||||
if (par_.size() == end) {
|
||||
// this is the last row of the paragraph;
|
||||
// thus, we must also consider the imaginary end-of-par character
|
||||
end++;
|
||||
}
|
||||
|
||||
if (start == end || !par_.isChanged(start, end))
|
||||
return;
|
||||
|
||||
int const height = tm_.isLastRow(row_)
|
||||
? row_.ascent()
|
||||
: row_.height();
|
||||
@ -576,7 +564,7 @@ void RowPainter::paintText()
|
||||
paintStringAndSel(e);
|
||||
|
||||
// Paint the spelling marks if enabled.
|
||||
if (lyxrc.spellcheck_continuously && pi_.do_spellcheck && pi_.pain.isDrawingEnabled())
|
||||
if (lyxrc.spellcheck_continuously && pi_.do_spellcheck && !pi_.pain.isNull())
|
||||
paintMisspelledMark(e);
|
||||
break;
|
||||
|
||||
|
@ -99,6 +99,18 @@ string envName(Spacing::Space space, bool useSetSpace)
|
||||
return useSetSpace ? name : support::ascii_lowercase(name);
|
||||
}
|
||||
|
||||
string cmdName(Spacing::Space space, bool useSetSpace)
|
||||
{
|
||||
static char const * const cmd_names[]
|
||||
= { "SingleSpacing", "OnehalfSpacing", "DoubleSpacing", "SetStretch", ""};
|
||||
string const name = cmd_names[space];
|
||||
|
||||
if (useSetSpace && name == "SetStretch")
|
||||
return "setSpacing";
|
||||
|
||||
return useSetSpace ? name : support::ascii_lowercase(name);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
string const Spacing::writeEnvirBegin(bool useSetSpace) const
|
||||
@ -118,6 +130,16 @@ string const Spacing::writeEnvirEnd(bool useSetSpace) const
|
||||
}
|
||||
|
||||
|
||||
string const Spacing::writeCmd(bool useSetSpace) const
|
||||
{
|
||||
string const name = cmdName(space, useSetSpace);
|
||||
if (space == Other)
|
||||
return "\\" + name + "{" + getValueAsString() + '}';
|
||||
else
|
||||
return name.empty() ? string() : "\\" + name + "{}";
|
||||
}
|
||||
|
||||
|
||||
string const Spacing::writePreamble(bool useSetSpace) const
|
||||
{
|
||||
string preamble;
|
||||
|
@ -62,6 +62,9 @@ public:
|
||||
std::string const writeEnvirEnd(bool useSetSpace) const;
|
||||
/// useSetSpace is true when using the variant supported by
|
||||
/// the memoir class.
|
||||
std::string const writeCmd(bool useSetSpace) const;
|
||||
/// useSetSpace is true when using the variant supported by
|
||||
/// the memoir class.
|
||||
std::string const writePreamble(bool useSetSpace) const;
|
||||
|
||||
private:
|
||||
|
@ -1977,7 +1977,7 @@ docstring Text::getPossibleLabel(Cursor const & cur) const
|
||||
Layout const * layout = &(pars_[pit].layout());
|
||||
|
||||
docstring text;
|
||||
docstring par_text = pars_[pit].asString();
|
||||
docstring par_text = pars_[pit].asString(AS_STR_SKIPDELETE);
|
||||
|
||||
// The return string of math matrices might contain linebreaks
|
||||
par_text = subst(par_text, '\n', '-');
|
||||
|
@ -860,6 +860,18 @@ void Text::dispatch(Cursor & cur, FuncRequest & cmd)
|
||||
cur.upDownInText(up, needsUpdate);
|
||||
needsUpdate |= cur.beforeDispatchCursor().inMathed();
|
||||
} else {
|
||||
pos_type newpos = up ? 0 : cur.lastpos();
|
||||
if (lyxrc.mac_like_cursor_movement && cur.pos() != newpos) {
|
||||
needsUpdate |= cur.selHandle(select);
|
||||
// we do not reset the targetx of the cursor
|
||||
cur.pos() = newpos;
|
||||
needsUpdate |= bv->checkDepm(cur, bv->cursor());
|
||||
cur.updateTextTargetOffset();
|
||||
if (needsUpdate)
|
||||
cur.forceBufferUpdate();
|
||||
break;
|
||||
}
|
||||
|
||||
// if the cursor cannot be moved up or down do not remove
|
||||
// the selection right now, but wait for the next dispatch.
|
||||
if (select)
|
||||
|
@ -43,7 +43,9 @@
|
||||
|
||||
#include "frontends/FontMetrics.h"
|
||||
#include "frontends/Painter.h"
|
||||
#include "frontends/NullPainter.h"
|
||||
|
||||
#include "support/convert.h"
|
||||
#include "support/debug.h"
|
||||
#include "support/lassert.h"
|
||||
|
||||
@ -198,6 +200,14 @@ bool TextMetrics::metrics(MetricsInfo & mi, Dimension & dim, int min_width)
|
||||
}
|
||||
|
||||
|
||||
void TextMetrics::updatePosCache(pit_type pit) const
|
||||
{
|
||||
frontend::NullPainter np;
|
||||
PainterInfo pi(bv_, np);
|
||||
drawParagraph(pi, pit, origin_.x_, par_metrics_[pit].position());
|
||||
}
|
||||
|
||||
|
||||
int TextMetrics::rightMargin(ParagraphMetrics const & pm) const
|
||||
{
|
||||
return text_->isMainText() ? pm.rightMargin(*bv_) : 0;
|
||||
@ -459,7 +469,7 @@ bool TextMetrics::redoParagraph(pit_type const pit)
|
||||
row.pit(pit);
|
||||
need_new_row = breakRow(row, right_margin);
|
||||
setRowHeight(row);
|
||||
row.setChanged(false);
|
||||
row.changed(true);
|
||||
if (row_index || row.endpos() < par.size()
|
||||
|| (row.right_boundary() && par.inInset().lyxCode() != CELL_CODE)) {
|
||||
/* If there is more than one row or the row has been
|
||||
@ -955,6 +965,10 @@ bool TextMetrics::breakRow(Row & row, int const right_margin) const
|
||||
row.addVirtual(end, docstring(1, char_type(0x00B6)), f, Change());
|
||||
}
|
||||
|
||||
// Is there a end-of-paragaph change?
|
||||
if (i == end && par.lookupChange(end).changed() && !need_new_row)
|
||||
row.needsChangeBar(true);
|
||||
|
||||
// if the row is too large, try to cut at last separator. In case
|
||||
// of success, reset indication that the row was broken abruptly.
|
||||
int const next_width = max_width_ - leftMargin(row.pit(), row.endpos())
|
||||
@ -1214,6 +1228,7 @@ void TextMetrics::newParMetricsDown()
|
||||
redoParagraph(pit);
|
||||
par_metrics_[pit].setPosition(last.second.position()
|
||||
+ last.second.descent() + par_metrics_[pit].ascent());
|
||||
updatePosCache(pit);
|
||||
}
|
||||
|
||||
|
||||
@ -1228,6 +1243,7 @@ void TextMetrics::newParMetricsUp()
|
||||
redoParagraph(pit);
|
||||
par_metrics_[pit].setPosition(first.second.position()
|
||||
- first.second.ascent() - par_metrics_[pit].descent());
|
||||
updatePosCache(pit);
|
||||
}
|
||||
|
||||
// y is screen coordinate
|
||||
@ -1486,14 +1502,14 @@ int TextMetrics::cursorX(CursorSlice const & sl,
|
||||
int TextMetrics::cursorY(CursorSlice const & sl, bool boundary) const
|
||||
{
|
||||
//lyxerr << "TextMetrics::cursorY: boundary: " << boundary << endl;
|
||||
ParagraphMetrics const & pm = par_metrics_[sl.pit()];
|
||||
ParagraphMetrics const & pm = parMetrics(sl.pit());
|
||||
if (pm.rows().empty())
|
||||
return 0;
|
||||
|
||||
int h = 0;
|
||||
h -= par_metrics_[0].rows()[0].ascent();
|
||||
h -= parMetrics(0).rows()[0].ascent();
|
||||
for (pit_type pit = 0; pit < sl.pit(); ++pit) {
|
||||
h += par_metrics_[pit].height();
|
||||
h += parMetrics(pit).height();
|
||||
}
|
||||
int pos = sl.pos();
|
||||
if (pos && boundary)
|
||||
@ -1797,8 +1813,8 @@ void TextMetrics::drawParagraph(PainterInfo & pi, pit_type const pit, int const
|
||||
return;
|
||||
size_t const nrows = pm.rows().size();
|
||||
|
||||
// Use fast lane when drawing is disabled.
|
||||
if (!pi.pain.isDrawingEnabled()) {
|
||||
// Use fast lane in nodraw stage.
|
||||
if (pi.pain.isNull()) {
|
||||
for (size_t i = 0; i != nrows; ++i) {
|
||||
|
||||
Row const & row = pm.rows()[i];
|
||||
@ -1850,17 +1866,11 @@ void TextMetrics::drawParagraph(PainterInfo & pi, pit_type const pit, int const
|
||||
if (i)
|
||||
y += row.ascent();
|
||||
|
||||
RowPainter rp(pi, *text_, row, row_x, y);
|
||||
|
||||
// It is not needed to draw on screen if we are not inside.
|
||||
bool const inside = (y + row.descent() >= 0
|
||||
&& y - row.ascent() < ww);
|
||||
pi.pain.setDrawingEnabled(inside);
|
||||
if (!inside) {
|
||||
// Paint only the insets to set inset cache correctly
|
||||
// FIXME: remove paintOnlyInsets when we know that positions
|
||||
// have already been set.
|
||||
rp.paintOnlyInsets();
|
||||
// Inset positions have already been set in nodraw stage.
|
||||
y += row.descent();
|
||||
continue;
|
||||
}
|
||||
@ -1874,27 +1884,30 @@ void TextMetrics::drawParagraph(PainterInfo & pi, pit_type const pit, int const
|
||||
// whether this row is the first or last and update the margins.
|
||||
if (row.selection()) {
|
||||
if (row.sel_beg == 0)
|
||||
row.begin_margin_sel = sel_beg.pit() < pit;
|
||||
row.change(row.begin_margin_sel, sel_beg.pit() < pit);
|
||||
if (row.sel_end == sel_end_par.lastpos())
|
||||
row.end_margin_sel = sel_end.pit() > pit;
|
||||
row.change(row.end_margin_sel, sel_end.pit() > pit);
|
||||
}
|
||||
|
||||
// Row signature; has row changed since last paint?
|
||||
row.setCrc(pm.computeRowSignature(row, *bv_));
|
||||
// has row changed since last paint?
|
||||
bool row_has_changed = row.changed()
|
||||
|| bv_->hadHorizScrollOffset(text_, pit, row.pos());
|
||||
|| bv_->hadHorizScrollOffset(text_, pit, row.pos())
|
||||
|| bv_->needRepaint(text_, row);
|
||||
|
||||
// Take this opportunity to spellcheck the row contents.
|
||||
if (row_has_changed && pi.do_spellcheck && lyxrc.spellcheck_continuously) {
|
||||
text_->getPar(pit).spellCheck();
|
||||
}
|
||||
|
||||
RowPainter rp(pi, *text_, row, row_x, y);
|
||||
|
||||
// Don't paint the row if a full repaint has not been requested
|
||||
// and if it has not changed.
|
||||
if (!pi.full_repaint && !row_has_changed) {
|
||||
// Paint only the insets if the text itself is
|
||||
// unchanged.
|
||||
rp.paintOnlyInsets();
|
||||
row.changed(false);
|
||||
y += row.descent();
|
||||
continue;
|
||||
}
|
||||
@ -1905,21 +1918,28 @@ void TextMetrics::drawParagraph(PainterInfo & pi, pit_type const pit, int const
|
||||
LYXERR(Debug::PAINTING, "Clear rect@("
|
||||
<< max(row_x, 0) << ", " << y - row.ascent() << ")="
|
||||
<< width() << " x " << row.height());
|
||||
pi.pain.fillRectangle(max(row_x, 0), y - row.ascent(),
|
||||
width(), row.height(), pi.background_color);
|
||||
// FIXME: this is a hack. We know that at least this
|
||||
// amount of pixels can be cleared on right and left.
|
||||
// Doing so gets rid of caret ghosts when the cursor is at
|
||||
// the begining/end of row. However, it will not work if
|
||||
// the caret has a ridiculous width like 6. (see ticket
|
||||
// #10797)
|
||||
pi.pain.fillRectangle(max(row_x, 0) - Inset::TEXT_TO_INSET_OFFSET,
|
||||
y - row.ascent(),
|
||||
width() + 2 * Inset::TEXT_TO_INSET_OFFSET,
|
||||
row.height(), pi.background_color);
|
||||
}
|
||||
|
||||
// Instrumentation for testing row cache (see also
|
||||
// 12 lines lower):
|
||||
if (lyxerr.debugging(Debug::PAINTING)
|
||||
&& (row.selection() || pi.full_repaint || row_has_changed)) {
|
||||
string const foreword = text_->isMainText() ?
|
||||
"main text redraw " : "inset text redraw: ";
|
||||
LYXERR(Debug::PAINTING, foreword << "pit=" << pit << " row=" << i
|
||||
<< " row_selection=" << row.selection()
|
||||
<< " full_repaint=" << pi.full_repaint
|
||||
<< " row_has_changed=" << row_has_changed
|
||||
<< " drawingEnabled=" << pi.pain.isDrawingEnabled());
|
||||
&& (row.selection() || pi.full_repaint || row_has_changed)) {
|
||||
string const foreword = text_->isMainText() ? "main text redraw "
|
||||
: "inset text redraw: ";
|
||||
LYXERR0(foreword << "pit=" << pit << " row=" << i
|
||||
<< (row.selection() ? " row_selection": "")
|
||||
<< (pi.full_repaint ? " full_repaint" : "")
|
||||
<< (row_has_changed ? " row_has_changed" : ""));
|
||||
}
|
||||
|
||||
// Backup full_repaint status and force full repaint
|
||||
@ -1930,7 +1950,8 @@ void TextMetrics::drawParagraph(PainterInfo & pi, pit_type const pit, int const
|
||||
rp.paintSelection();
|
||||
rp.paintAppendix();
|
||||
rp.paintDepthBar();
|
||||
rp.paintChangeBar();
|
||||
if (row.needsChangeBar())
|
||||
rp.paintChangeBar();
|
||||
if (i == 0 && !row.isRTL())
|
||||
rp.paintFirst();
|
||||
if (i == nrows - 1 && row.isRTL())
|
||||
@ -1944,11 +1965,25 @@ void TextMetrics::drawParagraph(PainterInfo & pi, pit_type const pit, int const
|
||||
row_x + row.right_x() > bv_->workWidth());
|
||||
y += row.descent();
|
||||
|
||||
#if 0
|
||||
// This debug code shows on screen which rows are repainted.
|
||||
// FIXME: since the updates related to caret blinking restrict
|
||||
// the painter to a small rectangle, the numbers are not
|
||||
// updated when this happens. Change the code in
|
||||
// GuiWorkArea::Private::show/hideCaret if this is important.
|
||||
static int count = 0;
|
||||
++count;
|
||||
FontInfo fi(sane_font);
|
||||
fi.setSize(FONT_SIZE_TINY);
|
||||
fi.setColor(Color_red);
|
||||
pi.pain.text(row_x, y, convert<docstring>(count), fi);
|
||||
#endif
|
||||
|
||||
// Restore full_repaint status.
|
||||
pi.full_repaint = tmp;
|
||||
|
||||
row.changed(false);
|
||||
}
|
||||
// Re-enable screen drawing for future use of the painter.
|
||||
pi.pain.setDrawingEnabled(true);
|
||||
|
||||
//LYXERR(Debug::PAINTING, ".");
|
||||
}
|
||||
|
@ -62,6 +62,11 @@ public:
|
||||
///
|
||||
void newParMetricsUp();
|
||||
|
||||
/// The "nodraw" drawing stage for one single paragraph: set the
|
||||
/// positions of the insets contained this paragraph in metrics
|
||||
/// cache. Related to BufferView::updatePosCache.
|
||||
void updatePosCache(pit_type pit) const;
|
||||
|
||||
/// Gets the fully instantiated font at a given position in a paragraph
|
||||
/// Basically the same routine as Paragraph::getFont() in Paragraph.cpp.
|
||||
/// The difference is that this one is used for displaying, and thus we
|
||||
|
40
src/Undo.cpp
40
src/Undo.cpp
@ -18,6 +18,7 @@
|
||||
#include "Undo.h"
|
||||
|
||||
#include "Buffer.h"
|
||||
#include "BufferList.h"
|
||||
#include "BufferParams.h"
|
||||
#include "buffer_funcs.h"
|
||||
#include "Cursor.h"
|
||||
@ -40,6 +41,7 @@
|
||||
|
||||
#include <algorithm>
|
||||
#include <deque>
|
||||
#include <set>
|
||||
|
||||
using namespace std;
|
||||
using namespace lyx::support;
|
||||
@ -645,22 +647,32 @@ void Undo::recordUndoFullBuffer(CursorData const & cur)
|
||||
|
||||
/// UndoGroupHelper class stuff
|
||||
|
||||
/** FIXME: handle restarted groups
|
||||
* It may happen that the buffers are visited in order buffer1,
|
||||
* buffer2, buffer1. In this case, we want to have only one undo group
|
||||
* in buffer1. One solution is to replace buffer_ with a set<Buffer*>,
|
||||
* but I am not sure yet how to do it. A use case is
|
||||
* InsetLabel::updateReferences.
|
||||
*/
|
||||
class UndoGroupHelper::Impl {
|
||||
friend class UndoGroupHelper;
|
||||
set<Buffer *> buffers_;
|
||||
};
|
||||
|
||||
|
||||
UndoGroupHelper::UndoGroupHelper(Buffer * buf) : d(new UndoGroupHelper::Impl)
|
||||
{
|
||||
resetBuffer(buf);
|
||||
}
|
||||
|
||||
|
||||
UndoGroupHelper::~UndoGroupHelper()
|
||||
{
|
||||
for (Buffer * buf : d->buffers_)
|
||||
if (theBufferList().isLoaded(buf) || theBufferList().isInternal(buf))
|
||||
buf->undo().endUndoGroup();
|
||||
delete d;
|
||||
}
|
||||
|
||||
void UndoGroupHelper::resetBuffer(Buffer * buf)
|
||||
{
|
||||
if (buf == buffer_)
|
||||
return;
|
||||
if (buffer_)
|
||||
buffer_->undo().endUndoGroup();
|
||||
buffer_ = buf;
|
||||
if (buffer_)
|
||||
buffer_->undo().beginUndoGroup();
|
||||
if (buf && d->buffers_.count(buf) == 0) {
|
||||
d->buffers_.insert(buf);
|
||||
buf->undo().beginUndoGroup();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
13
src/Undo.h
13
src/Undo.h
@ -135,15 +135,9 @@ private:
|
||||
*/
|
||||
class UndoGroupHelper {
|
||||
public:
|
||||
UndoGroupHelper(Buffer * buf = 0) : buffer_(0)
|
||||
{
|
||||
resetBuffer(buf);
|
||||
}
|
||||
UndoGroupHelper(Buffer * buf = 0);
|
||||
|
||||
~UndoGroupHelper()
|
||||
{
|
||||
resetBuffer(0);
|
||||
}
|
||||
~UndoGroupHelper();
|
||||
|
||||
/** Close the current undo group if necessary and create a new one
|
||||
* for buffer \c buf.
|
||||
@ -151,7 +145,8 @@ public:
|
||||
void resetBuffer(Buffer * buf);
|
||||
|
||||
private:
|
||||
Buffer * buffer_;
|
||||
class Impl;
|
||||
Impl * const d;
|
||||
};
|
||||
|
||||
|
||||
|
@ -17,6 +17,7 @@ liblyxfrontends_a_SOURCES = \
|
||||
Delegates.h \
|
||||
KeyModifier.h \
|
||||
KeySymbol.h \
|
||||
NullPainter.h \
|
||||
Painter.h \
|
||||
Clipboard.h \
|
||||
Selection.h \
|
||||
|
109
src/frontends/NullPainter.h
Normal file
109
src/frontends/NullPainter.h
Normal file
@ -0,0 +1,109 @@
|
||||
// -*- C++ -*-
|
||||
/**
|
||||
* \file NullPainter.h
|
||||
* This file is part of LyX, the document processor.
|
||||
* Licence details can be found in the file COPYING.
|
||||
*
|
||||
* \author unknown
|
||||
* \author John Levon
|
||||
* \author Jean-Marc Lasgouttes
|
||||
*
|
||||
* Full author contact details are available in file CREDITS.
|
||||
*/
|
||||
|
||||
#ifndef NULLPAINTER_H
|
||||
#define NULLPAINTER_H
|
||||
|
||||
#include "Painter.h"
|
||||
|
||||
namespace lyx {
|
||||
|
||||
namespace frontend {
|
||||
|
||||
/**
|
||||
* NullPainter - A painter instance that does nothing
|
||||
*/
|
||||
class NullPainter : public Painter {
|
||||
public:
|
||||
NullPainter() : Painter(1) {}
|
||||
|
||||
~NullPainter() {}
|
||||
|
||||
/// draw a line from point to point
|
||||
void line(int, int, int, int, Color,
|
||||
line_style = line_solid, int = thin_line) {}
|
||||
|
||||
///
|
||||
void lines(int const *, int const *, int, Color,
|
||||
fill_style = fill_none, line_style = line_solid,
|
||||
int = thin_line) {}
|
||||
|
||||
///
|
||||
void path(int const *, int const *, int const *, int const *,
|
||||
int const *, int const *, int, Color,
|
||||
fill_style = fill_none, line_style = line_solid, int = thin_line) {}
|
||||
|
||||
/// draw a rectangle
|
||||
void rectangle(int, int, int, int, Color,
|
||||
line_style = line_solid, int = thin_line) {}
|
||||
|
||||
/// draw a filled rectangle
|
||||
void fillRectangle(int, int, int, int, Color) {}
|
||||
|
||||
/// draw an arc
|
||||
void arc(int, int, unsigned int, unsigned int, int, int, Color) {}
|
||||
|
||||
/// draw a pixel
|
||||
void point(int, int, Color) {}
|
||||
|
||||
/// draw an image from the image cache
|
||||
void image(int, int, int, int, graphics::Image const &) {}
|
||||
|
||||
/// draw a string
|
||||
void text(int, int, docstring const &, FontInfo const &) {}
|
||||
|
||||
/// draw a char
|
||||
void text(int, int, char_type, FontInfo const &) {}
|
||||
|
||||
/// draw a string
|
||||
void text(int, int, docstring const &, Font const &, double, double) {}
|
||||
|
||||
///
|
||||
void text(int, int, docstring const &, Font const &,
|
||||
Color, size_type, size_type, double, double) {}
|
||||
|
||||
/// This painter does not paint
|
||||
bool isNull() const { return true; }
|
||||
|
||||
/// draw the underbar, strikeout, xout, uuline and uwave font attributes
|
||||
void textDecoration(FontInfo const &, int, int, int) {}
|
||||
|
||||
/**
|
||||
* Draw a string and enclose it inside a rectangle. If
|
||||
* back color is specified, the background is cleared with
|
||||
* the given color. If frame is specified, a thin frame is drawn
|
||||
* around the text with the given color.
|
||||
*/
|
||||
void rectText(int, int, docstring const &,
|
||||
FontInfo const &, Color, Color) {}
|
||||
|
||||
/// draw a string and enclose it inside a button frame
|
||||
void buttonText(int, int, docstring const &,
|
||||
FontInfo const &, Color, Color, int) {}
|
||||
|
||||
/// draw a character of a preedit string for cjk support.
|
||||
int preeditText(int, int, char_type, FontInfo const &,
|
||||
preedit_style) { return 0; }
|
||||
|
||||
/// start monochrome painting mode, i.e. map every color into [min,max]
|
||||
void enterMonochromeMode(Color const &, Color const &) {}
|
||||
/// leave monochrome painting mode
|
||||
void leaveMonochromeMode() {}
|
||||
/// draws a wavy line that can be used for underlining.
|
||||
void wavyHorizontalLine(int, int, int, ColorCode) {}
|
||||
};
|
||||
|
||||
} // namespace frontend
|
||||
} // namespace lyx
|
||||
|
||||
#endif // NULLPAINTER_H
|
@ -49,7 +49,7 @@ namespace frontend {
|
||||
*/
|
||||
class Painter {
|
||||
public:
|
||||
Painter(double pixel_ratio) : drawing_enabled_(true), pixel_ratio_(pixel_ratio) {}
|
||||
Painter(double pixel_ratio) : pixel_ratio_(pixel_ratio) {}
|
||||
|
||||
static const int thin_line;
|
||||
|
||||
@ -147,11 +147,8 @@ public:
|
||||
Color other, size_type from, size_type to,
|
||||
double wordspacing, double textwidth) = 0;
|
||||
|
||||
void setDrawingEnabled(bool drawing_enabled)
|
||||
{ drawing_enabled_ = drawing_enabled; }
|
||||
|
||||
/// Indicate wether real screen drawing shall be done or not.
|
||||
bool isDrawingEnabled() const { return drawing_enabled_; }
|
||||
// Returns true if the painter does not actually paint.
|
||||
virtual bool isNull() const = 0;
|
||||
|
||||
double pixelRatio() const { return pixel_ratio_; }
|
||||
|
||||
@ -183,8 +180,6 @@ public:
|
||||
/// draws a wavy line that can be used for underlining.
|
||||
virtual void wavyHorizontalLine(int x, int y, int width, ColorCode col) = 0;
|
||||
private:
|
||||
///
|
||||
bool drawing_enabled_;
|
||||
/// Ratio between physical pixels and device-independent pixels
|
||||
double pixel_ratio_;
|
||||
};
|
||||
|
@ -36,8 +36,8 @@ public:
|
||||
///
|
||||
virtual ~WorkArea() {}
|
||||
|
||||
/// redraw the screen, without using existing pixmap
|
||||
virtual void redraw(bool update_metrics) = 0;
|
||||
/// Update metrics if needed and schedule a paint event
|
||||
virtual void scheduleRedraw(bool update_metrics) = 0;
|
||||
|
||||
/// close this work area.
|
||||
/// Slot for Buffer::closing signal.
|
||||
|
@ -35,7 +35,7 @@ void WorkAreaManager::remove(WorkArea * wa)
|
||||
void WorkAreaManager::redrawAll(bool update_metrics)
|
||||
{
|
||||
for (WorkArea * wa : work_areas_)
|
||||
wa->redraw(update_metrics);
|
||||
wa->scheduleRedraw(update_metrics);
|
||||
}
|
||||
|
||||
|
||||
|
@ -16,6 +16,8 @@
|
||||
#include "LyXFileDialog.h"
|
||||
#include "qt_helpers.h"
|
||||
|
||||
#include "LyXRC.h"
|
||||
|
||||
#include "support/debug.h"
|
||||
#include "support/FileName.h"
|
||||
#include "support/filetools.h"
|
||||
@ -24,7 +26,9 @@
|
||||
|
||||
#include <string>
|
||||
|
||||
/** when this is defined, the code will use
|
||||
#include <QApplication>
|
||||
|
||||
/** when LyXRC::use_native_filedialog is true, we use
|
||||
* QFileDialog::getOpenFileName and friends to create filedialogs.
|
||||
* Effects:
|
||||
* - the dialog does not use the quick directory buttons (Button
|
||||
@ -35,13 +39,6 @@
|
||||
*
|
||||
* Therefore there is a tradeoff in enabling or disabling this (JMarc)
|
||||
*/
|
||||
#if defined(Q_OS_MAC) || defined(Q_OS_WIN)
|
||||
#define USE_NATIVE_FILEDIALOG 1
|
||||
#endif
|
||||
|
||||
#ifdef USE_NATIVE_FILEDIALOG
|
||||
#include <QApplication>
|
||||
#endif
|
||||
|
||||
namespace lyx {
|
||||
|
||||
@ -91,38 +88,38 @@ FileDialog::Result FileDialog::save(QString const & path,
|
||||
FileDialog::Result result;
|
||||
result.first = FileDialog::Chosen;
|
||||
|
||||
#ifdef USE_NATIVE_FILEDIALOG
|
||||
QString const startsWith = makeAbsPath(suggested, path);
|
||||
QString const name =
|
||||
QFileDialog::getSaveFileName(qApp->focusWidget(),
|
||||
title_, startsWith, filters.join(";;"),
|
||||
selectedFilter, QFileDialog::DontConfirmOverwrite);
|
||||
if (name.isNull())
|
||||
result.first = FileDialog::Later;
|
||||
else
|
||||
result.second = toqstr(os::internal_path(fromqstr(name)));
|
||||
#else
|
||||
LyXFileDialog dlg(title_, path, filters, private_->b1, private_->b2);
|
||||
dlg.setFileMode(QFileDialog::AnyFile);
|
||||
dlg.setAcceptMode(QFileDialog::AcceptSave);
|
||||
dlg.setConfirmOverwrite(false);
|
||||
if (selectedFilter != 0 && !selectedFilter->isEmpty())
|
||||
dlg.selectNameFilter(*selectedFilter);
|
||||
if (lyxrc.use_native_filedialog) {
|
||||
QString const startsWith = makeAbsPath(suggested, path);
|
||||
QString const name =
|
||||
QFileDialog::getSaveFileName(qApp->focusWidget(),
|
||||
title_, startsWith, filters.join(";;"),
|
||||
selectedFilter, QFileDialog::DontConfirmOverwrite);
|
||||
if (name.isNull())
|
||||
result.first = FileDialog::Later;
|
||||
else
|
||||
result.second = toqstr(os::internal_path(fromqstr(name)));
|
||||
} else {
|
||||
LyXFileDialog dlg(title_, path, filters, private_->b1, private_->b2);
|
||||
dlg.setFileMode(QFileDialog::AnyFile);
|
||||
dlg.setAcceptMode(QFileDialog::AcceptSave);
|
||||
dlg.setConfirmOverwrite(false);
|
||||
if (selectedFilter != 0 && !selectedFilter->isEmpty())
|
||||
dlg.selectNameFilter(*selectedFilter);
|
||||
|
||||
if (!suggested.isEmpty())
|
||||
dlg.selectFile(suggested);
|
||||
if (!suggested.isEmpty())
|
||||
dlg.selectFile(suggested);
|
||||
|
||||
LYXERR(Debug::GUI, "Synchronous FileDialog: ");
|
||||
int res = dlg.exec();
|
||||
LYXERR(Debug::GUI, "result " << res);
|
||||
if (res == QDialog::Accepted)
|
||||
result.second = internalPath(dlg.selectedFiles()[0]);
|
||||
else
|
||||
result.first = FileDialog::Later;
|
||||
if (selectedFilter != 0)
|
||||
*selectedFilter = dlg.selectedNameFilter();
|
||||
dlg.hide();
|
||||
#endif
|
||||
LYXERR(Debug::GUI, "Synchronous FileDialog: ");
|
||||
int res = dlg.exec();
|
||||
LYXERR(Debug::GUI, "result " << res);
|
||||
if (res == QDialog::Accepted)
|
||||
result.second = internalPath(dlg.selectedFiles()[0]);
|
||||
else
|
||||
result.first = FileDialog::Later;
|
||||
if (selectedFilter != 0)
|
||||
*selectedFilter = dlg.selectedNameFilter();
|
||||
dlg.hide();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -143,29 +140,29 @@ FileDialog::Result FileDialog::open(QString const & path,
|
||||
FileDialog::Result result;
|
||||
result.first = FileDialog::Chosen;
|
||||
|
||||
#ifdef USE_NATIVE_FILEDIALOG
|
||||
QString const startsWith = makeAbsPath(suggested, path);
|
||||
QString const file = QFileDialog::getOpenFileName(qApp->focusWidget(),
|
||||
title_, startsWith, filters.join(";;"));
|
||||
if (file.isNull())
|
||||
result.first = FileDialog::Later;
|
||||
else
|
||||
result.second = internalPath(file);
|
||||
#else
|
||||
LyXFileDialog dlg(title_, path, filters, private_->b1, private_->b2);
|
||||
if (lyxrc.use_native_filedialog) {
|
||||
QString const startsWith = makeAbsPath(suggested, path);
|
||||
QString const file = QFileDialog::getOpenFileName(qApp->focusWidget(),
|
||||
title_, startsWith, filters.join(";;"));
|
||||
if (file.isNull())
|
||||
result.first = FileDialog::Later;
|
||||
else
|
||||
result.second = internalPath(file);
|
||||
} else {
|
||||
LyXFileDialog dlg(title_, path, filters, private_->b1, private_->b2);
|
||||
|
||||
if (!suggested.isEmpty())
|
||||
dlg.selectFile(suggested);
|
||||
if (!suggested.isEmpty())
|
||||
dlg.selectFile(suggested);
|
||||
|
||||
LYXERR(Debug::GUI, "Synchronous FileDialog: ");
|
||||
int res = dlg.exec();
|
||||
LYXERR(Debug::GUI, "result " << res);
|
||||
if (res == QDialog::Accepted)
|
||||
result.second = internalPath(dlg.selectedFiles()[0]);
|
||||
else
|
||||
result.first = FileDialog::Later;
|
||||
dlg.hide();
|
||||
#endif
|
||||
LYXERR(Debug::GUI, "Synchronous FileDialog: ");
|
||||
int res = dlg.exec();
|
||||
LYXERR(Debug::GUI, "result " << res);
|
||||
if (res == QDialog::Accepted)
|
||||
result.second = internalPath(dlg.selectedFiles()[0]);
|
||||
else
|
||||
result.first = FileDialog::Later;
|
||||
dlg.hide();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -178,33 +175,33 @@ FileDialog::Result FileDialog::opendir(QString const & path,
|
||||
FileDialog::Result result;
|
||||
result.first = FileDialog::Chosen;
|
||||
|
||||
#ifdef USE_NATIVE_FILEDIALOG
|
||||
QString const startsWith = toqstr(makeAbsPath(fromqstr(suggested),
|
||||
fromqstr(path)).absFileName());
|
||||
QString const dir = QFileDialog::getExistingDirectory(qApp->focusWidget(),
|
||||
title_, startsWith);
|
||||
if (dir.isNull())
|
||||
result.first = FileDialog::Later;
|
||||
else
|
||||
result.second = toqstr(os::internal_path(fromqstr(dir)));
|
||||
#else
|
||||
LyXFileDialog dlg(title_, path, QStringList(qt_("Directories")),
|
||||
private_->b1, private_->b2);
|
||||
if (lyxrc.use_native_filedialog) {
|
||||
QString const startsWith =
|
||||
toqstr(makeAbsPath(fromqstr(suggested), fromqstr(path)).absFileName());
|
||||
QString const dir =
|
||||
QFileDialog::getExistingDirectory(qApp->focusWidget(), title_, startsWith);
|
||||
if (dir.isNull())
|
||||
result.first = FileDialog::Later;
|
||||
else
|
||||
result.second = toqstr(os::internal_path(fromqstr(dir)));
|
||||
} else {
|
||||
LyXFileDialog dlg(title_, path, QStringList(qt_("Directories")),
|
||||
private_->b1, private_->b2);
|
||||
|
||||
dlg.setFileMode(QFileDialog::DirectoryOnly);
|
||||
dlg.setFileMode(QFileDialog::DirectoryOnly);
|
||||
|
||||
if (!suggested.isEmpty())
|
||||
dlg.selectFile(suggested);
|
||||
if (!suggested.isEmpty())
|
||||
dlg.selectFile(suggested);
|
||||
|
||||
LYXERR(Debug::GUI, "Synchronous FileDialog: ");
|
||||
int res = dlg.exec();
|
||||
LYXERR(Debug::GUI, "result " << res);
|
||||
if (res == QDialog::Accepted)
|
||||
result.second = internalPath(dlg.selectedFiles()[0]);
|
||||
else
|
||||
result.first = FileDialog::Later;
|
||||
dlg.hide();
|
||||
#endif
|
||||
LYXERR(Debug::GUI, "Synchronous FileDialog: ");
|
||||
int res = dlg.exec();
|
||||
LYXERR(Debug::GUI, "result " << res);
|
||||
if (res == QDialog::Accepted)
|
||||
result.second = internalPath(dlg.selectedFiles()[0]);
|
||||
else
|
||||
result.first = FileDialog::Later;
|
||||
dlg.hide();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -65,8 +65,8 @@ FindAndReplaceWidget::FindAndReplaceWidget(GuiView & view)
|
||||
replace_work_area_->setFrameStyle(QFrame::StyledPanel);
|
||||
|
||||
// We don't want two cursors blinking.
|
||||
find_work_area_->stopBlinkingCursor();
|
||||
replace_work_area_->stopBlinkingCursor();
|
||||
find_work_area_->stopBlinkingCaret();
|
||||
replace_work_area_->stopBlinkingCaret();
|
||||
}
|
||||
|
||||
|
||||
|
@ -1395,9 +1395,9 @@ DispatchResult const & GuiApplication::dispatch(FuncRequest const & cmd)
|
||||
if (current_view_ && current_view_->currentBufferView()) {
|
||||
current_view_->currentBufferView()->cursor().saveBeforeDispatchPosXY();
|
||||
buffer = ¤t_view_->currentBufferView()->buffer();
|
||||
if (buffer)
|
||||
buffer->undo().beginUndoGroup();
|
||||
}
|
||||
// This handles undo groups automagically
|
||||
UndoGroupHelper ugh(buffer);
|
||||
|
||||
DispatchResult dr;
|
||||
// redraw the screen at the end (first of the two drawing steps).
|
||||
@ -1406,10 +1406,6 @@ DispatchResult const & GuiApplication::dispatch(FuncRequest const & cmd)
|
||||
dispatch(cmd, dr);
|
||||
updateCurrentView(cmd, dr);
|
||||
|
||||
// the buffer may have been closed by one action
|
||||
if (theBufferList().isLoaded(buffer) || theBufferList().isInternal(buffer))
|
||||
buffer->undo().endUndoGroup();
|
||||
|
||||
d->dispatch_result_ = dr;
|
||||
return d->dispatch_result_;
|
||||
}
|
||||
@ -1439,7 +1435,7 @@ void GuiApplication::updateCurrentView(FuncRequest const & cmd, DispatchResult &
|
||||
theSelection().haveSelection(bv->cursor().selection());
|
||||
|
||||
// update gui
|
||||
current_view_->restartCursor();
|
||||
current_view_->restartCaret();
|
||||
}
|
||||
if (dr.needMessageUpdate()) {
|
||||
// Some messages may already be translated, so we cannot use _()
|
||||
@ -1633,14 +1629,7 @@ void GuiApplication::dispatch(FuncRequest const & cmd, DispatchResult & dr)
|
||||
case LFUN_SCREEN_FONT_UPDATE: {
|
||||
// handle the screen font changes.
|
||||
d->font_loader_.update();
|
||||
// Backup current_view_
|
||||
GuiView * view = current_view_;
|
||||
// Set current_view_ to zero to forbid GuiWorkArea::redraw()
|
||||
// to skip the refresh.
|
||||
current_view_ = 0;
|
||||
theBufferList().changed(false);
|
||||
// Restore current_view_
|
||||
current_view_ = view;
|
||||
dr.screenUpdate(Update::Force | Update::FitCursor);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -1873,8 +1862,8 @@ void GuiApplication::dispatch(FuncRequest const & cmd, DispatchResult & dr)
|
||||
// FIXME: this LFUN should also work without any view.
|
||||
Buffer * buffer = (current_view_ && current_view_->documentBufferView())
|
||||
? &(current_view_->documentBufferView()->buffer()) : 0;
|
||||
if (buffer)
|
||||
buffer->undo().beginUndoGroup();
|
||||
// This handles undo groups automagically
|
||||
UndoGroupHelper ugh(buffer);
|
||||
while (!arg.empty()) {
|
||||
string first;
|
||||
arg = split(arg, first, ';');
|
||||
@ -1882,9 +1871,6 @@ void GuiApplication::dispatch(FuncRequest const & cmd, DispatchResult & dr)
|
||||
func.setOrigin(cmd.origin());
|
||||
dispatch(func);
|
||||
}
|
||||
// the buffer may have been closed by one action
|
||||
if (theBufferList().isLoaded(buffer) || theBufferList().isInternal(buffer))
|
||||
buffer->undo().endUndoGroup();
|
||||
break;
|
||||
}
|
||||
|
||||
@ -2158,7 +2144,7 @@ void GuiApplication::processKeySym(KeySymbol const & keysym, KeyModifier state)
|
||||
if (!keysym.isOK())
|
||||
LYXERR(Debug::KEY, "Empty kbd action (probably composing)");
|
||||
if (current_view_)
|
||||
current_view_->restartCursor();
|
||||
current_view_->restartCaret();
|
||||
return;
|
||||
}
|
||||
|
||||
@ -2218,7 +2204,7 @@ void GuiApplication::processKeySym(KeySymbol const & keysym, KeyModifier state)
|
||||
if (!isPrintable(encoded_last_key)) {
|
||||
LYXERR(Debug::KEY, "Non-printable character! Omitting.");
|
||||
if (current_view_)
|
||||
current_view_->restartCursor();
|
||||
current_view_->restartCaret();
|
||||
return;
|
||||
}
|
||||
// The following modifier check is not needed on Mac.
|
||||
@ -2240,7 +2226,7 @@ void GuiApplication::processKeySym(KeySymbol const & keysym, KeyModifier state)
|
||||
{
|
||||
if (current_view_) {
|
||||
current_view_->message(_("Unknown function."));
|
||||
current_view_->restartCursor();
|
||||
current_view_->restartCaret();
|
||||
}
|
||||
return;
|
||||
}
|
||||
@ -2255,7 +2241,7 @@ void GuiApplication::processKeySym(KeySymbol const & keysym, KeyModifier state)
|
||||
LYXERR(Debug::KEY, "Unknown Action and not isText() -- giving up");
|
||||
if (current_view_) {
|
||||
current_view_->message(_("Unknown function."));
|
||||
current_view_->restartCursor();
|
||||
current_view_->restartCaret();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
@ -27,6 +27,7 @@
|
||||
#include "TextClass.h"
|
||||
#include "FuncRequest.h"
|
||||
|
||||
#include "insets/InsetCitation.h"
|
||||
#include "insets/InsetCommand.h"
|
||||
|
||||
#include "support/debug.h"
|
||||
@ -92,7 +93,7 @@ static vector<lyx::docstring> to_docstring_vector(QStringList const & qlist)
|
||||
|
||||
GuiCitation::GuiCitation(GuiView & lv)
|
||||
: DialogView(lv, "citation", qt_("Citation")),
|
||||
style_(QString()), literal_(false), params_(insetCode("citation"))
|
||||
style_(QString()), params_(insetCode("citation"))
|
||||
{
|
||||
setupUi(this);
|
||||
|
||||
@ -232,12 +233,13 @@ void GuiCitation::on_restorePB_clicked()
|
||||
{
|
||||
init();
|
||||
updateFilterHint();
|
||||
filterPressed();
|
||||
}
|
||||
|
||||
|
||||
void GuiCitation::on_literalCB_clicked()
|
||||
{
|
||||
literal_ = literalCB->isChecked();
|
||||
InsetCitation::last_literal = literalCB->isChecked();
|
||||
changed();
|
||||
}
|
||||
|
||||
@ -768,7 +770,7 @@ void GuiCitation::init()
|
||||
// if this is a new citation, we set the literal checkbox
|
||||
// to its last set value.
|
||||
if (cited_keys_.isEmpty())
|
||||
literalCB->setChecked(literal_);
|
||||
literalCB->setChecked(InsetCitation::last_literal);
|
||||
else
|
||||
literalCB->setChecked(params_["literal"] == "true");
|
||||
|
||||
@ -1061,7 +1063,7 @@ void GuiCitation::saveSession(QSettings & settings) const
|
||||
settings.setValue(
|
||||
sessionKey() + "/citestyle", style_);
|
||||
settings.setValue(
|
||||
sessionKey() + "/literal", literal_);
|
||||
sessionKey() + "/literal", InsetCitation::last_literal);
|
||||
}
|
||||
|
||||
|
||||
@ -1073,7 +1075,8 @@ void GuiCitation::restoreSession()
|
||||
casesense_->setChecked(settings.value(sessionKey() + "/casesensitive").toBool());
|
||||
instant_->setChecked(settings.value(sessionKey() + "/autofind", true).toBool());
|
||||
style_ = settings.value(sessionKey() + "/citestyle").toString();
|
||||
literal_ = settings.value(sessionKey() + "/literal", false).toBool();
|
||||
InsetCitation::last_literal =
|
||||
settings.value(sessionKey() + "/literal", false).toBool();
|
||||
updateFilterHint();
|
||||
}
|
||||
|
||||
|
@ -183,9 +183,6 @@ private:
|
||||
|
||||
/// last used citation style
|
||||
QString style_;
|
||||
/// last set value for literal
|
||||
/// this is used only for new citations
|
||||
bool literal_;
|
||||
///
|
||||
GuiSelectionManager * selectionManager;
|
||||
/// available keys.
|
||||
|
@ -470,6 +470,33 @@ PreambleModule::PreambleModule(QWidget * parent)
|
||||
preambleTE->setWordWrapMode(QTextOption::NoWrap);
|
||||
setFocusProxy(preambleTE);
|
||||
connect(preambleTE, SIGNAL(textChanged()), this, SIGNAL(changed()));
|
||||
connect(findLE, SIGNAL(textEdited(const QString &)), this, SLOT(checkFindButton()));
|
||||
connect(findButtonPB, SIGNAL(clicked()), this, SLOT(findText()));
|
||||
connect(findLE, SIGNAL(returnPressed()), this, SLOT(findText()));
|
||||
checkFindButton();
|
||||
// https://stackoverflow.com/questions/13027091/how-to-override-tab-width-in-qt
|
||||
const int tabStop = 4;
|
||||
QFontMetrics metrics(preambleTE->currentFont());
|
||||
preambleTE->setTabStopWidth(tabStop * metrics.width(' '));
|
||||
}
|
||||
|
||||
|
||||
void PreambleModule::checkFindButton()
|
||||
{
|
||||
findButtonPB->setEnabled(!findLE->text().isEmpty());
|
||||
}
|
||||
|
||||
|
||||
void PreambleModule::findText()
|
||||
{
|
||||
bool const found = preambleTE->find(findLE->text());
|
||||
if (!found) {
|
||||
// wrap
|
||||
QTextCursor qtcur = preambleTE->textCursor();
|
||||
qtcur.movePosition(QTextCursor::Start);
|
||||
preambleTE->setTextCursor(qtcur);
|
||||
preambleTE->find(findLE->text());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -529,6 +556,8 @@ void PreambleModule::closeEvent(QCloseEvent * e)
|
||||
LocalLayout::LocalLayout(QWidget * parent)
|
||||
: UiWidget<Ui::LocalLayoutUi>(parent), current_id_(0), validated_(false)
|
||||
{
|
||||
locallayoutTE->setFont(guiApp->typewriterSystemFont());
|
||||
locallayoutTE->setWordWrapMode(QTextOption::NoWrap);
|
||||
connect(locallayoutTE, SIGNAL(textChanged()), this, SLOT(textChanged()));
|
||||
connect(validatePB, SIGNAL(clicked()), this, SLOT(validatePressed()));
|
||||
connect(convertPB, SIGNAL(clicked()), this, SLOT(convertPressed()));
|
||||
@ -1217,7 +1246,7 @@ GuiDocument::GuiDocument(GuiView & lv)
|
||||
setSectionResizeMode(mathsModule->packagesTW->horizontalHeader(), QHeaderView::Stretch);
|
||||
map<string, string> const & packages = BufferParams::auto_packages();
|
||||
mathsModule->packagesTW->setRowCount(packages.size());
|
||||
int i = 0;
|
||||
int packnum = 0;
|
||||
for (map<string, string>::const_iterator it = packages.begin();
|
||||
it != packages.end(); ++it) {
|
||||
docstring const package = from_ascii(it->first);
|
||||
@ -1248,11 +1277,35 @@ GuiDocument::GuiDocument(GuiView & lv)
|
||||
autoRB->setToolTip(autoTooltip);
|
||||
alwaysRB->setToolTip(alwaysTooltip);
|
||||
neverRB->setToolTip(neverTooltip);
|
||||
|
||||
// Pack the buttons in a layout in order to get proper alignment
|
||||
QWidget * autoRBWidget = new QWidget();
|
||||
QHBoxLayout * autoRBLayout = new QHBoxLayout(autoRBWidget);
|
||||
autoRBLayout->addWidget(autoRB);
|
||||
autoRBLayout->setAlignment(Qt::AlignCenter);
|
||||
autoRBLayout->setContentsMargins(0, 0, 0, 0);
|
||||
autoRBWidget->setLayout(autoRBLayout);
|
||||
|
||||
QWidget * alwaysRBWidget = new QWidget();
|
||||
QHBoxLayout * alwaysRBLayout = new QHBoxLayout(alwaysRBWidget);
|
||||
alwaysRBLayout->addWidget(alwaysRB);
|
||||
alwaysRBLayout->setAlignment(Qt::AlignCenter);
|
||||
alwaysRBLayout->setContentsMargins(0, 0, 0, 0);
|
||||
alwaysRBWidget->setLayout(alwaysRBLayout);
|
||||
|
||||
QWidget * neverRBWidget = new QWidget();
|
||||
QHBoxLayout * neverRBLayout = new QHBoxLayout(neverRBWidget);
|
||||
neverRBLayout->addWidget(neverRB);
|
||||
neverRBLayout->setAlignment(Qt::AlignCenter);
|
||||
neverRBLayout->setContentsMargins(0, 0, 0, 0);
|
||||
neverRBWidget->setLayout(neverRBLayout);
|
||||
|
||||
QTableWidgetItem * pack = new QTableWidgetItem(toqstr(package));
|
||||
mathsModule->packagesTW->setItem(i, 0, pack);
|
||||
mathsModule->packagesTW->setCellWidget(i, 1, autoRB);
|
||||
mathsModule->packagesTW->setCellWidget(i, 2, alwaysRB);
|
||||
mathsModule->packagesTW->setCellWidget(i, 3, neverRB);
|
||||
|
||||
mathsModule->packagesTW->setItem(packnum, 0, pack);
|
||||
mathsModule->packagesTW->setCellWidget(packnum, 1, autoRBWidget);
|
||||
mathsModule->packagesTW->setCellWidget(packnum, 2, alwaysRBWidget);
|
||||
mathsModule->packagesTW->setCellWidget(packnum, 3, neverRBWidget);
|
||||
|
||||
connect(autoRB, SIGNAL(clicked()),
|
||||
this, SLOT(change_adaptor()));
|
||||
@ -1260,7 +1313,7 @@ GuiDocument::GuiDocument(GuiView & lv)
|
||||
this, SLOT(change_adaptor()));
|
||||
connect(neverRB, SIGNAL(clicked()),
|
||||
this, SLOT(change_adaptor()));
|
||||
++i;
|
||||
++packnum;
|
||||
}
|
||||
connect(mathsModule->allPackagesAutoPB, SIGNAL(clicked()),
|
||||
this, SLOT(allPackagesAuto()));
|
||||
@ -3001,17 +3054,19 @@ void GuiDocument::applyView()
|
||||
if (!item)
|
||||
continue;
|
||||
int row = mathsModule->packagesTW->row(item);
|
||||
QRadioButton * rb = (QRadioButton*)mathsModule->packagesTW->cellWidget(row, 1);
|
||||
|
||||
QRadioButton * rb =
|
||||
(QRadioButton*)mathsModule->packagesTW->cellWidget(row, 1)->layout()->itemAt(0)->widget();
|
||||
if (rb->isChecked()) {
|
||||
bp_.use_package(it->first, BufferParams::package_auto);
|
||||
continue;
|
||||
}
|
||||
rb = (QRadioButton*)mathsModule->packagesTW->cellWidget(row, 2);
|
||||
rb = (QRadioButton*)mathsModule->packagesTW->cellWidget(row, 2)->layout()->itemAt(0)->widget();
|
||||
if (rb->isChecked()) {
|
||||
bp_.use_package(it->first, BufferParams::package_on);
|
||||
continue;
|
||||
}
|
||||
rb = (QRadioButton*)mathsModule->packagesTW->cellWidget(row, 3);
|
||||
rb = (QRadioButton*)mathsModule->packagesTW->cellWidget(row, 3)->layout()->itemAt(0)->widget();
|
||||
if (rb->isChecked())
|
||||
bp_.use_package(it->first, BufferParams::package_off);
|
||||
}
|
||||
@ -3546,17 +3601,20 @@ void GuiDocument::paramsToDialog()
|
||||
int row = mathsModule->packagesTW->row(item);
|
||||
switch (bp_.use_package(it->first)) {
|
||||
case BufferParams::package_off: {
|
||||
QRadioButton * rb = (QRadioButton*)mathsModule->packagesTW->cellWidget(row, 3);
|
||||
QRadioButton * rb =
|
||||
(QRadioButton*)mathsModule->packagesTW->cellWidget(row, 3)->layout()->itemAt(0)->widget();
|
||||
rb->setChecked(true);
|
||||
break;
|
||||
}
|
||||
case BufferParams::package_on: {
|
||||
QRadioButton * rb = (QRadioButton*)mathsModule->packagesTW->cellWidget(row, 2);
|
||||
QRadioButton * rb =
|
||||
(QRadioButton*)mathsModule->packagesTW->cellWidget(row, 2)->layout()->itemAt(0)->widget();
|
||||
rb->setChecked(true);
|
||||
break;
|
||||
}
|
||||
case BufferParams::package_auto: {
|
||||
QRadioButton * rb = (QRadioButton*)mathsModule->packagesTW->cellWidget(row, 1);
|
||||
QRadioButton * rb =
|
||||
(QRadioButton*)mathsModule->packagesTW->cellWidget(row, 1)->layout()->itemAt(0)->widget();
|
||||
rb->setChecked(true);
|
||||
break;
|
||||
}
|
||||
@ -4328,7 +4386,8 @@ void GuiDocument::dispatchParams()
|
||||
// We need a non-const buffer object.
|
||||
Buffer & buf = const_cast<BufferView *>(bufferview())->buffer();
|
||||
// There may be several undo records; group them (bug #8998)
|
||||
buf.undo().beginUndoGroup();
|
||||
// This handles undo groups automagically
|
||||
UndoGroupHelper ugh(&buf);
|
||||
|
||||
// This must come first so that a language change is correctly noticed
|
||||
setLanguage();
|
||||
@ -4395,10 +4454,6 @@ void GuiDocument::dispatchParams()
|
||||
// If we used an LFUN, we would not need these two lines:
|
||||
BufferView * bv = const_cast<BufferView *>(bufferview());
|
||||
bv->processUpdateFlags(Update::Force | Update::FitCursor);
|
||||
|
||||
// Don't forget to close the group. Note that it is important
|
||||
// to check that there is no early return in the method.
|
||||
buf.undo().endUndoGroup();
|
||||
}
|
||||
|
||||
|
||||
@ -4569,7 +4624,8 @@ void GuiDocument::allPackagesNot()
|
||||
void GuiDocument::allPackages(int col)
|
||||
{
|
||||
for (int row = 0; row < mathsModule->packagesTW->rowCount(); ++row) {
|
||||
QRadioButton * rb = (QRadioButton*)mathsModule->packagesTW->cellWidget(row, col);
|
||||
QRadioButton * rb =
|
||||
(QRadioButton*)mathsModule->packagesTW->cellWidget(row, col)->layout()->itemAt(0)->widget();
|
||||
rb->setChecked(true);
|
||||
}
|
||||
}
|
||||
|
@ -332,10 +332,14 @@ private:
|
||||
void closeEvent(QCloseEvent *);
|
||||
void on_preambleTE_textChanged() { changed(); }
|
||||
|
||||
private:
|
||||
typedef std::map<BufferId, std::pair<int,int> > Coords;
|
||||
Coords preamble_coords_;
|
||||
BufferId current_id_;
|
||||
|
||||
private Q_SLOTS:
|
||||
///
|
||||
void checkFindButton();
|
||||
void findText();
|
||||
};
|
||||
|
||||
|
||||
|
@ -493,6 +493,9 @@ static void getCrop(external::ClipData & data,
|
||||
|
||||
void GuiExternal::updateContents()
|
||||
{
|
||||
if (params_.filename.empty())
|
||||
tab->setCurrentIndex(0);
|
||||
|
||||
string const name =
|
||||
params_.filename.outputFileName(fromqstr(bufferFilePath()));
|
||||
fileED->setText(toqstr(name));
|
||||
|
@ -31,9 +31,9 @@
|
||||
#include "insets/InsetListingsParams.h"
|
||||
#include "insets/InsetInclude.h"
|
||||
|
||||
#include <QPushButton>
|
||||
#include <QCheckBox>
|
||||
#include <QLineEdit>
|
||||
#include <QPushButton>
|
||||
|
||||
#include <utility>
|
||||
|
||||
|
@ -52,10 +52,10 @@ GuiPainter::GuiPainter(QPaintDevice * device, double pixel_ratio)
|
||||
: QPainter(device), Painter(pixel_ratio),
|
||||
use_pixmap_cache_(false)
|
||||
{
|
||||
// new QPainter has default QPen:
|
||||
current_color_ = guiApp->colorCache().get(Color_black);
|
||||
current_ls_ = line_solid;
|
||||
current_lw_ = thin_line;
|
||||
// set cache correctly
|
||||
current_color_ = pen().color();
|
||||
current_ls_ = pen().style() == Qt::DotLine ? line_onoffdash : line_solid;
|
||||
current_lw_ = pen().width();
|
||||
}
|
||||
|
||||
|
||||
@ -171,9 +171,6 @@ void GuiPainter::leaveMonochromeMode()
|
||||
|
||||
void GuiPainter::point(int x, int y, Color col)
|
||||
{
|
||||
if (!isDrawingEnabled())
|
||||
return;
|
||||
|
||||
setQPainterPen(computeColor(col));
|
||||
drawPoint(x, y);
|
||||
}
|
||||
@ -184,9 +181,6 @@ void GuiPainter::line(int x1, int y1, int x2, int y2,
|
||||
line_style ls,
|
||||
int lw)
|
||||
{
|
||||
if (!isDrawingEnabled())
|
||||
return;
|
||||
|
||||
setQPainterPen(computeColor(col), ls, lw);
|
||||
bool const do_antialiasing = renderHints() & TextAntialiasing
|
||||
&& x1 != x2 && y1 != y2 && ls != line_solid_aliased;
|
||||
@ -202,9 +196,6 @@ void GuiPainter::lines(int const * xp, int const * yp, int np,
|
||||
line_style ls,
|
||||
int lw)
|
||||
{
|
||||
if (!isDrawingEnabled())
|
||||
return;
|
||||
|
||||
// double the size if needed
|
||||
// FIXME THREAD
|
||||
static QVector<QPoint> points(32);
|
||||
@ -247,9 +238,6 @@ void GuiPainter::path(int const * xp, int const * yp,
|
||||
line_style ls,
|
||||
int lw)
|
||||
{
|
||||
if (!isDrawingEnabled())
|
||||
return;
|
||||
|
||||
QPainterPath bpath;
|
||||
// This is the starting point, so its control points are meaningless
|
||||
bpath.moveTo(xp[0], yp[0]);
|
||||
@ -278,9 +266,6 @@ void GuiPainter::rectangle(int x, int y, int w, int h,
|
||||
line_style ls,
|
||||
int lw)
|
||||
{
|
||||
if (!isDrawingEnabled())
|
||||
return;
|
||||
|
||||
setQPainterPen(computeColor(col), ls, lw);
|
||||
drawRect(x, y, w, h);
|
||||
}
|
||||
@ -288,9 +273,6 @@ void GuiPainter::rectangle(int x, int y, int w, int h,
|
||||
|
||||
void GuiPainter::fillRectangle(int x, int y, int w, int h, Color col)
|
||||
{
|
||||
if (!isDrawingEnabled())
|
||||
return;
|
||||
|
||||
fillRect(x, y, w, h, guiApp->colorCache().get(col));
|
||||
}
|
||||
|
||||
@ -298,9 +280,6 @@ void GuiPainter::fillRectangle(int x, int y, int w, int h, Color col)
|
||||
void GuiPainter::arc(int x, int y, unsigned int w, unsigned int h,
|
||||
int a1, int a2, Color col)
|
||||
{
|
||||
if (!isDrawingEnabled())
|
||||
return;
|
||||
|
||||
// LyX usings 1/64ths degree, Qt usings 1/16th
|
||||
setQPainterPen(computeColor(col));
|
||||
bool const do_antialiasing = renderHints() & TextAntialiasing;
|
||||
@ -317,9 +296,6 @@ void GuiPainter::image(int x, int y, int w, int h, graphics::Image const & i)
|
||||
|
||||
fillRectangle(x, y, w, h, Color_graphicsbg);
|
||||
|
||||
if (!isDrawingEnabled())
|
||||
return;
|
||||
|
||||
QImage const image = qlimage.image();
|
||||
QRectF const drect = QRectF(x, y, w, h);
|
||||
QRectF const srect = QRectF(0, 0, image.width(), image.height());
|
||||
@ -391,7 +367,7 @@ void GuiPainter::text(int x, int y, docstring const & s,
|
||||
double const wordspacing, double const tw)
|
||||
{
|
||||
//LYXERR0("text: x=" << x << ", s=" << s);
|
||||
if (s.empty() || !isDrawingEnabled())
|
||||
if (s.empty())
|
||||
return;
|
||||
|
||||
/* Caution: The following ucs4 to QString conversions work for symbol fonts
|
||||
|
@ -37,6 +37,9 @@ public:
|
||||
GuiPainter(QPaintDevice *, double pixel_ratio);
|
||||
virtual ~GuiPainter();
|
||||
|
||||
/// This painter paints
|
||||
virtual bool isNull() const { return false; }
|
||||
|
||||
/// draw a line from point to point
|
||||
virtual void line(
|
||||
int x1, int y1,
|
||||
|
@ -1882,7 +1882,8 @@ bool GuiView::getStatus(FuncRequest const & cmd, FuncStatus & flag)
|
||||
|
||||
case LFUN_BUFFER_RELOAD:
|
||||
enable = doc_buffer && !doc_buffer->isUnnamed()
|
||||
&& doc_buffer->fileName().exists() && !doc_buffer->isClean();
|
||||
&& doc_buffer->fileName().exists()
|
||||
&& (!doc_buffer->isClean() || doc_buffer->notifiesExternalModification());
|
||||
break;
|
||||
|
||||
case LFUN_BUFFER_CHILD_OPEN:
|
||||
@ -2262,8 +2263,10 @@ Buffer * GuiView::loadDocument(FileName const & filename, bool tolastfiles)
|
||||
setBuffer(newBuffer);
|
||||
newBuffer->errors("Parse");
|
||||
|
||||
if (tolastfiles)
|
||||
if (tolastfiles) {
|
||||
theSession().lastFiles().add(filename);
|
||||
theSession().writeFile();
|
||||
}
|
||||
|
||||
return newBuffer;
|
||||
}
|
||||
@ -2802,6 +2805,7 @@ bool GuiView::saveBuffer(Buffer & b, FileName const & fn)
|
||||
bool const success = (fn.empty() ? b.save() : b.saveAs(fn));
|
||||
if (success) {
|
||||
theSession().lastFiles().add(b.fileName());
|
||||
theSession().writeFile();
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -4191,7 +4195,7 @@ void GuiView::dispatch(FuncRequest const & cmd, DispatchResult & dr)
|
||||
// painting so we must reset it.
|
||||
QPixmapCache::clear();
|
||||
guiApp->fontLoader().update();
|
||||
lyx::dispatch(FuncRequest(LFUN_SCREEN_FONT_UPDATE));
|
||||
dr.screenUpdate(Update::Force | Update::FitCursor);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -4387,19 +4391,19 @@ Buffer const * GuiView::updateInset(Inset const * inset)
|
||||
continue;
|
||||
Buffer const * buffer = &(wa->bufferView().buffer());
|
||||
if (inset_buffer == buffer)
|
||||
wa->scheduleRedraw();
|
||||
wa->scheduleRedraw(true);
|
||||
}
|
||||
return inset_buffer;
|
||||
}
|
||||
|
||||
|
||||
void GuiView::restartCursor()
|
||||
void GuiView::restartCaret()
|
||||
{
|
||||
/* When we move around, or type, it's nice to be able to see
|
||||
* the cursor immediately after the keypress.
|
||||
* the caret immediately after the keypress.
|
||||
*/
|
||||
if (d.current_work_area_)
|
||||
d.current_work_area_->startBlinkingCursor();
|
||||
d.current_work_area_->startBlinkingCaret();
|
||||
|
||||
// Take this occasion to update the other GUI elements.
|
||||
updateDialogs();
|
||||
@ -4468,7 +4472,7 @@ void GuiView::resetDialogs()
|
||||
// Now update controls with current buffer.
|
||||
guiApp->setCurrentView(this);
|
||||
restoreLayout();
|
||||
restartCursor();
|
||||
restartCaret();
|
||||
}
|
||||
|
||||
|
||||
|
@ -116,7 +116,7 @@ public:
|
||||
/// \return true if the \c FuncRequest has been dispatched.
|
||||
void dispatch(FuncRequest const & cmd, DispatchResult & dr);
|
||||
|
||||
void restartCursor();
|
||||
void restartCaret();
|
||||
/// Update the completion popup and the inline completion state.
|
||||
/// If \c start is true, then a new completion might be started.
|
||||
/// If \c keep is true, an active completion will be kept active
|
||||
|
@ -16,7 +16,13 @@
|
||||
|
||||
#include "ColorCache.h"
|
||||
#include "FontLoader.h"
|
||||
#include "GuiApplication.h"
|
||||
#include "GuiCompleter.h"
|
||||
#include "GuiKeySymbol.h"
|
||||
#include "GuiPainter.h"
|
||||
#include "GuiView.h"
|
||||
#include "Menus.h"
|
||||
#include "qt_helpers.h"
|
||||
|
||||
#include "Buffer.h"
|
||||
#include "BufferList.h"
|
||||
@ -26,19 +32,14 @@
|
||||
#include "Cursor.h"
|
||||
#include "Font.h"
|
||||
#include "FuncRequest.h"
|
||||
#include "GuiApplication.h"
|
||||
#include "GuiCompleter.h"
|
||||
#include "GuiKeySymbol.h"
|
||||
#include "GuiPainter.h"
|
||||
#include "GuiView.h"
|
||||
#include "KeySymbol.h"
|
||||
#include "Language.h"
|
||||
#include "LyX.h"
|
||||
#include "LyXRC.h"
|
||||
#include "LyXVC.h"
|
||||
#include "qt_helpers.h"
|
||||
#include "Text.h"
|
||||
#include "TextMetrics.h"
|
||||
#include "Undo.h"
|
||||
#include "version.h"
|
||||
|
||||
#include "graphics/GraphicsImage.h"
|
||||
@ -46,7 +47,6 @@
|
||||
|
||||
#include "support/convert.h"
|
||||
#include "support/debug.h"
|
||||
#include "support/gettext.h"
|
||||
#include "support/lassert.h"
|
||||
#include "support/TempFile.h"
|
||||
|
||||
@ -68,7 +68,6 @@
|
||||
#include <QMenu>
|
||||
#include <QPainter>
|
||||
#include <QPalette>
|
||||
#include <QPixmapCache>
|
||||
#include <QScrollBar>
|
||||
#include <QStyleOption>
|
||||
#include <QStylePainter>
|
||||
@ -77,8 +76,6 @@
|
||||
#include <QToolTip>
|
||||
#include <QMenuBar>
|
||||
|
||||
#include "support/bind.h"
|
||||
|
||||
#include <cmath>
|
||||
#include <iostream>
|
||||
|
||||
@ -130,17 +127,15 @@ mouse_button::state q_motion_state(Qt::MouseButtons state)
|
||||
|
||||
namespace frontend {
|
||||
|
||||
class CursorWidget {
|
||||
class CaretWidget {
|
||||
public:
|
||||
CursorWidget() : rtl_(false), l_shape_(false), completable_(false),
|
||||
show_(false), x_(0), cursor_width_(0)
|
||||
{
|
||||
recomputeWidth();
|
||||
}
|
||||
CaretWidget() : rtl_(false), l_shape_(false), completable_(false),
|
||||
x_(0), caret_width_(0)
|
||||
{}
|
||||
|
||||
void draw(QPainter & painter)
|
||||
{
|
||||
if (!show_ || !rect_.isValid())
|
||||
if (!rect_.isValid())
|
||||
return;
|
||||
|
||||
int y = rect_.top();
|
||||
@ -149,7 +144,7 @@ public:
|
||||
int bot = rect_.bottom();
|
||||
|
||||
// draw vertical line
|
||||
painter.fillRect(x_, y, cursor_width_, rect_.height(), color_);
|
||||
painter.fillRect(x_, y, caret_width_, rect_.height(), color_);
|
||||
|
||||
// draw RTL/LTR indication
|
||||
painter.setPen(color_);
|
||||
@ -157,7 +152,7 @@ public:
|
||||
if (rtl_)
|
||||
painter.drawLine(x_, bot, x_ - l, bot);
|
||||
else
|
||||
painter.drawLine(x_, bot, x_ + cursor_width_ + r, bot);
|
||||
painter.drawLine(x_, bot, x_ + caret_width_ + r, bot);
|
||||
}
|
||||
|
||||
// draw completion triangle
|
||||
@ -168,8 +163,8 @@ public:
|
||||
painter.drawLine(x_ - 1, m - d, x_ - 1 - d, m);
|
||||
painter.drawLine(x_ - 1, m + d, x_ - 1 - d, m);
|
||||
} else {
|
||||
painter.drawLine(x_ + cursor_width_, m - d, x_ + cursor_width_ + d, m);
|
||||
painter.drawLine(x_ + cursor_width_, m + d, x_ + cursor_width_ + d, m);
|
||||
painter.drawLine(x_ + caret_width_, m - d, x_ + caret_width_ + d, m);
|
||||
painter.drawLine(x_ + caret_width_, m + d, x_ + caret_width_ + d, m);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -203,38 +198,32 @@ public:
|
||||
r = max(r, TabIndicatorWidth);
|
||||
}
|
||||
|
||||
// compute overall rectangle
|
||||
rect_ = QRect(x - l, y, cursor_width_ + r + l, h);
|
||||
}
|
||||
|
||||
void show(bool set_show = true) { show_ = set_show; }
|
||||
void hide() { show_ = false; }
|
||||
int cursorWidth() const { return cursor_width_; }
|
||||
void recomputeWidth() {
|
||||
cursor_width_ = lyxrc.cursor_width
|
||||
//FIXME: LyXRC::cursor_width should be caret_width
|
||||
caret_width_ = lyxrc.cursor_width
|
||||
? lyxrc.cursor_width
|
||||
: 1 + int((lyxrc.currentZoom + 50) / 200.0);
|
||||
|
||||
// compute overall rectangle
|
||||
rect_ = QRect(x - l, y, caret_width_ + r + l, h);
|
||||
}
|
||||
|
||||
QRect const & rect() { return rect_; }
|
||||
|
||||
private:
|
||||
/// cursor is in RTL or LTR text
|
||||
/// caret is in RTL or LTR text
|
||||
bool rtl_;
|
||||
/// indication for RTL or LTR
|
||||
bool l_shape_;
|
||||
/// triangle to show that a completion is available
|
||||
bool completable_;
|
||||
///
|
||||
bool show_;
|
||||
///
|
||||
QColor color_;
|
||||
/// rectangle, possibly with l_shape and completion triangle
|
||||
QRect rect_;
|
||||
/// x position (were the vertical line is drawn)
|
||||
int x_;
|
||||
|
||||
int cursor_width_;
|
||||
/// the width of the vertical blinking bar
|
||||
int caret_width_;
|
||||
};
|
||||
|
||||
|
||||
@ -246,13 +235,35 @@ SyntheticMouseEvent::SyntheticMouseEvent()
|
||||
|
||||
|
||||
GuiWorkArea::Private::Private(GuiWorkArea * parent)
|
||||
: p(parent), screen_(0), buffer_view_(0), lyx_view_(0),
|
||||
cursor_visible_(false), cursor_(0),
|
||||
need_resize_(false), schedule_redraw_(false), preedit_lines_(1),
|
||||
pixel_ratio_(1.0),
|
||||
: p(parent), buffer_view_(0), lyx_view_(0),
|
||||
caret_(0), caret_visible_(false),
|
||||
need_resize_(false), preedit_lines_(1),
|
||||
last_pixel_ratio_(1.0),
|
||||
completer_(new GuiCompleter(p, p)), dialog_mode_(false), shell_escape_(false),
|
||||
read_only_(false), clean_(true), externally_modified_(false)
|
||||
{
|
||||
int const time = QApplication::cursorFlashTime() / 2;
|
||||
if (time > 0) {
|
||||
caret_timeout_.setInterval(time);
|
||||
caret_timeout_.start();
|
||||
} else {
|
||||
// let's initialize this just to be safe
|
||||
caret_timeout_.setInterval(500);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
GuiWorkArea::Private::~Private()
|
||||
{
|
||||
// If something is wrong with the buffer, we can ignore it safely
|
||||
try {
|
||||
buffer_view_->buffer().workAreaManager().remove(p);
|
||||
} catch(...) {}
|
||||
delete buffer_view_;
|
||||
delete caret_;
|
||||
// Completer has a QObject parent and is thus automatically destroyed.
|
||||
// See #4758.
|
||||
// delete completer_;
|
||||
}
|
||||
|
||||
|
||||
@ -287,24 +298,19 @@ double GuiWorkArea::pixelRatio() const
|
||||
void GuiWorkArea::init()
|
||||
{
|
||||
// Setup the signals
|
||||
connect(&d->cursor_timeout_, SIGNAL(timeout()),
|
||||
this, SLOT(toggleCursor()));
|
||||
connect(&d->caret_timeout_, SIGNAL(timeout()),
|
||||
this, SLOT(toggleCaret()));
|
||||
|
||||
int const time = QApplication::cursorFlashTime() / 2;
|
||||
if (time > 0) {
|
||||
d->cursor_timeout_.setInterval(time);
|
||||
d->cursor_timeout_.start();
|
||||
} else {
|
||||
// let's initialize this just to be safe
|
||||
d->cursor_timeout_.setInterval(500);
|
||||
}
|
||||
// This connection is closed at the same time as this is destroyed.
|
||||
d->synthetic_mouse_event_.timeout.timeout.connect([this](){
|
||||
generateSyntheticMouseEvent();
|
||||
});
|
||||
|
||||
d->resetScreen();
|
||||
// With Qt4.5 a mouse event will happen before the first paint event
|
||||
// so make sure that the buffer view has an up to date metrics.
|
||||
d->buffer_view_->resize(viewport()->width(), viewport()->height());
|
||||
d->cursor_ = new frontend::CursorWidget();
|
||||
d->cursor_->hide();
|
||||
d->caret_ = new frontend::CaretWidget();
|
||||
|
||||
setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
|
||||
setAcceptDrops(true);
|
||||
@ -313,63 +319,33 @@ void GuiWorkArea::init()
|
||||
setFrameStyle(QFrame::NoFrame);
|
||||
updateWindowTitle();
|
||||
|
||||
viewport()->setAutoFillBackground(false);
|
||||
// We don't need double-buffering nor SystemBackground on
|
||||
// the viewport because we have our own backing pixmap.
|
||||
viewport()->setAttribute(Qt::WA_NoSystemBackground);
|
||||
d->updateCursorShape();
|
||||
|
||||
// we paint our own background
|
||||
viewport()->setAttribute(Qt::WA_OpaquePaintEvent);
|
||||
|
||||
setFocusPolicy(Qt::StrongFocus);
|
||||
|
||||
d->setCursorShape(Qt::IBeamCursor);
|
||||
|
||||
// This connection is closed at the same time as this is destroyed.
|
||||
d->synthetic_mouse_event_.timeout.timeout.connect([this](){
|
||||
generateSyntheticMouseEvent();
|
||||
});
|
||||
|
||||
LYXERR(Debug::GUI, "viewport width: " << viewport()->width()
|
||||
<< " viewport height: " << viewport()->height());
|
||||
|
||||
// Enables input methods for asian languages.
|
||||
// Must be set when creating custom text editing widgets.
|
||||
setAttribute(Qt::WA_InputMethodEnabled, true);
|
||||
|
||||
d->dialog_mode_ = false;
|
||||
}
|
||||
|
||||
|
||||
GuiWorkArea::~GuiWorkArea()
|
||||
{
|
||||
// If something is wrong with the buffer, we can ignore it safely
|
||||
try {
|
||||
d->buffer_view_->buffer().workAreaManager().remove(this);
|
||||
} catch(...) {}
|
||||
delete d->screen_;
|
||||
delete d->buffer_view_;
|
||||
delete d->cursor_;
|
||||
// Completer has a QObject parent and is thus automatically destroyed.
|
||||
// See #4758.
|
||||
// delete completer_;
|
||||
delete d;
|
||||
}
|
||||
|
||||
|
||||
Qt::CursorShape GuiWorkArea::cursorShape() const
|
||||
{
|
||||
return viewport()->cursor().shape();
|
||||
}
|
||||
|
||||
|
||||
void GuiWorkArea::Private::setCursorShape(Qt::CursorShape shape)
|
||||
{
|
||||
p->viewport()->setCursor(shape);
|
||||
}
|
||||
|
||||
|
||||
void GuiWorkArea::Private::updateCursorShape()
|
||||
{
|
||||
setCursorShape(buffer_view_->clickableInset()
|
||||
? Qt::PointingHandCursor : Qt::IBeamCursor);
|
||||
bool const clickable = buffer_view_ && buffer_view_->clickableInset();
|
||||
p->viewport()->setCursor(clickable ? Qt::PointingHandCursor
|
||||
: Qt::IBeamCursor);
|
||||
}
|
||||
|
||||
|
||||
@ -436,14 +412,14 @@ BufferView const & GuiWorkArea::bufferView() const
|
||||
}
|
||||
|
||||
|
||||
void GuiWorkArea::stopBlinkingCursor()
|
||||
void GuiWorkArea::stopBlinkingCaret()
|
||||
{
|
||||
d->cursor_timeout_.stop();
|
||||
d->hideCursor();
|
||||
d->caret_timeout_.stop();
|
||||
d->hideCaret();
|
||||
}
|
||||
|
||||
|
||||
void GuiWorkArea::startBlinkingCursor()
|
||||
void GuiWorkArea::startBlinkingCaret()
|
||||
{
|
||||
// do not show the cursor if the view is busy
|
||||
if (view().busy())
|
||||
@ -451,23 +427,32 @@ void GuiWorkArea::startBlinkingCursor()
|
||||
|
||||
Point p;
|
||||
int h = 0;
|
||||
d->buffer_view_->cursorPosAndHeight(p, h);
|
||||
d->buffer_view_->caretPosAndHeight(p, h);
|
||||
// Don't start blinking if the cursor isn't on screen.
|
||||
if (!d->buffer_view_->cursorInView(p, h))
|
||||
return;
|
||||
|
||||
d->showCursor();
|
||||
d->showCaret();
|
||||
|
||||
//we're not supposed to cache this value.
|
||||
int const time = QApplication::cursorFlashTime() / 2;
|
||||
if (time <= 0)
|
||||
return;
|
||||
d->cursor_timeout_.setInterval(time);
|
||||
d->cursor_timeout_.start();
|
||||
d->caret_timeout_.setInterval(time);
|
||||
d->caret_timeout_.start();
|
||||
}
|
||||
|
||||
|
||||
void GuiWorkArea::redraw(bool update_metrics)
|
||||
void GuiWorkArea::toggleCaret()
|
||||
{
|
||||
if (d->caret_visible_)
|
||||
d->hideCaret();
|
||||
else
|
||||
d->showCaret();
|
||||
}
|
||||
|
||||
|
||||
void GuiWorkArea::scheduleRedraw(bool update_metrics)
|
||||
{
|
||||
if (!isVisible())
|
||||
// No need to redraw in this case.
|
||||
@ -483,17 +468,14 @@ void GuiWorkArea::redraw(bool update_metrics)
|
||||
d->buffer_view_->cursor().fixIfBroken();
|
||||
}
|
||||
|
||||
// update cursor position, because otherwise it has to wait until
|
||||
// update caret position, because otherwise it has to wait until
|
||||
// the blinking interval is over
|
||||
if (d->cursor_visible_) {
|
||||
d->hideCursor();
|
||||
d->showCursor();
|
||||
}
|
||||
d->updateCaretGeometry();
|
||||
|
||||
LYXERR(Debug::WORKAREA, "WorkArea::redraw screen");
|
||||
d->updateScreen();
|
||||
update(0, 0, viewport()->width(), viewport()->height());
|
||||
viewport()->update();
|
||||
|
||||
/// FIXME: is this still true now that paintEvent does the actual painting?
|
||||
/// \warning: scrollbar updating *must* be done after the BufferView is drawn
|
||||
/// because \c BufferView::updateScrollbar() is called in \c BufferView::draw().
|
||||
d->updateScrollbar();
|
||||
@ -526,9 +508,9 @@ void GuiWorkArea::processKeySym(KeySymbol const & key, KeyModifier mod)
|
||||
}
|
||||
|
||||
// In order to avoid bad surprise in the middle of an operation,
|
||||
// we better stop the blinking cursor...
|
||||
// the cursor gets restarted in GuiView::restartCursor()
|
||||
stopBlinkingCursor();
|
||||
// we better stop the blinking caret...
|
||||
// the caret gets restarted in GuiView::restartCaret()
|
||||
stopBlinkingCaret();
|
||||
guiApp->processKeySym(key, mod);
|
||||
}
|
||||
|
||||
@ -546,9 +528,9 @@ void GuiWorkArea::Private::dispatch(FuncRequest const & cmd)
|
||||
cmd.action() != LFUN_MOUSE_MOTION || cmd.button() != mouse_button::none;
|
||||
|
||||
// In order to avoid bad surprise in the middle of an operation, we better stop
|
||||
// the blinking cursor.
|
||||
// the blinking caret.
|
||||
if (notJustMovingTheMouse)
|
||||
p->stopBlinkingCursor();
|
||||
p->stopBlinkingCaret();
|
||||
|
||||
buffer_view_->mouseEventDispatch(cmd);
|
||||
|
||||
@ -568,8 +550,8 @@ void GuiWorkArea::Private::dispatch(FuncRequest const & cmd)
|
||||
// FIXME: let GuiView take care of those.
|
||||
lyx_view_->clearMessage();
|
||||
|
||||
// Show the cursor immediately after any operation
|
||||
p->startBlinkingCursor();
|
||||
// Show the caret immediately after any operation
|
||||
p->startBlinkingCaret();
|
||||
}
|
||||
|
||||
updateCursorShape();
|
||||
@ -580,18 +562,18 @@ void GuiWorkArea::Private::resizeBufferView()
|
||||
{
|
||||
// WARNING: Please don't put any code that will trigger a repaint here!
|
||||
// We are already inside a paint event.
|
||||
p->stopBlinkingCursor();
|
||||
p->stopBlinkingCaret();
|
||||
// Warn our container (GuiView).
|
||||
p->busy(true);
|
||||
|
||||
Point point;
|
||||
int h = 0;
|
||||
buffer_view_->cursorPosAndHeight(point, h);
|
||||
bool const cursor_in_view = buffer_view_->cursorInView(point, h);
|
||||
buffer_view_->caretPosAndHeight(point, h);
|
||||
bool const caret_in_view = buffer_view_->cursorInView(point, h);
|
||||
buffer_view_->resize(p->viewport()->width(), p->viewport()->height());
|
||||
if (cursor_in_view)
|
||||
if (caret_in_view)
|
||||
buffer_view_->scrollToCursor();
|
||||
updateScreen();
|
||||
updateCaretGeometry();
|
||||
|
||||
// Update scrollbars which might have changed due different
|
||||
// BufferView dimension. This is especially important when the
|
||||
@ -601,23 +583,20 @@ void GuiWorkArea::Private::resizeBufferView()
|
||||
|
||||
need_resize_ = false;
|
||||
p->busy(false);
|
||||
// Eventually, restart the cursor after the resize event.
|
||||
// Eventually, restart the caret after the resize event.
|
||||
// We might be resizing even if the focus is on another widget so we only
|
||||
// restart the cursor if we have the focus.
|
||||
// restart the caret if we have the focus.
|
||||
if (p->hasFocus())
|
||||
QTimer::singleShot(50, p, SLOT(startBlinkingCursor()));
|
||||
QTimer::singleShot(50, p, SLOT(startBlinkingCaret()));
|
||||
}
|
||||
|
||||
|
||||
void GuiWorkArea::Private::showCursor()
|
||||
void GuiWorkArea::Private::updateCaretGeometry()
|
||||
{
|
||||
if (cursor_visible_)
|
||||
return;
|
||||
|
||||
Point p;
|
||||
Point point;
|
||||
int h = 0;
|
||||
buffer_view_->cursorPosAndHeight(p, h);
|
||||
if (!buffer_view_->cursorInView(p, h))
|
||||
buffer_view_->caretPosAndHeight(point, h);
|
||||
if (!buffer_view_->cursorInView(point, h))
|
||||
return;
|
||||
|
||||
// RTL or not RTL
|
||||
@ -634,40 +613,41 @@ void GuiWorkArea::Private::showCursor()
|
||||
if (realfont.language() == latex_language)
|
||||
l_shape = false;
|
||||
|
||||
// show cursor on screen
|
||||
// show caret on screen
|
||||
Cursor & cur = buffer_view_->cursor();
|
||||
bool completable = cur.inset().showCompletionCursor()
|
||||
&& completer_->completionAvailable()
|
||||
&& !completer_->popupVisible()
|
||||
&& !completer_->inlineVisible();
|
||||
cursor_visible_ = true;
|
||||
cursor_->recomputeWidth();
|
||||
caret_visible_ = true;
|
||||
|
||||
//int cur_x = buffer_view_->getPos(cur).x_;
|
||||
// We may have decided to slide the cursor row so that cursor
|
||||
// We may have decided to slide the cursor row so that caret
|
||||
// is visible.
|
||||
p.x_ -= buffer_view_->horizScrollOffset();
|
||||
point.x_ -= buffer_view_->horizScrollOffset();
|
||||
|
||||
showCursor(p.x_, p.y_, h, l_shape, isrtl, completable);
|
||||
caret_->update(point.x_, point.y_, h, l_shape, isrtl, completable);
|
||||
}
|
||||
|
||||
|
||||
void GuiWorkArea::Private::hideCursor()
|
||||
void GuiWorkArea::Private::showCaret()
|
||||
{
|
||||
if (!cursor_visible_)
|
||||
if (caret_visible_)
|
||||
return;
|
||||
|
||||
cursor_visible_ = false;
|
||||
removeCursor();
|
||||
updateCaretGeometry();
|
||||
p->viewport()->update(caret_->rect());
|
||||
}
|
||||
|
||||
|
||||
void GuiWorkArea::toggleCursor()
|
||||
void GuiWorkArea::Private::hideCaret()
|
||||
{
|
||||
if (d->cursor_visible_)
|
||||
d->hideCursor();
|
||||
else
|
||||
d->showCursor();
|
||||
if (!caret_visible_)
|
||||
return;
|
||||
|
||||
caret_visible_ = false;
|
||||
//if (!qApp->focusWidget())
|
||||
p->viewport()->update(caret_->rect());
|
||||
}
|
||||
|
||||
|
||||
@ -690,7 +670,7 @@ void GuiWorkArea::Private::updateScrollbar()
|
||||
|
||||
void GuiWorkArea::scrollTo(int value)
|
||||
{
|
||||
stopBlinkingCursor();
|
||||
stopBlinkingCaret();
|
||||
d->buffer_view_->scrollDocView(value, true);
|
||||
|
||||
if (lyxrc.cursor_follows_scrollbar) {
|
||||
@ -698,8 +678,8 @@ void GuiWorkArea::scrollTo(int value)
|
||||
// FIXME: let GuiView take care of those.
|
||||
d->lyx_view_->updateLayoutList();
|
||||
}
|
||||
// Show the cursor immediately after any operation.
|
||||
startBlinkingCursor();
|
||||
// Show the caret immediately after any operation.
|
||||
startBlinkingCaret();
|
||||
// FIXME QT5
|
||||
#ifdef Q_WS_X11
|
||||
QApplication::syncX();
|
||||
@ -805,7 +785,7 @@ void GuiWorkArea::focusInEvent(QFocusEvent * e)
|
||||
d->lyx_view_->currentWorkArea()->bufferView().buffer().updateBuffer();
|
||||
}
|
||||
|
||||
startBlinkingCursor();
|
||||
startBlinkingCaret();
|
||||
QAbstractScrollArea::focusInEvent(e);
|
||||
}
|
||||
|
||||
@ -813,7 +793,7 @@ void GuiWorkArea::focusInEvent(QFocusEvent * e)
|
||||
void GuiWorkArea::focusOutEvent(QFocusEvent * e)
|
||||
{
|
||||
LYXERR(Debug::DEBUG, "GuiWorkArea::focusOutEvent(): " << this << endl);
|
||||
stopBlinkingCursor();
|
||||
stopBlinkingCaret();
|
||||
QAbstractScrollArea::focusOutEvent(e);
|
||||
}
|
||||
|
||||
@ -1176,157 +1156,31 @@ void GuiWorkArea::resizeEvent(QResizeEvent * ev)
|
||||
}
|
||||
|
||||
|
||||
void GuiWorkArea::Private::update(int x, int y, int w, int h)
|
||||
void GuiWorkArea::Private::paintPreeditText(GuiPainter & pain)
|
||||
{
|
||||
p->viewport()->update(x, y, w, h);
|
||||
}
|
||||
|
||||
|
||||
void GuiWorkArea::paintEvent(QPaintEvent * ev)
|
||||
{
|
||||
QRectF const rc = ev->rect();
|
||||
// LYXERR(Debug::PAINTING, "paintEvent begin: x: " << rc.x()
|
||||
// << " y: " << rc.y() << " w: " << rc.width() << " h: " << rc.height());
|
||||
|
||||
if (d->needResize()) {
|
||||
d->resetScreen();
|
||||
d->resizeBufferView();
|
||||
if (d->cursor_visible_) {
|
||||
d->hideCursor();
|
||||
d->showCursor();
|
||||
}
|
||||
}
|
||||
|
||||
QPainter pain(viewport());
|
||||
double const pr = pixelRatio();
|
||||
QRectF const rcs = QRectF(rc.x() * pr, rc.y() * pr, rc.width() * pr, rc.height() * pr);
|
||||
|
||||
if (lyxrc.use_qimage) {
|
||||
QImage const & image = static_cast<QImage const &>(*d->screen_);
|
||||
pain.drawImage(rc, image, rcs);
|
||||
} else {
|
||||
QPixmap const & pixmap = static_cast<QPixmap const &>(*d->screen_);
|
||||
pain.drawPixmap(rc, pixmap, rcs);
|
||||
}
|
||||
d->cursor_->draw(pain);
|
||||
ev->accept();
|
||||
}
|
||||
|
||||
|
||||
void GuiWorkArea::Private::updateScreen()
|
||||
{
|
||||
GuiPainter pain(screen_, p->pixelRatio());
|
||||
buffer_view_->draw(pain);
|
||||
}
|
||||
|
||||
|
||||
void GuiWorkArea::Private::showCursor(int x, int y, int h,
|
||||
bool l_shape, bool rtl, bool completable)
|
||||
{
|
||||
if (schedule_redraw_) {
|
||||
// This happens when a graphic conversion is finished. As we don't know
|
||||
// the size of the new graphics, it's better the update everything.
|
||||
// We can't use redraw() here because this would trigger a infinite
|
||||
// recursive loop with showCursor().
|
||||
buffer_view_->resize(p->viewport()->width(), p->viewport()->height());
|
||||
updateScreen();
|
||||
updateScrollbar();
|
||||
p->viewport()->update(QRect(0, 0, p->viewport()->width(), p->viewport()->height()));
|
||||
schedule_redraw_ = false;
|
||||
// Show the cursor immediately after the update.
|
||||
hideCursor();
|
||||
p->toggleCursor();
|
||||
if (preedit_string_.empty())
|
||||
return;
|
||||
}
|
||||
|
||||
cursor_->update(x, y, h, l_shape, rtl, completable);
|
||||
cursor_->show();
|
||||
p->viewport()->update(cursor_->rect());
|
||||
}
|
||||
|
||||
|
||||
void GuiWorkArea::Private::removeCursor()
|
||||
{
|
||||
cursor_->hide();
|
||||
//if (!qApp->focusWidget())
|
||||
p->viewport()->update(cursor_->rect());
|
||||
}
|
||||
|
||||
|
||||
void GuiWorkArea::inputMethodEvent(QInputMethodEvent * e)
|
||||
{
|
||||
QString const & commit_string = e->commitString();
|
||||
docstring const & preedit_string
|
||||
= qstring_to_ucs4(e->preeditString());
|
||||
|
||||
if (!commit_string.isEmpty()) {
|
||||
|
||||
LYXERR(Debug::KEY, "preeditString: " << e->preeditString()
|
||||
<< " commitString: " << e->commitString());
|
||||
|
||||
int key = 0;
|
||||
|
||||
// FIXME Iwami 04/01/07: we should take care also of UTF16 surrogates here.
|
||||
for (int i = 0; i != commit_string.size(); ++i) {
|
||||
QKeyEvent ev(QEvent::KeyPress, key, Qt::NoModifier, commit_string[i]);
|
||||
keyPressEvent(&ev);
|
||||
}
|
||||
}
|
||||
|
||||
// Hide the cursor during the kana-kanji transformation.
|
||||
if (preedit_string.empty())
|
||||
startBlinkingCursor();
|
||||
else
|
||||
stopBlinkingCursor();
|
||||
|
||||
// last_width : for checking if last preedit string was/wasn't empty.
|
||||
// FIXME THREAD && FIXME
|
||||
// We could have more than one work area, right?
|
||||
static bool last_width = false;
|
||||
if (!last_width && preedit_string.empty()) {
|
||||
// if last_width is last length of preedit string.
|
||||
e->accept();
|
||||
return;
|
||||
}
|
||||
|
||||
GuiPainter pain(d->screen_, pixelRatio());
|
||||
d->buffer_view_->updateMetrics();
|
||||
d->buffer_view_->draw(pain);
|
||||
// FIXME: shall we use real_current_font here? (see #10478)
|
||||
FontInfo font = d->buffer_view_->cursor().getFont().fontInfo();
|
||||
FontInfo const font = buffer_view_->cursor().getFont().fontInfo();
|
||||
FontMetrics const & fm = theFontMetrics(font);
|
||||
int height = fm.maxHeight();
|
||||
int cur_x = d->cursor_->rect().left();
|
||||
int cur_y = d->cursor_->rect().bottom();
|
||||
|
||||
// redraw area of preedit string.
|
||||
update(0, cur_y - height, viewport()->width(),
|
||||
(height + 1) * d->preedit_lines_);
|
||||
|
||||
if (preedit_string.empty()) {
|
||||
last_width = false;
|
||||
d->preedit_lines_ = 1;
|
||||
e->accept();
|
||||
return;
|
||||
}
|
||||
last_width = true;
|
||||
|
||||
// att : stores an IM attribute.
|
||||
QList<QInputMethodEvent::Attribute> const & att = e->attributes();
|
||||
int const height = fm.maxHeight();
|
||||
int cur_x = caret_->rect().left();
|
||||
int cur_y = caret_->rect().bottom();
|
||||
|
||||
// get attributes of input method cursor.
|
||||
// cursor_pos : cursor position in preedit string.
|
||||
size_t cursor_pos = 0;
|
||||
bool cursor_is_visible = false;
|
||||
for (int i = 0; i != att.size(); ++i) {
|
||||
if (att.at(i).type == QInputMethodEvent::Cursor) {
|
||||
cursor_pos = att.at(i).start;
|
||||
cursor_is_visible = att.at(i).length != 0;
|
||||
for (auto const & attr : preedit_attr_) {
|
||||
if (attr.type == QInputMethodEvent::Cursor) {
|
||||
cursor_pos = attr.start;
|
||||
cursor_is_visible = attr.length != 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
size_t preedit_length = preedit_string.length();
|
||||
size_t const preedit_length = preedit_string_.length();
|
||||
|
||||
// get position of selection in input method.
|
||||
// FIXME: isn't there a way to do this simplier?
|
||||
@ -1335,12 +1189,12 @@ void GuiWorkArea::inputMethodEvent(QInputMethodEvent * e)
|
||||
// rLength : selected string length in IM.
|
||||
size_t rLength = 0;
|
||||
if (cursor_pos < preedit_length) {
|
||||
for (int i = 0; i != att.size(); ++i) {
|
||||
if (att.at(i).type == QInputMethodEvent::TextFormat) {
|
||||
if (att.at(i).start <= int(cursor_pos)
|
||||
&& int(cursor_pos) < att.at(i).start + att.at(i).length) {
|
||||
rStart = att.at(i).start;
|
||||
rLength = att.at(i).length;
|
||||
for (auto const & attr : preedit_attr_) {
|
||||
if (attr.type == QInputMethodEvent::TextFormat) {
|
||||
if (attr.start <= int(cursor_pos)
|
||||
&& int(cursor_pos) < attr.start + attr.length) {
|
||||
rStart = attr.start;
|
||||
rLength = attr.length;
|
||||
if (!cursor_is_visible)
|
||||
cursor_pos += rLength;
|
||||
break;
|
||||
@ -1353,20 +1207,20 @@ void GuiWorkArea::inputMethodEvent(QInputMethodEvent * e)
|
||||
rLength = 0;
|
||||
}
|
||||
|
||||
int const right_margin = d->buffer_view_->rightMargin();
|
||||
int const right_margin = buffer_view_->rightMargin();
|
||||
Painter::preedit_style ps;
|
||||
// Most often there would be only one line:
|
||||
d->preedit_lines_ = 1;
|
||||
preedit_lines_ = 1;
|
||||
for (size_t pos = 0; pos != preedit_length; ++pos) {
|
||||
char_type const typed_char = preedit_string[pos];
|
||||
char_type const typed_char = preedit_string_[pos];
|
||||
// reset preedit string style
|
||||
ps = Painter::preedit_default;
|
||||
|
||||
// if we reached the right extremity of the screen, go to next line.
|
||||
if (cur_x + fm.width(typed_char) > viewport()->width() - right_margin) {
|
||||
if (cur_x + fm.width(typed_char) > p->viewport()->width() - right_margin) {
|
||||
cur_x = right_margin;
|
||||
cur_y += height + 1;
|
||||
++d->preedit_lines_;
|
||||
++preedit_lines_;
|
||||
}
|
||||
// preedit strings are displayed with dashed underline
|
||||
// and partial strings are displayed white on black indicating
|
||||
@ -1385,11 +1239,81 @@ void GuiWorkArea::inputMethodEvent(QInputMethodEvent * e)
|
||||
// draw one character and update cur_x.
|
||||
cur_x += pain.preeditText(cur_x, cur_y, typed_char, font, ps);
|
||||
}
|
||||
}
|
||||
|
||||
// update the preedit string screen area.
|
||||
update(0, cur_y - d->preedit_lines_*height, viewport()->width(),
|
||||
|
||||
void GuiWorkArea::paintEvent(QPaintEvent * ev)
|
||||
{
|
||||
// LYXERR(Debug::PAINTING, "paintEvent begin: x: " << rc.x()
|
||||
// << " y: " << rc.y() << " w: " << rc.width() << " h: " << rc.height());
|
||||
|
||||
if (d->need_resize_ || pixelRatio() != d->last_pixel_ratio_) {
|
||||
d->resetScreen();
|
||||
d->resizeBufferView();
|
||||
}
|
||||
|
||||
d->last_pixel_ratio_ = pixelRatio();
|
||||
|
||||
GuiPainter pain(d->screenDevice(), pixelRatio());
|
||||
|
||||
d->buffer_view_->draw(pain, d->caret_visible_);
|
||||
|
||||
// The preedit text, if needed
|
||||
d->paintPreeditText(pain);
|
||||
|
||||
// and the caret
|
||||
if (d->caret_visible_)
|
||||
d->caret_->draw(pain);
|
||||
|
||||
d->updateScreen(ev->rect());
|
||||
|
||||
ev->accept();
|
||||
}
|
||||
|
||||
|
||||
void GuiWorkArea::inputMethodEvent(QInputMethodEvent * e)
|
||||
{
|
||||
LYXERR(Debug::KEY, "preeditString: " << e->preeditString()
|
||||
<< " commitString: " << e->commitString());
|
||||
|
||||
// insert the processed text in the document (handles undo)
|
||||
if (!e->commitString().isEmpty()) {
|
||||
d->buffer_view_->cursor().beginUndoGroup();
|
||||
d->buffer_view_->cursor().insert(qstring_to_ucs4(e->commitString()));
|
||||
d->buffer_view_->updateMetrics();
|
||||
d->buffer_view_->cursor().endUndoGroup();
|
||||
viewport()->update();
|
||||
}
|
||||
|
||||
// Hide the caret during the test transformation.
|
||||
if (e->preeditString().isEmpty())
|
||||
startBlinkingCaret();
|
||||
else
|
||||
stopBlinkingCaret();
|
||||
|
||||
if (d->preedit_string_.empty() && e->preeditString().isEmpty()) {
|
||||
// Nothing to do
|
||||
e->accept();
|
||||
return;
|
||||
}
|
||||
|
||||
// The preedit text and its attributes will be used in paintPreeditText
|
||||
d->preedit_string_ = qstring_to_ucs4(e->preeditString());
|
||||
d->preedit_attr_ = e->attributes();
|
||||
|
||||
|
||||
// redraw area of preedit string.
|
||||
int height = d->caret_->rect().height();
|
||||
int cur_y = d->caret_->rect().bottom();
|
||||
viewport()->update(0, cur_y - height, viewport()->width(),
|
||||
(height + 1) * d->preedit_lines_);
|
||||
|
||||
if (d->preedit_string_.empty()) {
|
||||
d->preedit_lines_ = 1;
|
||||
e->accept();
|
||||
return;
|
||||
}
|
||||
|
||||
// Don't forget to accept the event!
|
||||
e->accept();
|
||||
}
|
||||
@ -1402,12 +1326,12 @@ QVariant GuiWorkArea::inputMethodQuery(Qt::InputMethodQuery query) const
|
||||
// this is the CJK-specific composition window position and
|
||||
// the context menu position when the menu key is pressed.
|
||||
case Qt::ImMicroFocus:
|
||||
cur_r = d->cursor_->rect();
|
||||
cur_r = d->caret_->rect();
|
||||
if (d->preedit_lines_ != 1)
|
||||
cur_r.moveLeft(10);
|
||||
cur_r.moveBottom(cur_r.bottom()
|
||||
+ cur_r.height() * (d->preedit_lines_ - 1));
|
||||
// return lower right of cursor in LyX.
|
||||
// return lower right of caret in LyX.
|
||||
return cur_r;
|
||||
default:
|
||||
return QWidget::inputMethodQuery(query);
|
||||
@ -1441,12 +1365,6 @@ bool GuiWorkArea::isFullScreen() const
|
||||
}
|
||||
|
||||
|
||||
void GuiWorkArea::scheduleRedraw()
|
||||
{
|
||||
d->schedule_redraw_ = true;
|
||||
}
|
||||
|
||||
|
||||
bool GuiWorkArea::inDialogMode() const
|
||||
{
|
||||
return d->dialog_mode_;
|
||||
@ -1529,7 +1447,7 @@ QSize EmbeddedWorkArea::sizeHint () const
|
||||
|
||||
void EmbeddedWorkArea::disable()
|
||||
{
|
||||
stopBlinkingCursor();
|
||||
stopBlinkingCaret();
|
||||
if (view().currentWorkArea() != this)
|
||||
return;
|
||||
// No problem if currentMainWorkArea() is 0 (setCurrentWorkArea()
|
||||
@ -1859,7 +1777,7 @@ void TabWorkArea::on_currentTabChanged(int i)
|
||||
GuiWorkArea * wa = workArea(i);
|
||||
LASSERT(wa, return);
|
||||
wa->setUpdatesEnabled(true);
|
||||
wa->redraw(true);
|
||||
wa->scheduleRedraw(true);
|
||||
wa->setFocus();
|
||||
///
|
||||
currentWorkAreaChanged(wa);
|
||||
|
@ -27,10 +27,6 @@ class QDropEvent;
|
||||
class QToolButton;
|
||||
class QWidget;
|
||||
|
||||
#ifdef CursorShape
|
||||
#undef CursorShape
|
||||
#endif
|
||||
|
||||
namespace lyx {
|
||||
|
||||
class Buffer;
|
||||
@ -64,13 +60,11 @@ public:
|
||||
/// is GuiView in fullscreen mode?
|
||||
bool isFullScreen() const;
|
||||
///
|
||||
void scheduleRedraw();
|
||||
///
|
||||
BufferView & bufferView();
|
||||
///
|
||||
BufferView const & bufferView() const;
|
||||
///
|
||||
void redraw(bool update_metrics);
|
||||
void scheduleRedraw(bool update_metrics);
|
||||
|
||||
/// return true if the key is part of a shortcut
|
||||
bool queryKeySym(KeySymbol const & key, KeyModifier mod) const;
|
||||
@ -81,8 +75,6 @@ public:
|
||||
///
|
||||
GuiCompleter & completer();
|
||||
|
||||
Qt::CursorShape cursorShape() const;
|
||||
|
||||
/// Return the GuiView this workArea belongs to
|
||||
GuiView const & view() const;
|
||||
GuiView & view();
|
||||
@ -95,9 +87,9 @@ public Q_SLOTS:
|
||||
/// This needs to be public because it is accessed externally by GuiView.
|
||||
void processKeySym(KeySymbol const & key, KeyModifier mod);
|
||||
///
|
||||
void stopBlinkingCursor();
|
||||
void stopBlinkingCaret();
|
||||
///
|
||||
void startBlinkingCursor();
|
||||
void startBlinkingCaret();
|
||||
|
||||
Q_SIGNALS:
|
||||
///
|
||||
@ -118,8 +110,8 @@ private Q_SLOTS:
|
||||
void scrollTo(int value);
|
||||
/// timer to limit triple clicks
|
||||
void doubleClickTimeout();
|
||||
/// toggle the cursor's visibility
|
||||
void toggleCursor();
|
||||
/// toggle the caret's visibility
|
||||
void toggleCaret();
|
||||
/// close this work area.
|
||||
/// Slot for Buffer::closing signal.
|
||||
void close();
|
||||
|
@ -13,28 +13,19 @@
|
||||
#define WORKAREA_PRIVATE_H
|
||||
|
||||
#include "FuncRequest.h"
|
||||
#include "LyXRC.h"
|
||||
|
||||
#include "support/FileName.h"
|
||||
#include "support/Timeout.h"
|
||||
|
||||
#include <QMouseEvent>
|
||||
#include <QImage>
|
||||
#include <QPixmap>
|
||||
#include <QTimer>
|
||||
|
||||
class QContextMenuEvent;
|
||||
class QDragEnterEvent;
|
||||
class QDropEvent;
|
||||
class QKeyEvent;
|
||||
class QPaintEvent;
|
||||
class QResizeEvent;
|
||||
class QToolButton;
|
||||
class QWheelEvent;
|
||||
class QWidget;
|
||||
|
||||
#ifdef CursorShape
|
||||
#undef CursorShape
|
||||
#ifdef Q_OS_MAC
|
||||
/* Qt on macOS does not respect the Qt::WA_OpaquePaintEvent attribute
|
||||
* and resets the widget backing store at each update. Therefore, we
|
||||
* use our own backing store in this case */
|
||||
#define LYX_BACKINGSTORE 1
|
||||
#include <QPainter>
|
||||
#endif
|
||||
|
||||
namespace lyx {
|
||||
@ -44,6 +35,7 @@ class Buffer;
|
||||
namespace frontend {
|
||||
|
||||
class GuiCompleter;
|
||||
class GuiPainter;
|
||||
class GuiView;
|
||||
class GuiWorkArea;
|
||||
|
||||
@ -86,96 +78,104 @@ public:
|
||||
/**
|
||||
* Implementation of the work area (buffer view GUI)
|
||||
*/
|
||||
class CursorWidget;
|
||||
class CaretWidget;
|
||||
|
||||
struct GuiWorkArea::Private
|
||||
{
|
||||
///
|
||||
Private(GuiWorkArea *);
|
||||
|
||||
/// update the passed area.
|
||||
void update(int x, int y, int w, int h);
|
||||
///
|
||||
void updateScreen();
|
||||
~Private();
|
||||
|
||||
///
|
||||
void resizeBufferView();
|
||||
|
||||
/// paint the cursor and store the background
|
||||
void showCursor(int x, int y, int h,
|
||||
bool l_shape, bool rtl, bool completable);
|
||||
|
||||
/// hide the cursor
|
||||
void removeCursor();
|
||||
///
|
||||
void dispatch(FuncRequest const & cmd0);
|
||||
/// hide the visible cursor, if it is visible
|
||||
void hideCursor();
|
||||
/// show the cursor if it is not visible
|
||||
void showCursor();
|
||||
/// recompute the shape and position of the caret
|
||||
void updateCaretGeometry();
|
||||
/// show the caret if it is not visible
|
||||
void showCaret();
|
||||
/// hide the caret if it is visible
|
||||
void hideCaret();
|
||||
/// Set the range and value of the scrollbar and connect to its valueChanged
|
||||
/// signal.
|
||||
void updateScrollbar();
|
||||
/// Change the cursor when the mouse hovers over a clickable inset
|
||||
void updateCursorShape();
|
||||
///
|
||||
void setCursorShape(Qt::CursorShape shape);
|
||||
|
||||
bool needResize() const {
|
||||
return need_resize_ || p->pixelRatio() != pixel_ratio_;
|
||||
void paintPreeditText(GuiPainter & pain);
|
||||
|
||||
void resetScreen() {
|
||||
#ifdef LYX_BACKINGSTORE
|
||||
int const pr = p->pixelRatio();
|
||||
screen_ = QImage(static_cast<int>(pr * p->viewport()->width()),
|
||||
static_cast<int>(pr * p->viewport()->height()),
|
||||
QImage::Format_ARGB32_Premultiplied);
|
||||
# if QT_VERSION >= 0x050000
|
||||
screen_.setDevicePixelRatio(pr);
|
||||
# endif
|
||||
#endif
|
||||
}
|
||||
|
||||
void resetScreen()
|
||||
{
|
||||
delete screen_;
|
||||
pixel_ratio_ = p->pixelRatio();
|
||||
if (lyxrc.use_qimage) {
|
||||
QImage *x =
|
||||
new QImage(static_cast<int>(pixel_ratio_ * p->viewport()->width()),
|
||||
static_cast<int>(pixel_ratio_ * p->viewport()->height()),
|
||||
QImage::Format_ARGB32_Premultiplied);
|
||||
#if QT_VERSION >= 0x050000
|
||||
x->setDevicePixelRatio(pixel_ratio_);
|
||||
QPaintDevice * screenDevice() {
|
||||
#ifdef LYX_BACKINGSTORE
|
||||
return &screen_;
|
||||
#else
|
||||
return p->viewport();
|
||||
#endif
|
||||
screen_ = x;
|
||||
} else {
|
||||
QPixmap *x =
|
||||
new QPixmap(static_cast<int>(pixel_ratio_ * p->viewport()->width()),
|
||||
static_cast<int>(pixel_ratio_ * p->viewport()->height()));
|
||||
#if QT_VERSION >= 0x050000
|
||||
x->setDevicePixelRatio(pixel_ratio_);
|
||||
#endif
|
||||
screen_ = x;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef LYX_BACKINGSTORE
|
||||
void updateScreen(QRectF const & rc) {
|
||||
QPainter qpain(p->viewport());
|
||||
double const pr = p->pixelRatio();
|
||||
QRectF const rcs = QRectF(rc.x() * pr, rc.y() * pr,
|
||||
rc.width() * pr, rc.height() * pr);
|
||||
qpain.drawImage(rc, screen_, rcs);
|
||||
}
|
||||
#else
|
||||
void updateScreen(QRectF const & ) {}
|
||||
#endif
|
||||
|
||||
///
|
||||
GuiWorkArea * p;
|
||||
///
|
||||
QPaintDevice * screen_;
|
||||
///
|
||||
BufferView * buffer_view_;
|
||||
///
|
||||
GuiView * lyx_view_;
|
||||
/// is the cursor currently displayed
|
||||
bool cursor_visible_;
|
||||
|
||||
#ifdef LYX_BACKINGSTORE
|
||||
///
|
||||
QTimer cursor_timeout_;
|
||||
QImage screen_;
|
||||
#endif
|
||||
///
|
||||
CaretWidget * caret_;
|
||||
/// is the caret currently displayed
|
||||
bool caret_visible_;
|
||||
///
|
||||
QTimer caret_timeout_;
|
||||
|
||||
///
|
||||
SyntheticMouseEvent synthetic_mouse_event_;
|
||||
///
|
||||
DoubleClick dc_event_;
|
||||
|
||||
///
|
||||
CursorWidget * cursor_;
|
||||
///
|
||||
bool need_resize_;
|
||||
///
|
||||
bool schedule_redraw_;
|
||||
///
|
||||
|
||||
/// the current preedit text of the input method
|
||||
docstring preedit_string_;
|
||||
/// Number of lines used by preedit text
|
||||
int preedit_lines_;
|
||||
/// the attributes of the preedit text
|
||||
QList<QInputMethodEvent::Attribute> preedit_attr_;
|
||||
|
||||
/// Ratio between physical pixels and device-independent pixels
|
||||
/// We save the last used value to detect changes of the
|
||||
/// current pixel_ratio of the viewport.
|
||||
double pixel_ratio_;
|
||||
double last_pixel_ratio_;
|
||||
///
|
||||
GuiCompleter * completer_;
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -6,172 +6,15 @@
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>500</width>
|
||||
<width>569</width>
|
||||
<height>367</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string/>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="allPakcagesLA">
|
||||
<property name="text">
|
||||
<string>All packages:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QPushButton" name="allPackagesAutoPB">
|
||||
<property name="text">
|
||||
<string>Load A&utomatically</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="2">
|
||||
<widget class="QPushButton" name="allPackagesAlwaysPB">
|
||||
<property name="text">
|
||||
<string>Load Alwa&ys</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="3">
|
||||
<widget class="QPushButton" name="allPackagesNotPB">
|
||||
<property name="text">
|
||||
<string>Do &Not Load</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QCheckBox" name="MathIndentCB">
|
||||
<property name="toolTip">
|
||||
<string>Indent displayed formulas instead of centering</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Indent &Formulas</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QComboBox" name="MathIndentCO">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Size of the indentation</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="2" colspan="2">
|
||||
<spacer name="horizontalSpacer_3">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>234</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="3" column="1">
|
||||
<widget class="QLineEdit" name="MathIndentLE">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="2">
|
||||
<widget class="lyx::frontend::LengthCombo" name="MathIndentLengthCO">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="3">
|
||||
<spacer name="horizontalSpacer_2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>153</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="4" column="0">
|
||||
<widget class="QLabel" name="MathNumberingPosL">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>115</width>
|
||||
<height>18</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Formula numbering side:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="1">
|
||||
<widget class="QComboBox" name="MathNumberingPosCO">
|
||||
<property name="enabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Side where formulas are numbered</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="2" colspan="2">
|
||||
<spacer name="horizontalSpacer_1">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>234</width>
|
||||
<height>17</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="0" column="0" colspan="4">
|
||||
<layout class="QGridLayout" name="gridLayout_2">
|
||||
<item row="0" column="0">
|
||||
<widget class="QTableWidget" name="packagesTW">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
|
||||
@ -179,6 +22,9 @@
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="alternatingRowColors">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="columnCount">
|
||||
<number>4</number>
|
||||
</property>
|
||||
@ -194,6 +40,171 @@
|
||||
<column/>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="allPakcagesLA">
|
||||
<property name="text">
|
||||
<string>All packages:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QPushButton" name="allPackagesAutoPB">
|
||||
<property name="text">
|
||||
<string>Load A&utomatically</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="2">
|
||||
<widget class="QPushButton" name="allPackagesAlwaysPB">
|
||||
<property name="text">
|
||||
<string>Load Alwa&ys</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="3">
|
||||
<widget class="QPushButton" name="allPackagesNotPB">
|
||||
<property name="text">
|
||||
<string>Do &Not Load</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QCheckBox" name="MathIndentCB">
|
||||
<property name="toolTip">
|
||||
<string>Indent displayed formulas instead of centering</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Indent &Formulas</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QComboBox" name="MathIndentCO">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Size of the indentation</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="2" colspan="2">
|
||||
<spacer name="horizontalSpacer_3">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>234</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QLineEdit" name="MathIndentLE">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="2">
|
||||
<widget class="lyx::frontend::LengthCombo" name="MathIndentLengthCO">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="3">
|
||||
<spacer name="horizontalSpacer_2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>153</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<widget class="QLabel" name="MathNumberingPosL">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>115</width>
|
||||
<height>18</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Formula numbering side:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QComboBox" name="MathNumberingPosCO">
|
||||
<property name="enabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Side where formulas are numbered</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_1">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>234</width>
|
||||
<height>17</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<customwidgets>
|
||||
|
@ -1,7 +1,8 @@
|
||||
<ui version="4.0" >
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>PreambleUi</class>
|
||||
<widget class="QWidget" name="PreambleUi" >
|
||||
<property name="geometry" >
|
||||
<widget class="QWidget" name="PreambleUi">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
@ -9,19 +10,38 @@
|
||||
<height>278</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle" >
|
||||
<property name="windowTitle">
|
||||
<string/>
|
||||
</property>
|
||||
<layout class="QGridLayout" >
|
||||
<property name="margin" >
|
||||
<layout class="QGridLayout">
|
||||
<property name="leftMargin">
|
||||
<number>11</number>
|
||||
</property>
|
||||
<property name="spacing" >
|
||||
<property name="topMargin">
|
||||
<number>11</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>11</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>11</number>
|
||||
</property>
|
||||
<property name="spacing">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<item row="0" column="0" >
|
||||
<widget class="QTextEdit" name="preambleTE" >
|
||||
<property name="acceptRichText" >
|
||||
<item row="1" column="0">
|
||||
<widget class="QLineEdit" name="findLE"/>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QPushButton" name="findButtonPB">
|
||||
<property name="text">
|
||||
<string>Find</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0" colspan="2">
|
||||
<widget class="QTextEdit" name="preambleTE">
|
||||
<property name="acceptRichText">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
@ -29,7 +49,7 @@
|
||||
</layout>
|
||||
</widget>
|
||||
<includes>
|
||||
<include location="local" >qt_i18n.h</include>
|
||||
<include location="local">qt_i18n.h</include>
|
||||
</includes>
|
||||
<resources/>
|
||||
<connections/>
|
||||
|
@ -249,6 +249,7 @@ docstring bibitemWidest(Buffer const & buffer, OutputParams const & runparams)
|
||||
ParagraphList::const_iterator it = buffer.paragraphs().begin();
|
||||
ParagraphList::const_iterator end = buffer.paragraphs().end();
|
||||
|
||||
bool is_literal = false;
|
||||
for (; it != end; ++it) {
|
||||
if (it->insetList().empty())
|
||||
continue;
|
||||
@ -274,11 +275,14 @@ docstring bibitemWidest(Buffer const & buffer, OutputParams const & runparams)
|
||||
if (wx > w) {
|
||||
w = wx;
|
||||
lbl = label;
|
||||
is_literal = (bitem->getParam("literal") == "true");
|
||||
}
|
||||
}
|
||||
|
||||
if (!lbl.empty()) {
|
||||
InsetCommandParams p(BIBITEM_CODE);
|
||||
if (is_literal)
|
||||
p["literal"] = from_ascii("true");
|
||||
return p.prepareCommand(runparams, lbl, ParamInfo::HANDLING_LATEXIFY);
|
||||
}
|
||||
|
||||
|
@ -59,6 +59,12 @@ InsetCitation::~InsetCitation()
|
||||
}
|
||||
|
||||
|
||||
// May well be over-ridden when session settings are loaded
|
||||
// in GuiCitation. Unfortunately, that will not happen until
|
||||
// such a dialog is created.
|
||||
bool InsetCitation::last_literal = true;
|
||||
|
||||
|
||||
ParamInfo const & InsetCitation::findInfo(string const & /* cmdName */)
|
||||
{
|
||||
static ParamInfo param_info_;
|
||||
|
@ -82,10 +82,14 @@ public:
|
||||
static bool isCompatibleCommand(std::string const &);
|
||||
//@}
|
||||
///
|
||||
void redoLabel() { cache.recalculate = true; }
|
||||
///
|
||||
CitationStyle getCitationStyle(BufferParams const & bp, std::string const & input,
|
||||
std::vector<CitationStyle> const & valid_styles) const;
|
||||
///
|
||||
std::map<docstring, docstring> getQualifiedLists(docstring const p) const;
|
||||
///
|
||||
static bool last_literal;
|
||||
|
||||
private:
|
||||
/// tries to make a pretty label and makes a basic one if not
|
||||
|
@ -1150,7 +1150,8 @@ void unifyGraphicsGroups(Buffer & b, string const & argument)
|
||||
InsetGraphicsParams params;
|
||||
InsetGraphics::string2params(argument, b, params);
|
||||
|
||||
b.undo().beginUndoGroup();
|
||||
// This handles undo groups automagically
|
||||
UndoGroupHelper ugh(&b);
|
||||
Inset & inset = b.inset();
|
||||
InsetIterator it = inset_iterator_begin(inset);
|
||||
InsetIterator const end = inset_iterator_end(inset);
|
||||
@ -1165,7 +1166,6 @@ void unifyGraphicsGroups(Buffer & b, string const & argument)
|
||||
}
|
||||
}
|
||||
}
|
||||
b.undo().endUndoGroup();
|
||||
}
|
||||
|
||||
|
||||
|
@ -97,12 +97,12 @@ void InsetLabel::updateLabelAndRefs(docstring const & new_label,
|
||||
if (label == old_label)
|
||||
return;
|
||||
|
||||
buffer().undo().beginUndoGroup();
|
||||
// This handles undo groups automagically
|
||||
UndoGroupHelper ugh(&buffer());
|
||||
if (cursor)
|
||||
cursor->recordUndo();
|
||||
setParam("name", label);
|
||||
updateReferences(old_label, label);
|
||||
buffer().undo().endUndoGroup();
|
||||
}
|
||||
|
||||
|
||||
|
@ -157,6 +157,7 @@ void RenderGraphic::metrics(MetricsInfo & mi, Dimension & dim) const
|
||||
dim.des = 0;
|
||||
|
||||
int font_width = 0;
|
||||
int font_height = 0;
|
||||
|
||||
FontInfo msgFont(mi.base.font);
|
||||
msgFont.setFamily(SANS_FAMILY);
|
||||
@ -166,6 +167,7 @@ void RenderGraphic::metrics(MetricsInfo & mi, Dimension & dim) const
|
||||
if (!justname.empty()) {
|
||||
msgFont.setSize(FONT_SIZE_FOOTNOTE);
|
||||
font_width = theFontMetrics(msgFont).width(justname);
|
||||
font_height = theFontMetrics(msgFont).maxHeight();
|
||||
}
|
||||
|
||||
docstring const msg = statusMessage(params_, loader_.status());
|
||||
@ -173,9 +175,12 @@ void RenderGraphic::metrics(MetricsInfo & mi, Dimension & dim) const
|
||||
msgFont.setSize(FONT_SIZE_TINY);
|
||||
font_width = max(font_width,
|
||||
theFontMetrics(msgFont).width(msg));
|
||||
font_height += theFontMetrics(msgFont).maxAscent();
|
||||
dim.des = theFontMetrics(msgFont).maxDescent();
|
||||
}
|
||||
|
||||
dim.wid = max(50, font_width + 15);
|
||||
dim.asc = max(50, font_height + 15);
|
||||
|
||||
dim_ = dim;
|
||||
}
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user