[Libreoffice-commits] core.git: Branch 'distro/collabora/cp-4.2' - 21 commits - canvas/source editeng/source filter/source include/vcl sc/inc sc/source sdext/source sd/source sfx2/source starmath/source sw/qa sw/source vcl/generic vcl/inc vcl/null vcl/source vcl/unx writerfilter/source

Luboš Luňák l.lunak at collabora.com
Tue Apr 22 00:54:56 PDT 2014


 canvas/source/cairo/cairo_canvasbitmap.cxx              |    2 
 canvas/source/cairo/cairo_xlib_cairo.cxx                |    9 
 editeng/source/misc/svxacorr.cxx                        |   18 
 filter/source/graphicfilter/ipcx/ipcx.cxx               |    9 
 filter/source/graphicfilter/itiff/itiff.cxx             |   80 +
 filter/source/graphicfilter/itiff/lzwdecom.cxx          |   14 
 filter/source/msfilter/msdffimp.cxx                     |   11 
 include/vcl/bitmap.hxx                                  |    6 
 include/vcl/bitmapex.hxx                                |    7 
 include/vcl/gdimtf.hxx                                  |    2 
 include/vcl/printerinfomanager.hxx                      |    4 
 sc/inc/scopetools.hxx                                   |   11 
 sc/source/core/data/column2.cxx                         |    9 
 sc/source/core/tool/scopetools.cxx                      |   11 
 sc/source/ui/inc/output.hxx                             |    2 
 sc/source/ui/undo/undoblk3.cxx                          |   11 
 sc/source/ui/unoobj/chart2uno.cxx                       |    5 
 sc/source/ui/view/output2.cxx                           |   76 +
 sc/source/ui/view/tabview3.cxx                          |    3 
 sd/source/ui/animations/CustomAnimationCreateDialog.cxx |    8 
 sd/source/ui/remotecontrol/BluetoothServer.cxx          |  673 ++++++++++++++--
 sd/source/ui/remotecontrol/BufferedStreamSocket.cxx     |    2 
 sd/source/ui/remotecontrol/Communicator.cxx             |    3 
 sdext/source/presenter/PresenterToolBar.cxx             |   16 
 sfx2/source/doc/guisaveas.cxx                           |    3 
 starmath/source/dialog.cxx                              |    2 
 sw/qa/extras/ooxmlimport/data/fdo55381.docx             |binary
 sw/qa/extras/ooxmlimport/ooxmlimport.cxx                |    9 
 sw/qa/extras/rtfimport/data/fdo75735.rtf                |    8 
 sw/qa/extras/rtfimport/rtfimport.cxx                    |    7 
 sw/source/core/fields/reffld.cxx                        |   72 -
 vcl/generic/print/printerjob.cxx                        |    2 
 vcl/inc/cupsmgr.hxx                                     |    2 
 vcl/null/printerinfomanager.cxx                         |    2 
 vcl/source/gdi/bitmap3.cxx                              |   28 
 vcl/source/gdi/bitmapex.cxx                             |    4 
 vcl/source/gdi/gdimtf.cxx                               |   25 
 vcl/unx/generic/printer/cupsmgr.cxx                     |    4 
 vcl/unx/generic/printer/printerinfomanager.cxx          |    2 
 vcl/unx/kde4/KDEXLib.cxx                                |   17 
 vcl/unx/kde4/VCLKDEApplication.hxx                      |    8 
 vcl/unx/x11/xlimits.cxx                                 |   13 
 writerfilter/source/dmapper/DomainMapper.cxx            |   12 
 writerfilter/source/dmapper/DomainMapper_Impl.cxx       |   19 
 writerfilter/source/rtftok/rtfdocumentimpl.cxx          |    2 
 writerfilter/source/rtftok/rtfsprm.cxx                  |    6 
 writerfilter/source/rtftok/rtfsprm.hxx                  |    2 
 47 files changed, 997 insertions(+), 244 deletions(-)

New commits:
commit 2708f679a74c0a3278aabc83a8d6d0d774afd81f
Author: Luboš Luňák <l.lunak at collabora.com>
Date:   Sun Apr 20 14:29:27 2014 +0200

    adjust output file extension when exporting (bnc#870581)
    
    If foo.odt is open, 'foo.odt' is the file name passed to the file dialog
    for File->Export to PDF (simply because it's the document name).  If automatic
    file extension is enabled, the file dialog will fix this to the PDF file type,
    but if disabled, the default filename will remain foo.odt, possibly overwriting
    the source file if the user confirms without checking.
    
    (cherry picked from commit cadf6cc31ffa000d1fe8e42cc3e6cd427e0104bd)
    Signed-off-by: Andras Timar <andras.timar at collabora.com>
    
    Change-Id: I46504630b5f4e489d5a0cedf0b2b358305763722

diff --git a/sfx2/source/doc/guisaveas.cxx b/sfx2/source/doc/guisaveas.cxx
index 9a8d84b..446d9d5 100644
--- a/sfx2/source/doc/guisaveas.cxx
+++ b/sfx2/source/doc/guisaveas.cxx
@@ -991,6 +991,9 @@ sal_Bool ModelData_Impl::OutputFileDialog( sal_Int8 nStoreMode,
                                         OUString("UIName"),
                                         OUString() );
         pFileDlg->SetCurrentFilter( aFilterUIName );
+        aAdjustToType = aPreselectedFilterPropsHM.getUnpackedValueOrDefault(
+                                        OUString("Type"),
+                                        OUString() );
     }
     // it is no export, bSetStandardName == true means that user agreed to store document in the default (default default ;-)) format
     else if ( bSetStandardName || GetStorable()->hasLocation() )
commit 793aeb20972686c9e283650598afd6b296716410
Author: Luboš Luňák <l.lunak at collabora.com>
Date:   Mon Apr 21 19:10:37 2014 +0200

    handle properly page breaks even if a page contains only a frame (fdo#55381)
    
    The test document has 4 pages which only contain frames, first 3 pages
    (sections) have <p> block with <framePr> and another <p> with just <sectPr>,
    and the second paragraph would be removed, thus there would be no nodes on which
    to actually set the page style and they would be set on nodes for the previous
    page, overwriting its page style. The last page does not have its own <p>
    at all, so it needs to be faked.
    
    The changes in finishParagraph() are because of e.g. the comments-nested.odt
    sw test, which there causes exception because of unknown property ParaStyleName
    (comments do not use those it seems) and the code is skipped over (which
    is probably a bug on its own, but it's unrelated to this change otherwise).
    
    Change-Id: I9d37f992407a9b649c710d2a031ec4447fb11771

diff --git a/sw/qa/extras/ooxmlimport/data/fdo55381.docx b/sw/qa/extras/ooxmlimport/data/fdo55381.docx
new file mode 100644
index 0000000..ffeae1f
Binary files /dev/null and b/sw/qa/extras/ooxmlimport/data/fdo55381.docx differ
diff --git a/sw/qa/extras/ooxmlimport/ooxmlimport.cxx b/sw/qa/extras/ooxmlimport/ooxmlimport.cxx
index 1c8665b..6c2f3a7 100644
--- a/sw/qa/extras/ooxmlimport/ooxmlimport.cxx
+++ b/sw/qa/extras/ooxmlimport/ooxmlimport.cxx
@@ -1645,6 +1645,15 @@ DECLARE_OOXMLIMPORT_TEST(testStrictLockedcanvas, "strict-lockedcanvas.docx")
     getShape(1);
 }
 
+DECLARE_OOXMLIMPORT_TEST(testFdo55381, "fdo55381.docx")
+{
+    uno::Reference<frame::XModel> xModel(mxComponent, uno::UNO_QUERY);
+    uno::Reference<text::XTextViewCursorSupplier> xTextViewCursorSupplier(xModel->getCurrentController(), uno::UNO_QUERY);
+    uno::Reference<text::XPageCursor> xCursor(xTextViewCursorSupplier->getViewCursor(), uno::UNO_QUERY);
+    xCursor->jumpToLastPage();
+    CPPUNIT_ASSERT_EQUAL(sal_Int16(4), xCursor->getPage());
+}
+
 #endif
 
 CPPUNIT_PLUGIN_IMPLEMENT();
diff --git a/writerfilter/source/dmapper/DomainMapper.cxx b/writerfilter/source/dmapper/DomainMapper.cxx
index dbb16d0..c7625e3 100644
--- a/writerfilter/source/dmapper/DomainMapper.cxx
+++ b/writerfilter/source/dmapper/DomainMapper.cxx
@@ -3643,6 +3643,18 @@ void DomainMapper::lcl_endSectionGroup()
 {
     m_pImpl->CheckUnregisteredFrameConversion();
     m_pImpl->ExecuteFrameConversion();
+    if(m_pImpl->GetIsFirstParagraphInSection())
+    {
+        // This section has no paragraph at all (e.g. they are all actually in a frame).
+        // If this section has a page break, there would be nothing to apply to the page
+        // style, so force a dummy paragraph.
+        lcl_startParagraphGroup();
+        lcl_startCharacterGroup();
+        sal_uInt8 sBreak[] = { 0xd };
+        lcl_text(sBreak, 1);
+        lcl_endCharacterGroup();
+        lcl_endParagraphGroup();
+    }
     PropertyMapPtr pContext = m_pImpl->GetTopContextOfType(CONTEXT_SECTION);
     SectionPropertyMap* pSectionContext = dynamic_cast< SectionPropertyMap* >( pContext.get() );
     OSL_ENSURE(pSectionContext, "SectionContext unavailable!");
diff --git a/writerfilter/source/dmapper/DomainMapper_Impl.cxx b/writerfilter/source/dmapper/DomainMapper_Impl.cxx
index 7fe53ae8..6591673 100644
--- a/writerfilter/source/dmapper/DomainMapper_Impl.cxx
+++ b/writerfilter/source/dmapper/DomainMapper_Impl.cxx
@@ -1140,12 +1140,6 @@ void DomainMapper_Impl::finishParagraph( PropertyMapPtr pPropertyMap )
                 uno::Reference< text::XTextRange > xParaEnd( xCur, uno::UNO_QUERY );
                 CheckParaRedline( xParaEnd );
 
-                m_bIsFirstParaInSection = false;
-                m_bIsLastParaInSection = false;
-                m_bParaChanged = false;
-
-                // Reset the frame properties for the next paragraph
-                pParaContext->ResetFrameProperties();
             }
             if( !bKeepLastParagraphProperties )
                 rAppendContext.pLastParagraphProperties = pToBeSavedProperties;
@@ -1154,11 +1148,22 @@ void DomainMapper_Impl::finishParagraph( PropertyMapPtr pPropertyMap )
         {
             OSL_FAIL( "IllegalArgumentException in DomainMapper_Impl::finishParagraph" );
         }
-        catch(const uno::Exception&)
+        catch(const uno::Exception& e)
         {
+            SAL_WARN( "writerfilter", "finishParagraph() exception: " << e.Message );
         }
     }
 
+    m_bParaChanged = false;
+    if(!pParaContext->IsFrameMode())
+    { // If the paragraph is in a frame, it's not a paragraph of the section itself.
+        m_bIsFirstParaInSection = false;
+        m_bIsLastParaInSection = false;
+    }
+
+    // Reset the frame properties for the next paragraph
+    pParaContext->ResetFrameProperties();
+
 #ifdef DEBUG_DOMAINMAPPER
     dmapper_logger->endElement();
 #endif
commit e098576f4629a3ff42b963d7f589ed41c0cadca2
Author: László Németh <nemeth at numbertext.org>
Date:   Mon Apr 21 12:43:32 2014 +0200

    fdo#77603 new wildcard in autocorrection: .* instead of *
    
    (cherry picked from commit 022e351c2431e0260220a51a54d576f49f789ebc)
    
    Conflicts:
    
    	editeng/source/misc/svxacorr.cxx
    
    Change-Id: I04700e742239c97de39cf502fd8b0845b03c4e3a

diff --git a/editeng/source/misc/svxacorr.cxx b/editeng/source/misc/svxacorr.cxx
index 667f561..f0501f3 100644
--- a/editeng/source/misc/svxacorr.cxx
+++ b/editeng/source/misc/svxacorr.cxx
@@ -72,7 +72,6 @@ static const int C_NONE             = 0x00;
 static const int C_FULL_STOP        = 0x01;
 static const int C_EXCLAMATION_MARK = 0x02;
 static const int C_QUESTION_MARK    = 0x04;
-static const int C_ASTERISK         = 0x2A;
 static const sal_Unicode cNonBreakingSpace = 0xA0;
 
 static const sal_Char pXMLImplWrdStt_ExcptLstStr[] = "WordExceptList.xml";
@@ -2761,7 +2760,7 @@ const SvxAutocorrWord* SvxAutocorrWordList::WordMatches(const SvxAutocorrWord *p
                                       sal_Int32 nEndPos) const
 {
     const OUString& rChk = pFnd->GetShort();
-    xub_StrLen left_wildcard = ( rChk[0] == C_ASTERISK ) ? 1 : 0; // "*word" pattern?
+    xub_StrLen left_wildcard = rChk.startsWith( ".*" ) ? 2 : 0; // ".*word" pattern?
     xub_StrLen nSttWdPos = nEndPos;
     if( nEndPos >= rChk.getLength() - left_wildcard)
     {
@@ -2774,22 +2773,25 @@ const SvxAutocorrWord* SvxAutocorrWordList::WordMatches(const SvxAutocorrWord *p
         {
             TransliterationWrapper& rCmp = GetIgnoreTranslWrapper();
             OUString sWord = rTxt.copy(nCalcStt, rChk.getLength() - left_wildcard);
-            if( (!left_wildcard && rCmp.isEqual( rChk, sWord )) || (left_wildcard && rCmp.isEqual( rChk.copy(1), sWord) ))
+            if( (!left_wildcard && rCmp.isEqual( rChk, sWord )) || (left_wildcard && rCmp.isEqual( rChk.copy(left_wildcard), sWord) ))
             {
                 rStt = nCalcStt;
                 if (!left_wildcard) return pFnd;
-                // get the first word delimiter position before the matching "*word" pattern
+                // get the first word delimiter position before the matching ".*word" pattern
                 while( rStt && !(bWasWordDelim = IsWordDelim( rTxt[ --rStt ])))
                     ;
                 if (bWasWordDelim) rStt++;
-                SvxAutocorrWord* pNew = new SvxAutocorrWord(rTxt.copy(rStt, nEndPos - rStt), rTxt.copy(rStt, nEndPos - rStt - rChk.getLength() + 1) + pFnd->GetLong());
+                OUString left_pattern = rTxt.copy(rStt, nEndPos - rStt - rChk.getLength() + left_wildcard);
+                // avoid double spaces before simple "word" replacement
+                left_pattern += (left_pattern.getLength() == 0 && pFnd->GetLong()[0] == 0x20) ? pFnd->GetLong().copy(1) : pFnd->GetLong();
+                SvxAutocorrWord* pNew = new SvxAutocorrWord(rTxt.copy(rStt, nEndPos - rStt), left_pattern);
                 if( Insert( pNew ) ) return pNew; else delete pNew;
             }
         }
-        // match "word*" patterns, eg. "i18n*"
-        if ( rChk[ rChk.getLength() - 1] == C_ASTERISK )
+        // match "word.*" patterns, eg. "i18n.*"
+        if ( rChk.endsWith( ".*" ) )
         {
-            OUString sTmp( rChk.copy( 0, rChk.getLength() - 1 ) );
+            OUString sTmp( rChk.copy( 0, rChk.getLength() - 2 ) );
             // Get the last word delimiter position
             bool not_suffix;
             while( nSttWdPos && !(bWasWordDelim = IsWordDelim( rTxt[ --nSttWdPos ])))
commit eae151d7784e5a1f4400d2042ec2683a89ec6b36
Author: Luboš Luňák <l.lunak at collabora.com>
Date:   Tue Mar 25 12:20:16 2014 +0100

    prevent KDE/Qt from interfering with the session manager
    
    I occassionally get lockups in IceProcessMessages() called from QtCore,
    I'm actually not exactly sure why, as theoretically two connections
    from one app shouldn't be a problem, but since LO does its own
    session handling, there's no need to the KDE/Qt code to be involved,
    so prevent it from connecting to the session manager altogether.
    
    Change-Id: Iebe20d4cb5403e5fea8bd5d8c1f69b62d1c2907b
    (cherry picked from commit 71f2aff7a56cef4e133abad3c2e447c76c5ee1fe)
    Reviewed-on: https://gerrit.libreoffice.org/9079
    Reviewed-by: Maxim Monastirsky <momonasmon at gmail.com>
    Tested-by: Maxim Monastirsky <momonasmon at gmail.com>

diff --git a/vcl/unx/kde4/KDEXLib.cxx b/vcl/unx/kde4/KDEXLib.cxx
index 820d39a..e4900a7 100644
--- a/vcl/unx/kde4/KDEXLib.cxx
+++ b/vcl/unx/kde4/KDEXLib.cxx
@@ -166,8 +166,23 @@ void KDEXLib::Init()
 
     KCmdLineArgs::init( m_nFakeCmdLineArgs, m_pAppCmdLineArgs, kAboutData );
 
+    // LO does its own session management, so prevent KDE/Qt from interfering
+    // (QApplication::disableSessionManagement(false) wouldn't quite do,
+    // since that still actually connects to the session manager, it just
+    // won't save the application data on session shutdown).
+    char* session_manager = NULL;
+    if( getenv( "SESSION_MANAGER" ) != NULL )
+    {
+        session_manager = strdup( getenv( "SESSION_MANAGER" ));
+        unsetenv( "SESSION_MANAGER" );
+    }
     m_pApplication = new VCLKDEApplication();
-    kapp->disableSessionManagement();
+    if( session_manager != NULL )
+    {
+        setenv( "SESSION_MANAGER", session_manager, 1 );
+        free( session_manager );
+    }
+
     KApplication::setQuitOnLastWindowClosed(false);
 
 #if KDE_HAVE_GLIB
diff --git a/vcl/unx/kde4/VCLKDEApplication.hxx b/vcl/unx/kde4/VCLKDEApplication.hxx
index 412ee34..4ce0b2c 100644
--- a/vcl/unx/kde4/VCLKDEApplication.hxx
+++ b/vcl/unx/kde4/VCLKDEApplication.hxx
@@ -21,22 +21,14 @@
 
 #define Region QtXRegion
 
-#include <QSessionManager>
-
 #include <kapplication.h>
 
 #undef Region
 
-/* #i59042# override KApplications method for session management
- * since it will interfere badly with our own.
- */
 class VCLKDEApplication : public KApplication
 {
     public:
         VCLKDEApplication();
-
-        virtual void commitData(QSessionManager&) {};
-
         virtual bool x11EventFilter(XEvent* event);
 };
 
commit 761932cbcc2479bfd4a7af15488587cfe685996d
Author: Miklos Vajna <vmiklos at collabora.co.uk>
Date:   Fri Apr 18 16:47:14 2014 +0200

    fdo#75735 RTF import: fix COW when writing a nested structure
    
    Regression from a48e2fd9049797110b3b2505c363557284987ca8 (fdo#44736 -
    convert RTFSprms to a copy-on-write structure., 2012-12-07)
    
    (cherry picked from commit 6b6e4d471c2954d34d280398ed1c986d7fb27ae1)
    
    Conflicts:
    	writerfilter/source/rtftok/rtfsprm.hxx
    
    Change-Id: I2538f440e29cef6d40db2ea914e4afcbfe411890
    Reviewed-on: https://gerrit.libreoffice.org/9100
    Tested-by: David Tardon <dtardon at redhat.com>
    Reviewed-by: David Tardon <dtardon at redhat.com>

diff --git a/sw/qa/extras/rtfimport/data/fdo75735.rtf b/sw/qa/extras/rtfimport/data/fdo75735.rtf
new file mode 100644
index 0000000..7d844bd
--- /dev/null
+++ b/sw/qa/extras/rtfimport/data/fdo75735.rtf
@@ -0,0 +1,8 @@
+{\rtf1\ansi
+{\fonttbl \f0\froman Times;}
+\pard\tx1440\plain
+{\tx360\tx720\tx1080\tab\tab\tab\tab This is line one.\
+}
+{\tx480\tx960\tab\tab\tab This is line two.\
+}
+}
diff --git a/sw/qa/extras/rtfimport/rtfimport.cxx b/sw/qa/extras/rtfimport/rtfimport.cxx
index 4d61147..908178f 100644
--- a/sw/qa/extras/rtfimport/rtfimport.cxx
+++ b/sw/qa/extras/rtfimport/rtfimport.cxx
@@ -22,6 +22,7 @@
 #include <com/sun/star/style/LineSpacing.hpp>
 #include <com/sun/star/style/LineSpacingMode.hpp>
 #include <com/sun/star/style/ParagraphAdjust.hpp>
+#include <com/sun/star/style/TabStop.hpp>
 #include <com/sun/star/table/BorderLine2.hpp>
 #include <com/sun/star/table/BorderLineStyle.hpp>
 #include <com/sun/star/text/RelOrientation.hpp>
@@ -1628,6 +1629,12 @@ DECLARE_RTFIMPORT_TEST(testFdo77267, "fdo77267.rtf")
     CPPUNIT_ASSERT_EQUAL(style::ParagraphAdjust_CENTER, static_cast<style::ParagraphAdjust>(getProperty<sal_Int16>(getParagraph(1), "ParaAdjust")));
 }
 
+DECLARE_RTFIMPORT_TEST(testFdo75735, "fdo75735.rtf")
+{
+    // Number of tabstops in the second paragraph should be 3, was 6.
+    CPPUNIT_ASSERT_EQUAL(sal_Int32(3), getProperty< uno::Sequence<style::TabStop> >(getParagraph(2), "ParaTabStops").getLength());
+}
+
 CPPUNIT_PLUGIN_IMPLEMENT();
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/writerfilter/source/rtftok/rtfdocumentimpl.cxx b/writerfilter/source/rtftok/rtfdocumentimpl.cxx
index b5a5f13..d06f6bc 100644
--- a/writerfilter/source/rtftok/rtfdocumentimpl.cxx
+++ b/writerfilter/source/rtftok/rtfdocumentimpl.cxx
@@ -83,7 +83,7 @@ static Id lcl_getParagraphBorder(sal_uInt32 nIndex)
 static void lcl_putNestedAttribute(RTFSprms& rSprms, Id nParent, Id nId, RTFValue::Pointer_t pValue,
         bool bOverwrite = true, bool bAttribute = true)
 {
-    RTFValue::Pointer_t pParent = rSprms.find(nParent);
+    RTFValue::Pointer_t pParent = rSprms.find(nParent, /*bFirst=*/true, /*bForWrite=*/true);
     if (!pParent.get())
     {
         RTFSprms aAttributes;
diff --git a/writerfilter/source/rtftok/rtfsprm.cxx b/writerfilter/source/rtftok/rtfsprm.cxx
index ace6735..2af21213 100644
--- a/writerfilter/source/rtftok/rtfsprm.cxx
+++ b/writerfilter/source/rtftok/rtfsprm.cxx
@@ -78,9 +78,13 @@ std::string RTFSprm::toString() const
     return aBuf.makeStringAndClear().getStr();
 }
 
-RTFValue::Pointer_t RTFSprms::find(Id nKeyword, bool bFirst)
+RTFValue::Pointer_t RTFSprms::find(Id nKeyword, bool bFirst, bool bForWrite)
 {
     RTFValue::Pointer_t pValue;
+
+    if (bForWrite)
+        ensureCopyBeforeWrite();
+
     for (RTFSprms::Iterator_t i = m_pSprms->begin(); i != m_pSprms->end(); ++i)
         if (i->first == nKeyword)
         {
diff --git a/writerfilter/source/rtftok/rtfsprm.hxx b/writerfilter/source/rtftok/rtfsprm.hxx
index dc82256..19f0514 100644
--- a/writerfilter/source/rtftok/rtfsprm.hxx
+++ b/writerfilter/source/rtftok/rtfsprm.hxx
@@ -48,7 +48,7 @@ namespace writerfilter {
             RTFSprms(const RTFSprms& rSprms);
             ~RTFSprms();
             RTFSprms& operator=(const RTFSprms& rOther);
-            RTFValue::Pointer_t find(Id nKeyword, bool bFirst = true);
+            RTFValue::Pointer_t find(Id nKeyword, bool bFirst = true, bool bForWrite = false);
             /// Does the same as ->push_back(), except that it can overwrite existing entries.
             void set(Id nKeyword, RTFValue::Pointer_t pValue, bool bOverwrite = true);
             bool erase(Id nKeyword);
commit 99bf0a6a94b6a8c92b18390f863ac46b71815200
Author: Caolán McNamara <caolanm at redhat.com>
Date:   Fri Apr 18 09:45:38 2014 +0100

    Related: rhbz#1088625 PresenterPaintManager seen as NULL
    
    Change-Id: I3b7ba51d48ebc5f9304f6125de0595d41d50ad4d
    (cherry picked from commit 42dd5615429e6273e9169a4bd941ad56fec1e6f6)
    Reviewed-on: https://gerrit.libreoffice.org/9094
    Reviewed-by: Miklos Vajna <vmiklos at collabora.co.uk>
    Tested-by: Miklos Vajna <vmiklos at collabora.co.uk>

diff --git a/sdext/source/presenter/PresenterToolBar.cxx b/sdext/source/presenter/PresenterToolBar.cxx
index 69fb531..53263b5 100644
--- a/sdext/source/presenter/PresenterToolBar.cxx
+++ b/sdext/source/presenter/PresenterToolBar.cxx
@@ -457,7 +457,10 @@ void PresenterToolBar::InvalidateArea (
     const awt::Rectangle& rRepaintBox,
     const bool bSynchronous)
 {
-    mpPresenterController->GetPaintManager()->Invalidate(
+    ::boost::shared_ptr<PresenterPaintManager> xManager(mpPresenterController->GetPaintManager());
+    if (!xManager)
+        return;
+    xManager->Invalidate(
         mxWindow,
         rRepaintBox,
         bSynchronous);
@@ -467,7 +470,11 @@ void PresenterToolBar::RequestLayout (void)
 {
     mbIsLayoutPending = true;
 
-    mpPresenterController->GetPaintManager()->Invalidate(mxWindow);
+    ::boost::shared_ptr<PresenterPaintManager> xManager(mpPresenterController->GetPaintManager());
+    if (!xManager)
+        return;
+
+    xManager->Invalidate(mxWindow);
 }
 
 geometry::RealSize2D PresenterToolBar::GetMinimalSize (void)
@@ -822,7 +829,10 @@ void PresenterToolBar::Layout (
     }
 
     // The whole window has to be repainted.
-    mpPresenterController->GetPaintManager()->Invalidate(mxWindow);
+    ::boost::shared_ptr<PresenterPaintManager> xManager(mpPresenterController->GetPaintManager());
+    if (!xManager)
+        return;
+    xManager->Invalidate(mxWindow);
 }
 
 geometry::RealSize2D PresenterToolBar::CalculatePartSize (
commit 6b56cf3ec870ecdf7e9a29b10473a6168b1cc94d
Author: Stephan Bergmann <sbergman at redhat.com>
Date:   Thu Jan 9 23:09:12 2014 +0100

    every even numbered print job is reported as failed
    
    because of.
    bool bSuccess;
    ...
    bSuccess &= ...endSpool(...);
    
    in PspSalPrinter::StartJob
    
    was...
    
    endSpool return value is effectively success flag, not job ID
    
    (cherry picked from commit e6323214830895d1c76ec44ee53990bf577fbda2)
    
    Change-Id: I5b96eeff80ca29f0f8f24ee6da7a2ca76cbb05ce
    Reviewed-on: https://gerrit.libreoffice.org/9093
    Reviewed-by: Miklos Vajna <vmiklos at collabora.co.uk>
    Tested-by: Miklos Vajna <vmiklos at collabora.co.uk>

diff --git a/include/vcl/printerinfomanager.hxx b/include/vcl/printerinfomanager.hxx
index 96e7846..7e3ccd6 100644
--- a/include/vcl/printerinfomanager.hxx
+++ b/include/vcl/printerinfomanager.hxx
@@ -211,8 +211,8 @@ public:
     // close the FILE* returned by startSpool and does the actual spooling
     // set bBanner to "false" will attempt to suppress banner printing
     // set bBanner to "true" will rely on the system default
-    // returns a numerical job id
-    virtual int endSpool( const OUString& rPrinterName, const OUString& rJobTitle, FILE* pFile, const JobData& rDocumentJobData, bool bBanner );
+    // returns true on success
+    virtual bool endSpool( const OUString& rPrinterName, const OUString& rJobTitle, FILE* pFile, const JobData& rDocumentJobData, bool bBanner );
 
     // for spadmin: whether adding or removing a printer is possible
     virtual bool addOrRemovePossible() const;
diff --git a/vcl/generic/print/printerjob.cxx b/vcl/generic/print/printerjob.cxx
index 7c1b359..f611c26 100644
--- a/vcl/generic/print/printerjob.cxx
+++ b/vcl/generic/print/printerjob.cxx
@@ -530,7 +530,7 @@ PrinterJob::EndJob ()
     else
     {
         PrinterInfoManager& rPrinterInfoManager = PrinterInfoManager::get();
-        if (0 == rPrinterInfoManager.endSpool( m_aLastJobData.m_aPrinterName,
+        if (!rPrinterInfoManager.endSpool( m_aLastJobData.m_aPrinterName,
             maJobTitle, pDestFILE, m_aDocumentJobData, true ))
         {
             bSuccess = sal_False;
diff --git a/vcl/inc/cupsmgr.hxx b/vcl/inc/cupsmgr.hxx
index 8c659fe..a8c06bb 100644
--- a/vcl/inc/cupsmgr.hxx
+++ b/vcl/inc/cupsmgr.hxx
@@ -78,7 +78,7 @@ public:
     const char* authenticateUser( const char* );
 
     virtual FILE* startSpool( const OUString& rPrinterName, bool bQuickCommand );
-    virtual int endSpool( const OUString& rPrinterName, const OUString& rJobTitle, FILE* pFile, const JobData& rDocumentJobData, bool bBanner );
+    virtual bool endSpool( const OUString& rPrinterName, const OUString& rJobTitle, FILE* pFile, const JobData& rDocumentJobData, bool bBanner );
     virtual void setupJobContextData( JobData& rData );
 
     /// changes the info about a named printer
diff --git a/vcl/null/printerinfomanager.cxx b/vcl/null/printerinfomanager.cxx
index a480856..4845ec3 100644
--- a/vcl/null/printerinfomanager.cxx
+++ b/vcl/null/printerinfomanager.cxx
@@ -147,7 +147,7 @@ FILE* PrinterInfoManager::startSpool( const OUString& /* rPrintername */, bool /
     return NULL;
 }
 
-int PrinterInfoManager::endSpool( const OUString& /*rPrintername*/, const OUString& /*rJobTitle*/, FILE* /* pFile */, const JobData& /*rDocumentJobData*/, bool /*bBanner*/ )
+bool PrinterInfoManager::endSpool( const OUString& /*rPrintername*/, const OUString& /*rJobTitle*/, FILE* /* pFile */, const JobData& /*rDocumentJobData*/, bool /*bBanner*/ )
 {
     return true;
 }
diff --git a/vcl/unx/generic/printer/cupsmgr.cxx b/vcl/unx/generic/printer/cupsmgr.cxx
index 069df7d..ecf44e7 100644
--- a/vcl/unx/generic/printer/cupsmgr.cxx
+++ b/vcl/unx/generic/printer/cupsmgr.cxx
@@ -640,7 +640,7 @@ void CUPSManager::getOptionsFromDocumentSetup( const JobData& rJob, bool bBanner
     }
 }
 
-int CUPSManager::endSpool( const OUString& rPrintername, const OUString& rJobTitle, FILE* pFile, const JobData& rDocumentJobData, bool bBanner )
+bool CUPSManager::endSpool( const OUString& rPrintername, const OUString& rJobTitle, FILE* pFile, const JobData& rDocumentJobData, bool bBanner )
 {
     OSL_TRACE( "endSpool: %s, %s, copy count = %d",
                OUStringToOString( rPrintername, RTL_TEXTENCODING_UTF8 ).getStr(),
@@ -699,7 +699,7 @@ int CUPSManager::endSpool( const OUString& rPrintername, const OUString& rJobTit
             cupsFreeOptions( nNumOptions, pOptions );
     }
 
-    return nJobID;
+    return nJobID != 0;
 }
 
 
diff --git a/vcl/unx/generic/printer/printerinfomanager.cxx b/vcl/unx/generic/printer/printerinfomanager.cxx
index 4f8f56e..45b9f62 100644
--- a/vcl/unx/generic/printer/printerinfomanager.cxx
+++ b/vcl/unx/generic/printer/printerinfomanager.cxx
@@ -1117,7 +1117,7 @@ FILE* PrinterInfoManager::startSpool( const OUString& rPrintername, bool bQuickC
     return popen (aShellCommand.getStr(), "w");
 }
 
-int PrinterInfoManager::endSpool( const OUString& /*rPrintername*/, const OUString& /*rJobTitle*/, FILE* pFile, const JobData& /*rDocumentJobData*/, bool /*bBanner*/ )
+bool PrinterInfoManager::endSpool( const OUString& /*rPrintername*/, const OUString& /*rJobTitle*/, FILE* pFile, const JobData& /*rDocumentJobData*/, bool /*bBanner*/ )
 {
     return (0 == pclose( pFile ));
 }
commit c31af75c20c33cbb195ed56723fc3f1219e20962
Author: Luboš Luňák <l.lunak at collabora.com>
Date:   Fri Apr 18 20:46:34 2014 +0200

    handle strange brightness+contrast adjustment from msoffice (fdo#38410)
    
    LO uses basically the formula "newpixel=(oldpixel-128)*contrast+128+brightness",
    i.e. contrast is applied first. It looks like there's no "oficial" formula for this,
    so a formula that applies brightness first would be ok too. MSO for some weird reason
    apparently uses a formula that applies half of brightness before contrast and
    half afterwards (insert funny political correctness or compromise joke here).
    While the result is the same like with the LO formula if only either brightness
    or contrast is adjusted, the result is different if both are involved. Just modify
    the image using the MSO algorithm if this is the case.
    
    Conflicts:
    	filter/source/msfilter/msdffimp.cxx
    	include/vcl/bitmap.hxx
    	include/vcl/bitmapex.hxx
    	include/vcl/gdimtf.hxx
    	vcl/source/gdi/bitmap3.cxx
    	vcl/source/gdi/bitmapex.cxx
    	vcl/source/gdi/gdimtf.cxx
    
    Change-Id: I55fe8f395832685b90f024cf2f58b0797c1ba588
    Reviewed-on: https://gerrit.libreoffice.org/9099
    Reviewed-by: Miklos Vajna <vmiklos at collabora.co.uk>
    Tested-by: Miklos Vajna <vmiklos at collabora.co.uk>

diff --git a/filter/source/msfilter/msdffimp.cxx b/filter/source/msfilter/msdffimp.cxx
index 63847b3..472e1a5 100644
--- a/filter/source/msfilter/msdffimp.cxx
+++ b/filter/source/msfilter/msdffimp.cxx
@@ -3817,7 +3817,12 @@ SdrObject* SvxMSDffManager::ImportGraphic( SvStream& rSt, SfxItemSet& rSet, cons
 
             if ( nContrast || nBrightness || ( nGamma != 0x10000 ) || ( eDrawMode != GRAPHICDRAWMODE_STANDARD ) )
             {
-                if ( ( rObjData.nSpFlags & SP_FOLESHAPE ) == 0 )
+                // MSO uses a different algorithm for contrast+brightness, LO applies contrast before brightness,
+                // while MSO apparently applies half of brightness before contrast and half after. So if only
+                // contrast or brightness need to be altered, the result is the same, but if both are involved,
+                // there's no way to map that, so just force a conversion of the image.
+                bool needsConversion = nContrast != 0 && nBrightness != 0;
+                if ( ( rObjData.nSpFlags & SP_FOLESHAPE ) == 0 && !needsConversion )
                 {
                     if ( nBrightness )
                         rSet.Put( SdrGrafLuminanceItem( nBrightness ) );
@@ -3842,7 +3847,7 @@ SdrObject* SvxMSDffManager::ImportGraphic( SvStream& rSt, SfxItemSet& rSet, cons
                         {
                             BitmapEx    aBitmapEx( aGraf.GetBitmapEx() );
                             if ( nBrightness || nContrast || ( nGamma != 0x10000 ) )
-                                aBitmapEx.Adjust( nBrightness, (sal_Int16)nContrast, 0, 0, 0, (double)nGamma / 0x10000, sal_False );
+                                aBitmapEx.Adjust( nBrightness, (sal_Int16)nContrast, 0, 0, 0, (double)nGamma / 0x10000, false, true );
                             if ( eDrawMode == GRAPHICDRAWMODE_GREYS )
                                 aBitmapEx.Convert( BMP_CONVERSION_8BIT_GREYS );
                             else if ( eDrawMode == GRAPHICDRAWMODE_MONO )
@@ -3856,7 +3861,7 @@ SdrObject* SvxMSDffManager::ImportGraphic( SvStream& rSt, SfxItemSet& rSet, cons
                         {
                             GDIMetaFile aGdiMetaFile( aGraf.GetGDIMetaFile() );
                             if ( nBrightness || nContrast || ( nGamma != 0x10000 ) )
-                                aGdiMetaFile.Adjust( nBrightness, (sal_Int16)nContrast, 0, 0, 0, (double)nGamma / 0x10000, sal_False );
+                                aGdiMetaFile.Adjust( nBrightness, (sal_Int16)nContrast, 0, 0, 0, (double)nGamma / 0x10000, false, true );
                             if ( eDrawMode == GRAPHICDRAWMODE_GREYS )
                                 aGdiMetaFile.Convert( MTF_CONVERSION_8BIT_GREYS );
                             else if ( eDrawMode == GRAPHICDRAWMODE_MONO )
diff --git a/include/vcl/bitmap.hxx b/include/vcl/bitmap.hxx
index adf6b63..621fceb 100644
--- a/include/vcl/bitmap.hxx
+++ b/include/vcl/bitmap.hxx
@@ -779,6 +779,9 @@ public:
         If sal_True, invert the channel values with the logical 'not' operator
 
         @return sal_True, if the operation was completed successfully.
+
+        @param msoBrightness
+        Use the same formula for brightness as used by MSOffice.
      */
     sal_Bool                    Adjust( short nLuminancePercent = 0,
                                     short nContrastPercent = 0,
@@ -786,7 +789,8 @@ public:
                                     short nChannelGPercent = 0,
                                     short nChannelBPercent = 0,
                                     double fGamma = 1.0,
-                                    sal_Bool bInvert = sal_False );
+                                    bool bInvert = false,
+                                    bool msoBrightness = false );
 
     /** Apply specified filter to the bitmap
 
diff --git a/include/vcl/bitmapex.hxx b/include/vcl/bitmapex.hxx
index da23547..8ac6325 100644
--- a/include/vcl/bitmapex.hxx
+++ b/include/vcl/bitmapex.hxx
@@ -343,6 +343,10 @@ public:
         If sal_True, invert the channel values with the logical 'not' operator
 
         @return sal_True, if the operation was completed successfully.
+
+        @param msoFormula
+        Use the same formula for brightness as used by MSOffice.
+
      */
     sal_Bool                Adjust( short nLuminancePercent = 0,
                                 short nContrastPercent = 0,
@@ -350,7 +354,8 @@ public:
                                 short nChannelGPercent = 0,
                                 short nChannelBPercent = 0,
                                 double fGamma = 1.0,
-                                sal_Bool bInvert = sal_False );
+                                bool bInvert = false,
+                                bool msoBrightness = false );
 
     /** Apply specified filter to the bitmap
 
diff --git a/include/vcl/gdimtf.hxx b/include/vcl/gdimtf.hxx
index 8afdc14..d38f863 100644
--- a/include/vcl/gdimtf.hxx
+++ b/include/vcl/gdimtf.hxx
@@ -150,7 +150,7 @@ public:
     void            Adjust( short nLuminancePercent = 0, short nContrastPercent = 0,
                             short nChannelRPercent = 0,  short nChannelGPercent = 0,
                             short nChannelBPercent = 0,  double fGamma = 1.0,
-                            sal_Bool bInvert = sal_False
+                            bool bInvert = false, bool msoBrightness = false
                     );
 
     void            Convert( MtfConversion eConversion );
diff --git a/vcl/source/gdi/bitmap3.cxx b/vcl/source/gdi/bitmap3.cxx
index 5c4905a..4fbe1b8 100644
--- a/vcl/source/gdi/bitmap3.cxx
+++ b/vcl/source/gdi/bitmap3.cxx
@@ -3250,7 +3250,7 @@ sal_Bool Bitmap::Vectorize( GDIMetaFile& rMtf, sal_uInt8 cReduce, sal_uLong nFla
 
 sal_Bool Bitmap::Adjust( short nLuminancePercent, short nContrastPercent,
                      short nChannelRPercent, short nChannelGPercent, short nChannelBPercent,
-                     double fGamma, sal_Bool bInvert )
+                     double fGamma, bool bInvert, bool msoBrightness )
 {
     sal_Bool bRet = sal_False;
 
@@ -3282,8 +3282,11 @@ sal_Bool Bitmap::Adjust( short nLuminancePercent, short nContrastPercent,
             else
                 fM = ( 128.0 + 1.27 * MinMax( nContrastPercent, -100L, 0L ) ) / 128.0;
 
-            // total offset = luminance offset + contrast offset
-            fOff = MinMax( nLuminancePercent, -100L, 100L ) * 2.55 + 128.0 - fM * 128.0;
+            if(!msoBrightness)
+                // total offset = luminance offset + contrast offset
+                fOff = MinMax( nLuminancePercent, -100L, 100L ) * 2.55 + 128.0 - fM * 128.0;
+            else
+                fOff = MinMax( nLuminancePercent, -100L, 100L ) * 2.55;
 
             // channel offset = channel offset  + total offset
             fROff = nChannelRPercent * 2.55 + fOff;
@@ -3297,10 +3300,21 @@ sal_Bool Bitmap::Adjust( short nLuminancePercent, short nContrastPercent,
             // create mapping table
             for( nX = 0L; nX < 256L; nX++ )
             {
-                cMapR[ nX ] = (sal_uInt8) MinMax( FRound( nX * fM + fROff ), 0L, 255L );
-                cMapG[ nX ] = (sal_uInt8) MinMax( FRound( nX * fM + fGOff ), 0L, 255L );
-                cMapB[ nX ] = (sal_uInt8) MinMax( FRound( nX * fM + fBOff ), 0L, 255L );
-
+                if(!msoBrightness)
+                {
+                    cMapR[ nX ] = (sal_uInt8) MinMax( FRound( nX * fM + fROff ), 0L, 255L );
+                    cMapG[ nX ] = (sal_uInt8) MinMax( FRound( nX * fM + fGOff ), 0L, 255L );
+                    cMapB[ nX ] = (sal_uInt8) MinMax( FRound( nX * fM + fBOff ), 0L, 255L );
+                }
+                else
+                {
+                    // LO simply uses (in a somewhat optimized form) "newcolor = (oldcolor-128)*contrast+brightness+128"
+                    // as the formula, i.e. contrast first, brightness afterwards. MSOffice, for whatever weird reason,
+                    // use neither first, but apparently it applies half of brightness before contrast and half afterwards.
+                    cMapR[ nX ] = (sal_uInt8) MinMax( FRound( (nX+fROff/2-128) * fM + 128 + fROff/2 ), 0L, 255L );
+                    cMapG[ nX ] = (sal_uInt8) MinMax( FRound( (nX+fGOff/2-128) * fM + 128 + fGOff/2 ), 0L, 255L );
+                    cMapB[ nX ] = (sal_uInt8) MinMax( FRound( (nX+fBOff/2-128) * fM + 128 + fBOff/2 ), 0L, 255L );
+                }
                 if( bGamma )
                 {
                     cMapR[ nX ] = GAMMA( cMapR[ nX ], fGamma );
diff --git a/vcl/source/gdi/bitmapex.cxx b/vcl/source/gdi/bitmapex.cxx
index 6deb1db..98c6b24 100644
--- a/vcl/source/gdi/bitmapex.cxx
+++ b/vcl/source/gdi/bitmapex.cxx
@@ -633,11 +633,11 @@ sal_Bool BitmapEx::Replace( const Color* pSearchColors, const Color* pReplaceCol
 
 sal_Bool BitmapEx::Adjust( short nLuminancePercent, short nContrastPercent,
                        short nChannelRPercent, short nChannelGPercent, short nChannelBPercent,
-                       double fGamma, sal_Bool bInvert )
+                       double fGamma, bool bInvert, bool msoBrightness )
 {
     return( !!aBitmap ? aBitmap.Adjust( nLuminancePercent, nContrastPercent,
                                         nChannelRPercent, nChannelGPercent, nChannelBPercent,
-                                        fGamma, bInvert ) : sal_False );
+                                        fGamma, bInvert, msoBrightness ) : false );
 }
 
 sal_Bool BitmapEx::Filter( BmpFilter eFilter, const BmpFilterParam* pFilterParam, const Link* pProgress )
diff --git a/vcl/source/gdi/gdimtf.cxx b/vcl/source/gdi/gdimtf.cxx
index 2e74172..12ad981 100644
--- a/vcl/source/gdi/gdimtf.cxx
+++ b/vcl/source/gdi/gdimtf.cxx
@@ -2175,7 +2175,7 @@ void GDIMetaFile::ImplExchangeColors( ColorExchangeFnc pFncCol, const void* pCol
 
 void GDIMetaFile::Adjust( short nLuminancePercent, short nContrastPercent,
                           short nChannelRPercent, short nChannelGPercent,
-                          short nChannelBPercent, double fGamma, sal_Bool bInvert )
+                          short nChannelBPercent, double fGamma, bool bInvert, bool msoBrightness )
 {
     // nothing to do? => return quickly
     if( nLuminancePercent || nContrastPercent ||
@@ -2196,8 +2196,11 @@ void GDIMetaFile::Adjust( short nLuminancePercent, short nContrastPercent,
         else
             fM = ( 128.0 + 1.27 * MinMax( nContrastPercent, -100L, 0L ) ) / 128.0;
 
-        // total offset = luminance offset + contrast offset
-        fOff = MinMax( nLuminancePercent, -100L, 100L ) * 2.55 + 128.0 - fM * 128.0;
+        if(!msoBrightness)
+            // total offset = luminance offset + contrast offset
+            fOff = MinMax( nLuminancePercent, -100L, 100L ) * 2.55 + 128.0 - fM * 128.0;
+        else
+            fOff = MinMax( nLuminancePercent, -100L, 100L ) * 2.55;
 
         // channel offset = channel offset  + total offset
         fROff = nChannelRPercent * 2.55 + fOff;
@@ -2211,10 +2214,18 @@ void GDIMetaFile::Adjust( short nLuminancePercent, short nContrastPercent,
         // create mapping table
         for( long nX = 0L; nX < 256L; nX++ )
         {
-            aColParam.pMapR[ nX ] = (sal_uInt8) MinMax( FRound( nX * fM + fROff ), 0L, 255L );
-            aColParam.pMapG[ nX ] = (sal_uInt8) MinMax( FRound( nX * fM + fGOff ), 0L, 255L );
-            aColParam.pMapB[ nX ] = (sal_uInt8) MinMax( FRound( nX * fM + fBOff ), 0L, 255L );
-
+            if(!msoBrightness)
+            {
+                aColParam.pMapR[ nX ] = (sal_uInt8) MinMax( FRound( nX * fM + fROff ), 0L, 255L );
+                aColParam.pMapG[ nX ] = (sal_uInt8) MinMax( FRound( nX * fM + fGOff ), 0L, 255L );
+                aColParam.pMapB[ nX ] = (sal_uInt8) MinMax( FRound( nX * fM + fBOff ), 0L, 255L );
+            }
+            else
+            {
+                aColParam.pMapR[ nX ] = (sal_uInt8) MinMax( FRound( (nX+fROff/2-128) * fM + 128 + fROff/2 ), 0L, 255L );
+                aColParam.pMapG[ nX ] = (sal_uInt8) MinMax( FRound( (nX+fGOff/2-128) * fM + 128 + fGOff/2 ), 0L, 255L );
+                aColParam.pMapB[ nX ] = (sal_uInt8) MinMax( FRound( (nX+fBOff/2-128) * fM + 128 + fBOff/2 ), 0L, 255L );
+            }
             if( bGamma )
             {
                 aColParam.pMapR[ nX ] = GAMMA( aColParam.pMapR[ nX ], fGamma );
commit f2a58c8d470f027b1e3ece0b26da804a4ab169dd
Author: Caolán McNamara <caolanm at redhat.com>
Date:   Wed Apr 16 20:41:44 2014 +0100

    coverity#1202882 Dereference before null check
    
    Change-Id: Ie61df08c11b687c0b4a3ae212b3f9a6c95171396
    (cherry picked from commit c152349f69acfb6bb873ed1cd12ca1b6dc325f1f)
    Reviewed-on: https://gerrit.libreoffice.org/9095
    Tested-by: Andrzej Hunt <andrzej.hunt at collabora.com>
    Reviewed-by: Andrzej Hunt <andrzej.hunt at collabora.com>

diff --git a/sd/source/ui/remotecontrol/Communicator.cxx b/sd/source/ui/remotecontrol/Communicator.cxx
index d3af697..bf399ca 100644
--- a/sd/source/ui/remotecontrol/Communicator.cxx
+++ b/sd/source/ui/remotecontrol/Communicator.cxx
@@ -122,10 +122,9 @@ void Communicator::execute()
     pTransmitter->join();
     pTransmitter = NULL;
 
-    if( mpSocket )
-        mpSocket->close();
+    mpSocket->close();
     delete mpSocket;
-
+    mpSocket = NULL;
 
     RemoteServer::removeCommunicator( this );
 }
commit 544fbfeb5dc05d975337722950b8b059b2c107bd
Author: Caolán McNamara <caolanm at redhat.com>
Date:   Thu Apr 17 11:56:17 2014 +0100

    Resolves: rhbz#1086714 overlarge pixmap
    
    (cherry picked from commit f31ac2405bbd0755fb14daa6cb84d7bb7d84c492)
    
    Conflicts:
    	canvas/source/cairo/cairo_xlib_cairo.cxx
    	vcl/unx/x11/xlimits.cxx
    
    Change-Id: I015308406a43e6b039059a5e35316d59745d0a48
    Reviewed-on: https://gerrit.libreoffice.org/9083
    Tested-by: Markus Mohrhard <markus.mohrhard at googlemail.com>
    Reviewed-by: Markus Mohrhard <markus.mohrhard at googlemail.com>

diff --git a/canvas/source/cairo/cairo_canvasbitmap.cxx b/canvas/source/cairo/cairo_canvasbitmap.cxx
index 277c133..d243596 100644
--- a/canvas/source/cairo/cairo_canvasbitmap.cxx
+++ b/canvas/source/cairo/cairo_canvasbitmap.cxx
@@ -158,7 +158,7 @@ namespace cairocanvas
                 pPixels = cairo_image_surface_create( CAIRO_FORMAT_ARGB32,
                                                       aSize.Width(), aSize.Height() );
                 cairo_t *pCairo = cairo_create( pPixels );
-                if( !pPixels || !pCairo )
+                if( !pPixels || !pCairo || cairo_status(pCairo) != CAIRO_STATUS_SUCCESS )
                     break;
 
                 // suck ourselves from the X server to this buffer so then we can fiddle with
diff --git a/canvas/source/cairo/cairo_xlib_cairo.cxx b/canvas/source/cairo/cairo_xlib_cairo.cxx
index bae6943..e5bb189 100644
--- a/canvas/source/cairo/cairo_xlib_cairo.cxx
+++ b/canvas/source/cairo/cairo_xlib_cairo.cxx
@@ -36,11 +36,12 @@ namespace
     Pixmap limitXCreatePixmap(Display *display, Drawable d, unsigned int width, unsigned int height, unsigned int depth)
     {
         // The X protocol request CreatePixmap puts an upper bound
-        // of 16 bit to the size.
-        //
-        // see, e.g. moz#424333, fdo#48961
+        // of 16 bit to the size. And in practice some drivers
+        // fall over with values close to the max.
+
+        // see, e.g. moz#424333, fdo#48961, rhbz#1086714
         // we've a duplicate of this in vcl :-(
-        if (width > SAL_MAX_INT16 || height > SAL_MAX_INT16)
+        if (width > SAL_MAX_INT16-10 || height > SAL_MAX_INT16-10)
         {
             SAL_WARN("canvas", "overlarge pixmap: " << width << " x " << height);
             return None;
diff --git a/vcl/unx/x11/xlimits.cxx b/vcl/unx/x11/xlimits.cxx
index 71b9983..b8509cb 100644
--- a/vcl/unx/x11/xlimits.cxx
+++ b/vcl/unx/x11/xlimits.cxx
@@ -13,13 +13,12 @@
 Pixmap limitXCreatePixmap(Display *display, Drawable d, unsigned int width, unsigned int height, unsigned int depth)
 {
     // The X protocol request CreatePixmap puts an upper bound
-    // of 16 bit to the size. Beyond that there may be implementation
-    // limits of the Xserver; which we should catch by a failed XCreatePixmap
-    // call. However extra large values should be caught here since we'd run into
-    // 16 bit truncation here without noticing.
-    //
-    // see, e.g. moz#424333
-    if (width > SAL_MAX_INT16 || height > SAL_MAX_INT16)
+    // of 16 bit to the size. And in practice some drivers
+    // fall over with values close to the max.
+
+    // see, e.g. moz#424333, fdo#48961, rhbz#1086714
+    // we've a duplicate of this in canvas :-(
+    if (width > SAL_MAX_INT16-10 || height > SAL_MAX_INT16-10)
     {
         SAL_WARN("vcl", "overlarge pixmap: " << width << " x " << height);
         return None;
commit 89ec126493272afc48be2cf6a27787ba331205fd
Author: Caolán McNamara <caolanm at redhat.com>
Date:   Thu Apr 17 11:58:38 2014 +0100

    zero various members
    
    (cherry picked from commit 9de20d1eb046f7bb92d893408206b91a9c054e2e)
    
    Conflicts:
    	filter/Module_filter.mk
    	filter/source/graphicfilter/ipcx/ipcx.cxx
    	filter/source/graphicfilter/itiff/itiff.cxx
    
    Change-Id: Iad6948fdf6eb60f86d764783b72a4fe7f5642e40
    Reviewed-on: https://gerrit.libreoffice.org/9082
    Tested-by: Markus Mohrhard <markus.mohrhard at googlemail.com>
    Reviewed-by: Markus Mohrhard <markus.mohrhard at googlemail.com>

diff --git a/filter/source/graphicfilter/ipcx/ipcx.cxx b/filter/source/graphicfilter/ipcx/ipcx.cxx
index 54579ff..2d35844 100644
--- a/filter/source/graphicfilter/ipcx/ipcx.cxx
+++ b/filter/source/graphicfilter/ipcx/ipcx.cxx
@@ -148,10 +148,7 @@ sal_Bool PCXReader::ReadPCX(Graphic & rGraphic)
 
 void PCXReader::ImplReadHeader()
 {
-    sal_uInt8 nbyte;
-    sal_uInt16 nushort;
-    sal_uInt16 nMinX,nMinY,nMaxX,nMaxY;
-
+    sal_uInt8 nbyte(0);
     m_rPCX >> nbyte >> nVersion >> nEncoding;
     if ( nbyte!=0x0a || (nVersion != 0 && nVersion != 2 && nVersion != 3 && nVersion != 5) || nEncoding > 1 )
     {
@@ -159,7 +156,9 @@ void PCXReader::ImplReadHeader()
         return;
     }
 
+    nbyte = 0;
     m_rPCX >> nbyte; nBitsPerPlanePix = (sal_uLong)nbyte;
+    sal_uInt16 nMinX(0),nMinY(0),nMaxX(0),nMaxY(0);
     m_rPCX >> nMinX >> nMinY >> nMaxX >> nMaxY;
 
     if ((nMinX > nMaxX) || (nMinY > nMaxY))
@@ -179,7 +178,9 @@ void PCXReader::ImplReadHeader()
     ImplReadPalette( 16 );
 
     m_rPCX.SeekRel( 1 );
+    nbyte = 0;
     m_rPCX >> nbyte;   nPlanes = (sal_uLong)nbyte;
+    sal_uInt16 nushort(0);
     m_rPCX >> nushort; nBytesPerPlaneLin = (sal_uLong)nushort;
     m_rPCX >> nPaletteInfo;
 
diff --git a/filter/source/graphicfilter/itiff/itiff.cxx b/filter/source/graphicfilter/itiff/itiff.cxx
index 71bd7e0..71bad87 100644
--- a/filter/source/graphicfilter/itiff/itiff.cxx
+++ b/filter/source/graphicfilter/itiff/itiff.cxx
@@ -125,7 +125,54 @@ private:
     bool HasAlphaChannel() const;
 public:
 
-    TIFFReader() : pAlphaMask(0), pMaskAcc(0) {}
+    TIFFReader()
+        : bStatus(false)
+        , nLastPercent(0)
+        , pTIFF(NULL)
+        , pAcc(NULL)
+        , nDstBitsPerPixel(0)
+        , pAlphaMask(NULL)
+        , pMaskAcc(NULL)
+        , nOrigPos(0)
+        , nOrigNumberFormat(0)
+        , nDataType(0)
+        , bByteSwap(false)
+        , nNewSubFile(0)
+        , nSubFile(0)
+        , nImageWidth(0)
+        , nImageLength(0)
+        , nBitsPerSample(1)
+        , nCompression(1)
+        , nPhotometricInterpretation(0)
+        , nThresholding(1)
+        , nCellWidth(1)
+        , nCellLength(1)
+        , nFillOrder(1)
+        , pStripOffsets(NULL)
+        , nNumStripOffsets(0)
+        , nOrientation(1)
+        , nSamplesPerPixel(1)
+        , nRowsPerStrip(0xffffffff)
+        , pStripByteCounts(NULL)
+        , nNumStripByteCounts(0)
+        , nMinSampleValue(0)
+        , nMaxSampleValue(0)
+        , fXResolution(0.0)
+        , fYResolution(0.0)
+        , nPlanarConfiguration(1)
+        , nGroup3Options(0)
+        , nGroup4Options(0)
+        , nResolutionUnit(2)
+        , nPredictor(0)
+        , pColorMap(NULL)
+        , nNumColors(0)
+        , nPlanes(0)
+        , nStripsPerPlane(0)
+        , nBytesPerRow(0)
+    {
+        pMap[ 0 ] = pMap[ 1 ] = pMap[ 2 ] = pMap[ 3 ] = NULL;
+    }
+
     ~TIFFReader()
     {
         delete pAlphaMask;
@@ -178,14 +225,14 @@ sal_uLong TIFFReader::DataTypeSize()
 
 sal_uLong TIFFReader::ReadIntData()
 {
-    double  nDOUBLE;
-    float   nFLOAT;
-    sal_uInt32  nUINT32a, nUINT32b;
-    sal_Int32   nINT32;
-    sal_uInt16  nUINT16;
-    sal_Int16   nINT16;
-    sal_uInt8   nBYTE;
-    char    nCHAR;
+    double  nDOUBLE(0.0);
+    float   nFLOAT(0);
+    sal_uInt32  nUINT32a(0), nUINT32b(0);
+    sal_Int32   nINT32(0);
+    sal_uInt16  nUINT16(0);
+    sal_Int16   nINT16(0);
+    sal_uInt8   nBYTE(0);
+    char    nCHAR(0);
 
     switch( nDataType )
     {
@@ -241,13 +288,14 @@ sal_uLong TIFFReader::ReadIntData()
 
 double TIFFReader::ReadDoubleData()
 {
-    sal_uInt32 nulong;
     double  nd;
 
     if ( nDataType == 5 )
     {
+        sal_uInt32 nulong(0);
         *pTIFF >> nulong;
         nd = (double)nulong;
+        nulong = 0;
         *pTIFF >> nulong;
         if ( nulong != 0 )
             nd /= (double)nulong;
@@ -603,7 +651,7 @@ sal_Bool TIFFReader::ReadMap( sal_uLong nMinPercent, sal_uLong nMaxPercent )
     else if ( nCompression == 32773 )
     {
         sal_uLong nStrip,nRecCount,nRowBytesLeft,ny,np,i;
-        sal_uInt8 * pdst, nRecHeader, nRecData;
+        sal_uInt8 * pdst;
         nStrip = 0;
         if ( nStrip >= nNumStripOffsets )
             return sal_False;
@@ -623,6 +671,7 @@ sal_Bool TIFFReader::ReadMap( sal_uLong nMinPercent, sal_uLong nMaxPercent )
                 pdst=pMap[ np ];
                 do
                 {
+                    sal_uInt8 nRecHeader(0);
                     *pTIFF >> nRecHeader;
                     if ((nRecHeader&0x80)==0)
                     {
@@ -644,6 +693,7 @@ sal_Bool TIFFReader::ReadMap( sal_uLong nMinPercent, sal_uLong nMaxPercent )
 //                          return;
 
                         }
+                        sal_uInt8 nRecData(0);
                         *pTIFF >> nRecData;
                         for ( i = 0; i < nRecCount; i++ )
                             *(pdst++) = nRecData;
@@ -1081,8 +1131,8 @@ void TIFFReader::MakePalCol( void )
 
 void TIFFReader::ReadHeader()
 {
-    sal_uInt8 nbyte1, nbyte2;
-    sal_uInt16 nushort;
+    sal_uInt8 nbyte1(0), nbyte2(0);
+    sal_uInt16 nushort(0);
 
     *pTIFF >> nbyte1;
     if ( nbyte1 == 'I' )
@@ -1111,10 +1161,10 @@ bool TIFFReader::HasAlphaChannel() const
 
 sal_Bool TIFFReader::ReadTIFF(SvStream & rTIFF, Graphic & rGraphic )
 {
-    sal_uInt16  i, nNumTags, nTagType;
+    sal_uInt16  i, nNumTags(0), nTagType(0);
     sal_uLong   nMaxPos;
     sal_uLong   nPos;
-    sal_uInt32 nFirstIfd, nDataLen;
+    sal_uInt32 nFirstIfd(0), nDataLen;
 
     bStatus = sal_True;
     nLastPercent = 0;
diff --git a/filter/source/graphicfilter/itiff/lzwdecom.cxx b/filter/source/graphicfilter/itiff/lzwdecom.cxx
index 4ac9d4c..00e7a33 100644
--- a/filter/source/graphicfilter/itiff/lzwdecom.cxx
+++ b/filter/source/graphicfilter/itiff/lzwdecom.cxx
@@ -23,7 +23,16 @@
 #define MAX_TABLE_SIZE 4096
 
 LZWDecompressor::LZWDecompressor()
-    : pOutBufData(NULL)
+    : pIStream(NULL)
+    , nTableSize(0)
+    , bEOIFound(false)
+    , bInvert(false)
+    , bFirst(true)
+    , nOldCode(0)
+    , pOutBufData(NULL)
+    , nOutBufDataLen(0)
+    , nInputBitsBuf(0)
+    , nInputBitsBufSize(0)
 {
     sal_uInt16 i;
 
@@ -35,9 +44,6 @@ LZWDecompressor::LZWDecompressor()
         pTable[i].nDataCount=1;
         pTable[i].nData=(sal_uInt8)i;
     }
-    pIStream=NULL;
-    bFirst = sal_True;
-    nOldCode = 0;
 }
 
 
commit 13b913adbd15da416f11bf7c49fd3fbe5be956f0
Author: Michael Stahl <mstahl at redhat.com>
Date:   Thu Apr 17 15:25:23 2014 +0200

    fdo#77342: sw: fix copy/paste of footnote cross references
    
    The fix for sequence fields broke the footnote references some more;
    simplify it by handling the footnotes in the same way as the sequence
    fields, and not remapping GetExp fields for which the corresponding
    SetExp field / footnote is missing.
    
    Also, don't do any remapping when the target is a clipboard document, to
    prevent modifying the source document.
    
    (regression from bb665affbd8870652ade3951d626d76e99143f67)
    
    (cherry picked from commit cbfcb837fb06a14daf5281ae13fc1886328cee6f)
    
    Conflicts:
    	sw/source/core/fields/reffld.cxx
    
    Change-Id: If1be1e1d9742182a4085bbbff53e26a8fa8665b8
    Reviewed-on: https://gerrit.libreoffice.org/9085
    Reviewed-by: Caolán McNamara <caolanm at redhat.com>
    Tested-by: Caolán McNamara <caolanm at redhat.com>

diff --git a/sw/source/core/fields/reffld.cxx b/sw/source/core/fields/reffld.cxx
index e20accb..9fbd6cd 100644
--- a/sw/source/core/fields/reffld.cxx
+++ b/sw/source/core/fields/reffld.cxx
@@ -1009,6 +1009,17 @@ void _RefIdsMap::Init( SwDoc& rDoc, SwDoc& rDestDoc, bool bField )
     {
         GetNoteIdsFromDoc( rDestDoc, aIds );
         GetNoteIdsFromDoc( rDoc, aDstIds );
+
+        for (std::set<sal_uInt16>::iterator pIt = aDstIds.begin(); pIt != aDstIds.end(); ++pIt)
+            AddId( GetFirstUnusedId(aIds), *pIt );
+
+        // Change the footnotes/endnotes in the source doc to the new ID
+        for (sal_uInt16 i = 0, nCnt = rDoc.GetFtnIdxs().size(); i < nCnt; ++i)
+        {
+            SwTxtFtn *const pFtnIdx = rDoc.GetFtnIdxs()[i];
+            sal_uInt16 const n = pFtnIdx->GetSeqRefNo();
+            pFtnIdx->SetSeqNo(sequencedIds[n]);
+        }
     }
     bInit = true;
 }
@@ -1046,53 +1057,38 @@ void _RefIdsMap::Check( SwDoc& rDoc, SwDoc& rDestDoc, SwGetRefField& rFld,
 {
     Init( rDoc, rDestDoc, bField);
 
-    sal_uInt16 nSeqNo = rFld.GetSeqNo();
-
-    // Check if the number is used in both documents
-    // Note: For fields, aIds contains both the ids of SetExp from rDestDoc
-    // and the targets of the already remapped ones from rDoc.
-    // It is possible that aDstIds contains numbers that aIds does not contain!
-    // For example, copying a selection to clipboard that does not contain
-    // the first SwSetExpField will result in id 0 missing, then pasting that
-    // into empty document gives a mapping 1->0 ... N->N-1 (fdo#63553).
-    if (aIds.count(nSeqNo) || aDstIds.count(nSeqNo))
-    {
-        // Number already taken, so need a new one.
-        if( sequencedIds.count(nSeqNo) )
-            rFld.SetSeqNo( sequencedIds[nSeqNo] );
-        else
-        {
-            assert(!bField || !aDstIds.count(nSeqNo)); // postcond of Init
-
-            sal_uInt16 n = GetFirstUnusedId( aIds );
-
-            // die neue SeqNo eintragen, damit die "belegt" ist
-            AddId( n, nSeqNo );
-            rFld.SetSeqNo( n );
+    sal_uInt16 const nSeqNo = rFld.GetSeqNo();
 
-            // und noch die Fuss-/EndNote auf die neue Id umsetzen
-            if( !bField )
-            {
-                SwTxtFtn* pFtnIdx;
-                for( sal_uInt16 i = 0, nCnt = rDoc.GetFtnIdxs().size(); i < nCnt; ++i )
-                    if( nSeqNo == (pFtnIdx = rDoc.GetFtnIdxs()[ i ])->GetSeqRefNo() )
-                    {
-                        pFtnIdx->SetSeqNo( n );
-                        break;
-                    }
-            }
-        }
-    }
-    else
+    // check if it needs to be remapped
+    // if sequencedIds doesn't contain the number, it means there is no
+    // SetExp field / footnote in the source document: do not modify
+    // the number, which works well for copy from/paste to same document
+    // (and if it is not the same document, there's no "correct" result anyway)
+    if (sequencedIds.count(nSeqNo))
     {
-        AddId( nSeqNo, nSeqNo ); // this requires that nSeqNo is unused in both!
+        rFld.SetSeqNo( sequencedIds[nSeqNo] );
     }
 }
 
+/// 1. if _both_ SetExp + GetExp / Footnote + GetExp field are copied,
+///    enusure that both get a new unused matching number
+/// 2. if only SetExp / Footnote is copied, it gets a new unused number
+/// 3. if only GetExp field is copied, for the case of copy from / paste to
+///    same document it's desirable to keep the same number;
+///    for other cases of copy/paste or master documents it's not obvious
+///    what is most desirable since it's going to be wrong anyway
 void SwGetRefFieldType::MergeWithOtherDoc( SwDoc& rDestDoc )
 {
     if( &rDestDoc != pDoc )
     {
+        if (rDestDoc.IsClipBoard())
+        {
+            // when copying _to_ clipboard, expectation is that no fields exist
+            // so no re-mapping is required to avoid collisions
+            assert(!rDestDoc.GetSysFldType(RES_GETREFFLD)->GetDepends());
+            return; // don't modify the fields in the source doc
+        }
+
         // then there are RefFields in the DescDox - so all RefFields in the SourceDoc
         // need to be converted to have unique IDs for both documents
         _RefIdsMap aFntMap( aEmptyOUStr );
commit 7eb4c0e476240448b9da227be27c312c53447350
Author: Markus Mohrhard <markus.mohrhard at collabora.co.uk>
Date:   Thu Apr 17 02:02:15 2014 +0200

    limit the range shrinking in charts to really large ranges, fdo#70609,
    
    Also improves the situation for fdo#55697.
    
    It is just the fist step to a better algorithm.
    
    Change-Id: I15de1ca6604e585fcf5690f0d903c757d641e765
    Reviewed-on: https://gerrit.libreoffice.org/9078
    Reviewed-by: Andras Timar <andras.timar at collabora.com>
    Tested-by: Andras Timar <andras.timar at collabora.com>

diff --git a/sc/source/ui/unoobj/chart2uno.cxx b/sc/source/ui/unoobj/chart2uno.cxx
index 8754057..093dbbe 100644
--- a/sc/source/ui/unoobj/chart2uno.cxx
+++ b/sc/source/ui/unoobj/chart2uno.cxx
@@ -1372,6 +1372,8 @@ bool lcl_addUpperLeftCornerIfMissing(vector<ScTokenRef>& rRefTokens,
     return true;
 }
 
+#define SHRINK_RANGE_THRESHOLD 10000
+
 class ShrinkRefTokenToDataRange : std::unary_function<ScTokenRef, void>
 {
     ScDocument* mpDoc;
@@ -1391,6 +1393,9 @@ public:
         ScSingleRefData& s = rData.Ref1;
         ScSingleRefData& e = rData.Ref2;
 
+        if(abs((e.Col()-s.Col())*(e.Row()-s.Row())) < SHRINK_RANGE_THRESHOLD)
+            return;
+
         SCCOL nMinCol = MAXCOL, nMaxCol = 0;
         SCROW nMinRow = MAXROW, nMaxRow = 0;
 
commit 5e198e97a5cef9a837f7cd509753f9089492a235
Author: Andrzej Hunt <andrzej.hunt at collabora.com>
Date:   Thu Apr 10 21:58:29 2014 +0100

    fdo#74697 Add Bluez 5 support for impress remote.
    
    This time we:
     - Don't break SAL_WARN with an fprintf like syntax.
     - Replace DBUS_TYPE_UNIX_FD with it's definition 'h' as we might
       be building on dbus-glib versions that do not support it (however
       presumably anyone running bluez 5 will have a dbus version that is
       new enough to support this, i.e. purely a build-time issue).
     - Remove various C++11'isms.
    
    Change-Id: I736cad2122cd3789a5c7fb62c39e409d41fc1e32
    Reviewed-on: https://gerrit.libreoffice.org/8924
    Tested-by: Andrzej Hunt <andrzej.hunt at collabora.com>
    Reviewed-by: Andrzej Hunt <andrzej.hunt at collabora.com>
    (cherry picked from commit b15666fd7582729c75bd0dd1bd0cb5d7c5a77f0c)
    Reviewed-on: https://gerrit.libreoffice.org/8931
    Reviewed-by: Andras Timar <andras.timar at collabora.com>
    Tested-by: Andras Timar <andras.timar at collabora.com>

diff --git a/sd/source/ui/remotecontrol/BluetoothServer.cxx b/sd/source/ui/remotecontrol/BluetoothServer.cxx
index 63407a6..a447900 100644
--- a/sd/source/ui/remotecontrol/BluetoothServer.cxx
+++ b/sd/source/ui/remotecontrol/BluetoothServer.cxx
@@ -13,6 +13,8 @@
 #include <iomanip>
 #include <new>
 
+#include <boost/scoped_ptr.hpp>
+
 #include <sal/log.hxx>
 
 #ifdef LINUX_BLUETOOTH
@@ -90,25 +92,40 @@ struct DBusObject {
     }
 };
 
+static DBusObject* getBluez5Adapter(DBusConnection *pConnection);
+
 struct sd::BluetoothServer::Impl {
     // the glib mainloop running in the thread
     GMainContext *mpContext;
     DBusConnection *mpConnection;
     DBusObject *mpService;
     volatile bool mbExitMainloop;
+    enum BluezVersion { BLUEZ4, BLUEZ5, UNKNOWN };
+    BluezVersion maBluezVersion;
 
     Impl()
         : mpContext( g_main_context_new() )
         , mpConnection( NULL )
         , mpService( NULL )
         , mbExitMainloop( false )
+        , maBluezVersion( UNKNOWN )
     { }
 
     DBusObject *getAdapter()
     {
-        if( !mpService )
+        if (mpService)
+        {
+            DBusObject* pAdapter = mpService->cloneForInterface( "org.bluez.Adapter" );
+            return pAdapter;
+        }
+        else if (spServer->mpImpl->maBluezVersion == BLUEZ5)
+        {
+            return getBluez5Adapter(mpConnection);
+        }
+        else
+        {
             return NULL;
-        return mpService->cloneForInterface( "org.bluez.Adapter" );
+        }
     }
 };
 
@@ -156,37 +173,181 @@ sendUnrefAndWaitForReply( DBusConnection *pConnection, DBusMessage *pMsg )
     return pMsg;
 }
 
+static bool
+isBluez5Available(DBusConnection *pConnection)
+{
+    DBusMessage *pMsg;
+
+    // Simplest wasy to check whether we have Bluez 5+ is to check
+    // that we can obtain adapters using the new interfaces.
+    // The first two error checks however don't tell us anything as they should
+    // succeed as long as dbus is working correctly.
+    pMsg = DBusObject( "org.bluez", "/", "org.freedesktop.DBus.ObjectManager" ).getMethodCall( "GetManagedObjects" );
+    if (!pMsg)
+    {
+        SAL_INFO("sdremote.bluetooth", "No GetManagedObjects call created");
+        return false;
+    }
+
+    pMsg = sendUnrefAndWaitForReply( pConnection, pMsg );
+    if (!pMsg)
+    {
+        SAL_INFO("sdremote.bluetooth", "No reply received");
+        return false;
+    }
+
+    // If dbus is working correctly and we aren't on bluez 5 this is where we
+    // should actually get the error.
+    if (dbus_message_get_error_name( pMsg ))
+    {
+        SAL_INFO( "sdremote.bluetooth", "GetManagedObjects call failed with \""
+                    << dbus_message_get_error_name( pMsg )
+                    << "\" -- we don't seem to have Bluez 5 available");
+        return false;
+    }
+    SAL_INFO("sdremote.bluetooth", "GetManagedObjects call seems to have succeeded -- we must be on Bluez 5");
+    dbus_message_unref(pMsg);
+    return true;
+}
+
+
+static DBusObject*
+getBluez5Adapter(DBusConnection *pConnection)
+{
+    DBusMessage *pMsg;
+    // This returns a list of objects where we need to find the first
+    // org.bluez.Adapter1 .
+    pMsg = DBusObject( "org.bluez", "/", "org.freedesktop.DBus.ObjectManager" ).getMethodCall( "GetManagedObjects" );
+    if (!pMsg)
+        return NULL;
+
+    const gchar* pInterfaceType = "org.bluez.Adapter1";
+
+    pMsg = sendUnrefAndWaitForReply( pConnection, pMsg );
+
+    DBusMessageIter aObjectIterator;
+    if (pMsg && dbus_message_iter_init(pMsg, &aObjectIterator))
+    {
+        if (DBUS_TYPE_ARRAY == dbus_message_iter_get_arg_type(&aObjectIterator))
+        {
+            DBusMessageIter aObject;
+            dbus_message_iter_recurse(&aObjectIterator, &aObject);
+            do
+            {
+                if (DBUS_TYPE_DICT_ENTRY == dbus_message_iter_get_arg_type(&aObject))
+                {
+                    DBusMessageIter aContainerIter;
+                    dbus_message_iter_recurse(&aObject, &aContainerIter);
+                    char *pPath = 0;
+                    do
+                    {
+                        if (DBUS_TYPE_OBJECT_PATH == dbus_message_iter_get_arg_type(&aContainerIter))
+                        {
+                            dbus_message_iter_get_basic(&aContainerIter, &pPath);
+                            SAL_INFO( "sdremote.bluetooth", "Something retrieved: '"
+                            << pPath << "' '");
+                        }
+                        else if (DBUS_TYPE_ARRAY == dbus_message_iter_get_arg_type(&aContainerIter))
+                        {
+                            DBusMessageIter aInnerIter;
+                            dbus_message_iter_recurse(&aContainerIter, &aInnerIter);
+                            do
+                            {
+                                if (DBUS_TYPE_DICT_ENTRY == dbus_message_iter_get_arg_type(&aInnerIter))
+                                {
+                                    DBusMessageIter aInnerInnerIter;
+                                    dbus_message_iter_recurse(&aInnerIter, &aInnerInnerIter);
+                                    do
+                                    {
+                                        if (DBUS_TYPE_STRING == dbus_message_iter_get_arg_type(&aInnerInnerIter))
+                                        {
+                                            char* pMessage;
+
+                                            dbus_message_iter_get_basic(&aInnerInnerIter, &pMessage);
+                                            if (OString(pMessage) == "org.bluez.Adapter1")
+                                            {
+                                                dbus_message_unref(pMsg);
+                                                if (pPath)
+                                                {
+                                                    return new DBusObject( "org.bluez", pPath, pInterfaceType );
+                                                }
+                                                assert(false); // We should already have pPath provided for us.
+                                            }
+                                        }
+                                    }
+                                    while (dbus_message_iter_next(&aInnerInnerIter));
+                                }
+                            }
+                            while (dbus_message_iter_next(&aInnerIter));
+                        }
+                    }
+                    while (dbus_message_iter_next(&aContainerIter));
+                }
+            }
+            while (dbus_message_iter_next(&aObject));
+        }
+        dbus_message_unref(pMsg);
+    }
+
+    return NULL;
+}
+
 static DBusObject *
-bluezGetDefaultService( DBusConnection *pConnection )
+bluez4GetDefaultService( DBusConnection *pConnection )
 {
     DBusMessage *pMsg;
     DBusMessageIter it;
     const gchar* pInterfaceType = "org.bluez.Service";
 
+    // org.bluez.manager only exists for bluez 4.
+    // getMethodCall should return NULL if there is any issue e.g. the
+    // if org.bluez.manager doesn't exist.
     pMsg = DBusObject( "org.bluez", "/", "org.bluez.Manager" ).getMethodCall( "DefaultAdapter" );
+
+    if (!pMsg)
+    {
+        SAL_WARN("sdremote.bluetooth", "Couldn't retrieve DBusObject for DefaultAdapter");
+        return NULL;
+    }
+
+    SAL_INFO("sdremote.bluetooth", "successfully retrieved org.bluez.Manager.DefaultAdapter, attempting to use.");
     pMsg = sendUnrefAndWaitForReply( pConnection, pMsg );
 
     if(!pMsg || !dbus_message_iter_init( pMsg, &it ) )
+    {
         return NULL;
+    }
 
-    if( DBUS_TYPE_OBJECT_PATH != dbus_message_iter_get_arg_type( &it ) )
-        SAL_INFO( "sdremote.bluetooth", "invalid type of reply to DefaultAdapter: '"
-                  << dbus_message_iter_get_arg_type( &it ) << "'" );
-    else
+    // This works for Bluez 4
+    if( DBUS_TYPE_OBJECT_PATH == dbus_message_iter_get_arg_type( &it ) )
     {
         const char *pObjectPath = NULL;
         dbus_message_iter_get_basic( &it, &pObjectPath );
         SAL_INFO( "sdremote.bluetooth", "DefaultAdapter retrieved: '"
-                  << pObjectPath << "' '" << pInterfaceType << "'" );
+                << pObjectPath << "' '" << pInterfaceType << "'" );
+        dbus_message_unref( pMsg );
         return new DBusObject( "org.bluez", pObjectPath, pInterfaceType );
     }
-    dbus_message_unref( pMsg );
-
+    // Some form of error, e.g. if we have bluez 5 we get a message that
+    // this method doesn't exist.
+    else if ( DBUS_TYPE_STRING == dbus_message_iter_get_arg_type( &it ) )
+    {
+        const char *pMessage = NULL;
+        dbus_message_iter_get_basic( &it, &pMessage );
+        SAL_INFO( "sdremote.bluetooth", "Error message: '"
+                << pMessage << "' '" << pInterfaceType << "'" );
+    }
+    else
+    {
+        SAL_INFO( "sdremote.bluetooth", "invalid type of reply to DefaultAdapter: '"
+                << (const char) dbus_message_iter_get_arg_type( &it ) << "'" );
+    }
+    dbus_message_unref(pMsg);
     return NULL;
 }
 
 static bool
-bluezRegisterServiceRecord( DBusConnection *pConnection, DBusObject *pAdapter,
+bluez4RegisterServiceRecord( DBusConnection *pConnection, DBusObject *pAdapter,
                             const char *pServiceRecord )
 {
     DBusMessage *pMsg;
@@ -443,8 +604,14 @@ extern "C" {
     }
 }
 
+/*
+ * Bluez 4 uses custom methods for setting properties, whereas Bluez 5+
+ * implements properties using the generic "org.freedesktop.DBus.Properties"
+ * interface -- hence we have a specific Bluez 4 function to deal with the
+ * old style of reading properties.
+ */
 static bool
-getBooleanProperty( DBusConnection *pConnection, DBusObject *pAdapter,
+getBluez4BooleanProperty( DBusConnection *pConnection, DBusObject *pAdapter,
                     const char *pPropertyName, bool *pBoolean )
 {
     *pBoolean = false;
@@ -523,63 +690,391 @@ getBooleanProperty( DBusConnection *pConnection, DBusObject *pAdapter,
     return false;
 }
 
-static void
-setDiscoverable( DBusConnection *pConnection, DBusObject *pAdapter, bool bDiscoverable )
+/*
+ * This gets an org.freedesktop.DBus.Properties boolean
+ * (as opposed to the old Bluez 4 custom properties methods as visible above).
+ */
+static bool
+getDBusBooleanProperty( DBusConnection *pConnection, DBusObject *pAdapter,
+                        const char *pPropertyName, bool *pBoolean )
 {
-    SAL_INFO( "sdremote.bluetooth", "setDiscoverable to " << bDiscoverable );
+    assert( pAdapter );
 
-    bool bPowered = false;
-    if( !getBooleanProperty( pConnection, pAdapter, "Powered", &bPowered ) || !bPowered )
-        return; // nothing to do
+    *pBoolean = false;
+    bool bRet = false;
 
-    DBusMessage *pMsg;
-    DBusMessageIter it, varIt;
+    ::boost::scoped_ptr< DBusObject > pProperties (
+            pAdapter->cloneForInterface( "org.freedesktop.DBus.Properties" ) );
 
-    // set timeout to zero
-    pMsg = pAdapter->getMethodCall( "SetProperty" );
-    dbus_message_iter_init_append( pMsg, &it );
-    const char *pTimeoutStr = "DiscoverableTimeout";
-    dbus_message_iter_append_basic( &it, DBUS_TYPE_STRING, &pTimeoutStr );
-    dbus_message_iter_open_container( &it, DBUS_TYPE_VARIANT,
-                                      DBUS_TYPE_UINT32_AS_STRING, &varIt );
-    dbus_uint32_t nTimeout = 0;
-    dbus_message_iter_append_basic( &varIt, DBUS_TYPE_UINT32, &nTimeout );
-    dbus_message_iter_close_container( &it, &varIt );
-    dbus_connection_send( pConnection, pMsg, NULL ); // async send - why not ?
-    dbus_message_unref( pMsg );
+    DBusMessage *pMsg = pProperties->getMethodCall( "Get" );
 
-    // set discoverable value
-    pMsg = pAdapter->getMethodCall( "SetProperty" );
-    dbus_message_iter_init_append( pMsg, &it );
-    const char *pDiscoverableStr = "Discoverable";
-    dbus_message_iter_append_basic( &it, DBUS_TYPE_STRING, &pDiscoverableStr );
-    dbus_message_iter_open_container( &it, DBUS_TYPE_VARIANT,
-                                      DBUS_TYPE_BOOLEAN_AS_STRING, &varIt );
-    dbus_bool_t bValue = bDiscoverable;
-    dbus_message_iter_append_basic( &varIt, DBUS_TYPE_BOOLEAN, &bValue );
-    dbus_message_iter_close_container( &it, &varIt ); // async send - why not ?
-    dbus_connection_send( pConnection, pMsg, NULL );
+    DBusMessageIter itIn;
+    dbus_message_iter_init_append( pMsg, &itIn );
+    const char* pInterface = "org.bluez.Adapter1";
+    dbus_message_iter_append_basic( &itIn, DBUS_TYPE_STRING, &pInterface );
+    dbus_message_iter_append_basic( &itIn, DBUS_TYPE_STRING, &pPropertyName );
+    pMsg = sendUnrefAndWaitForReply( pConnection, pMsg );
+
+    DBusMessageIter it;
+    if( !pMsg || !dbus_message_iter_init( pMsg, &it ) )
+    {
+        SAL_WARN( "sdremote.bluetooth", "no valid reply / timeout" );
+        return false;
+    }
+
+    if( DBUS_TYPE_VARIANT != dbus_message_iter_get_arg_type( &it ) )
+    {
+        SAL_WARN( "sdremote.bluetooth", "invalid return type" );
+    }
+    else
+    {
+        DBusMessageIter variantIt;
+        dbus_message_iter_recurse( &it, &variantIt );
+
+        if( dbus_message_iter_get_arg_type( &variantIt ) == DBUS_TYPE_BOOLEAN )
+        {
+            dbus_bool_t bBool = false;
+            dbus_message_iter_get_basic( &variantIt, &bBool );
+            SAL_INFO( "sdremote.bluetooth", "" << pPropertyName << " is " << bBool );
+            *pBoolean = bBool;
+            bRet = true;
+        }
+        else
+        {
+            SAL_WARN( "sdremote.bluetooth", "" << pPropertyName << " type " <<
+                        dbus_message_iter_get_arg_type( &variantIt ) );
+        }
+
+        const char* pError = dbus_message_get_error_name( pMsg );
+        if ( pError )
+        {
+            SAL_WARN( "sdremote.bluetooth",
+                      "Get failed for " << pPropertyName << " on " <<
+                      pAdapter->maPath  << " with error: " << pError );
+        }
+    }
     dbus_message_unref( pMsg );
+
+    return bRet;
+}
+
+static void
+setDBusBooleanProperty( DBusConnection *pConnection, DBusObject *pAdapter,
+                        const char *pPropertyName, bool bBoolean )
+{
+    assert( pAdapter );
+
+    ::boost::scoped_ptr< DBusObject > pProperties(
+            pAdapter->cloneForInterface( "org.freedesktop.DBus.Properties" ) );
+
+    DBusMessage *pMsg = pProperties->getMethodCall( "Set" );
+
+    DBusMessageIter itIn;
+    dbus_message_iter_init_append( pMsg, &itIn );
+    const char* pInterface = "org.bluez.Adapter1";
+    dbus_message_iter_append_basic( &itIn, DBUS_TYPE_STRING, &pInterface );
+    dbus_message_iter_append_basic( &itIn, DBUS_TYPE_STRING, &pPropertyName );
+
+    {
+        DBusMessageIter varIt;
+        dbus_message_iter_open_container( &itIn, DBUS_TYPE_VARIANT,
+                                        DBUS_TYPE_BOOLEAN_AS_STRING, &varIt );
+        dbus_bool_t bDBusBoolean = bBoolean;
+        dbus_message_iter_append_basic( &varIt, DBUS_TYPE_BOOLEAN, &bDBusBoolean );
+        dbus_message_iter_close_container( &itIn, &varIt );
+    }
+
+    pMsg = sendUnrefAndWaitForReply( pConnection, pMsg );
+
+    if( !pMsg )
+    {
+        SAL_WARN( "sdremote.bluetooth", "no valid reply / timeout" );
+    }
+    else
+    {
+        const char* pError = dbus_message_get_error_name( pMsg );
+        if ( pError )
+        {
+            SAL_WARN( "sdremote.bluetooth",
+                      "Set failed for " << pPropertyName << " on " <<
+                      pAdapter->maPath << " with error: " << pError );
+        }
+        dbus_message_unref( pMsg );
+    }
+}
+
+static bool
+getDiscoverable( DBusConnection *pConnection, DBusObject *pAdapter )
+{
+    if (pAdapter->maInterface == "org.bluez.Adapter") // Bluez 4
+    {
+        bool bDiscoverable;
+        if( getBluez4BooleanProperty(pConnection, pAdapter, "Discoverable", &bDiscoverable ) )
+            return bDiscoverable;
+    }
+    else if (pAdapter->maInterface == "org.bluez.Adapter1") // Bluez 5
+    {
+        bool bDiscoverable;
+        if ( getDBusBooleanProperty(pConnection, pAdapter, "Discoverable", &bDiscoverable ) )
+            return bDiscoverable;
+    }
+    return false;
+}
+
+static void
+setDiscoverable( DBusConnection *pConnection, DBusObject *pAdapter, bool bDiscoverable )
+{
+    SAL_INFO( "sdremote.bluetooth", "setDiscoverable to " << bDiscoverable );
+
+    if (pAdapter->maInterface == "org.bluez.Adapter") // Bluez 4
+    {
+        bool bPowered = false;
+        if( !getBluez4BooleanProperty( pConnection, pAdapter, "Powered", &bPowered ) || !bPowered )
+            return; // nothing to do
+
+        DBusMessage *pMsg;
+        DBusMessageIter it, varIt;
+
+        // set timeout to zero
+        pMsg = pAdapter->getMethodCall( "SetProperty" );
+        dbus_message_iter_init_append( pMsg, &it );
+        const char *pTimeoutStr = "DiscoverableTimeout";
+        dbus_message_iter_append_basic( &it, DBUS_TYPE_STRING, &pTimeoutStr );
+        dbus_message_iter_open_container( &it, DBUS_TYPE_VARIANT,
+                                        DBUS_TYPE_UINT32_AS_STRING, &varIt );
+        dbus_uint32_t nTimeout = 0;
+        dbus_message_iter_append_basic( &varIt, DBUS_TYPE_UINT32, &nTimeout );
+        dbus_message_iter_close_container( &it, &varIt );
+        dbus_connection_send( pConnection, pMsg, NULL ); // async send - why not ?
+        dbus_message_unref( pMsg );
+
+        // set discoverable value
+        pMsg = pAdapter->getMethodCall( "SetProperty" );
+        dbus_message_iter_init_append( pMsg, &it );
+        const char *pDiscoverableStr = "Discoverable";
+        dbus_message_iter_append_basic( &it, DBUS_TYPE_STRING, &pDiscoverableStr );
+        dbus_message_iter_open_container( &it, DBUS_TYPE_VARIANT,
+                                        DBUS_TYPE_BOOLEAN_AS_STRING, &varIt );
+        dbus_bool_t bValue = bDiscoverable;
+        dbus_message_iter_append_basic( &varIt, DBUS_TYPE_BOOLEAN, &bValue );
+        dbus_message_iter_close_container( &it, &varIt ); // async send - why not ?
+        dbus_connection_send( pConnection, pMsg, NULL );
+        dbus_message_unref( pMsg );
+    }
+    else if  (pAdapter->maInterface == "org.bluez.Adapter1") // Bluez 5
+    {
+        setDBusBooleanProperty(pConnection, pAdapter, "Discoverable", bDiscoverable );
+    }
 }
 
 static DBusObject *
 registerWithDefaultAdapter( DBusConnection *pConnection )
 {
     DBusObject *pService;
-    pService = bluezGetDefaultService( pConnection );
-    if( !pService )
-        return NULL;
-
-    if( !bluezRegisterServiceRecord( pConnection, pService,
-                                     bluetooth_service_record ) )
+    pService = bluez4GetDefaultService( pConnection );
+    if( pService )
     {
-        delete pService;
-        return NULL;
+        if( !bluez4RegisterServiceRecord( pConnection, pService,
+                                     bluetooth_service_record ) )
+        {
+            delete pService;
+            return NULL;
+        }
     }
 
     return pService;
 }
 
+void ProfileUnregisterFunction
+(DBusConnection *connection, void *user_data)
+{
+    // We specifically don't need to do anything here.
+    (void) connection;
+    (void) user_data;
+}
+
+DBusHandlerResult ProfileMessageFunction
+(DBusConnection *pConnection, DBusMessage *pMessage, void *user_data)
+{
+    SAL_INFO("sdremote.bluetooth", "ProfileMessageFunction||" << dbus_message_get_interface(pMessage) << "||" <<  dbus_message_get_member(pMessage));
+    DBusHandlerResult aRet = DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+
+    if (OString(dbus_message_get_interface(pMessage)).equals("org.bluez.Profile1"))
+    {
+        if (OString(dbus_message_get_member(pMessage)).equals("Release"))
+        {
+            return DBUS_HANDLER_RESULT_HANDLED;
+        }
+        else if (OString(dbus_message_get_member(pMessage)).equals("NewConnection"))
+        {
+            if (!dbus_message_has_signature(pMessage, "oha{sv}"))
+            {
+                SAL_WARN("sdremote.bluetooth", "wrong signature for NewConnection");
+            }
+
+            DBusMessageIter it;
+            dbus_message_iter_init(pMessage, &it);
+
+            char* pPath;
+            dbus_message_iter_get_basic(&it, &pPath);
+            SAL_INFO("sdremote.bluetooth", "Adapter path:" << pPath);
+
+            if (!dbus_message_iter_next(&it))
+                SAL_WARN("sdremote.bluetooth", "not enough parameters passed");
+
+            // DBUS_TYPE_UNIX_FD == 'h' -- doesn't exist in older versions
+            // of dbus (< 1.3?) hence defined manually for now
+            if ('h' == dbus_message_iter_get_arg_type(&it))
+            {
+
+                int nDescriptor;
+                dbus_message_iter_get_basic(&it, &nDescriptor);
+                std::vector<Communicator*>* pCommunicators = (std::vector<Communicator*>*) user_data;
+
+                // Bluez gives us non-blocking sockets, but our code relies
+                // on blocking behaviour.
+                fcntl(nDescriptor, F_SETFL, fcntl(nDescriptor, F_GETFL) & ~O_NONBLOCK);
+
+                SAL_INFO( "sdremote.bluetooth", "connection accepted " << nDescriptor);
+                Communicator* pCommunicator = new Communicator( new BufferedStreamSocket( nDescriptor ) );
+                pCommunicators->push_back( pCommunicator );
+                pCommunicator->launch();
+            }
+
+            // For some reason an (empty?) reply is expected.
+            DBusMessage* pRet = dbus_message_new_method_return(pMessage);
+            dbus_connection_send(pConnection, pRet, NULL);
+            dbus_message_unref(pRet);
+
+            // We could read the remote profile version and features here
+            // (i.e. they are provided as part of the DBusMessage),
+            // however for us they are irrelevant (as our protocol handles
+            // equivalent functionality independently of whether we're on
+            // bluetooth or normal network connection).
+            return DBUS_HANDLER_RESULT_HANDLED;
+        }
+        else if (OString(dbus_message_get_member(pMessage)).equals("RequestDisconnection"))
+        {
+            return DBUS_HANDLER_RESULT_HANDLED;
+        }
+    }
+    SAL_WARN("sdremote.bluetooth", "Couldn't handle message correctly.");
+    return aRet;
+
+}
+
+static void
+setupBluez5Profile1(DBusConnection* pConnection, std::vector<Communicator*>* pCommunicators)
+{
+    bool bErr;
+
+    SAL_INFO("sdremote.bluetooth", "Attempting to register our org.bluez.Profile1");
+    static DBusObjectPathVTable aVTable;
+    aVTable.unregister_function = ProfileUnregisterFunction;
+    aVTable.message_function = ProfileMessageFunction;
+
+    // dbus_connection_try_register_object_path could be used but only exists for
+    // dbus-glib >= 1.2 -- we really shouldn't be trying this twice in any case.
+    // (dbus_connection_try_register_object_path also returns an error with more
+    // information which could be useful for debugging purposes.)
+    bErr = !dbus_connection_register_object_path(pConnection, "/org/libreoffice/bluez/profile1", &aVTable, pCommunicators);
+
+    if (bErr)
+    {
+        SAL_WARN("sdremote.bluetooth", "Failed to register Bluez 5 Profile1 callback, bluetooth won't work.");
+    }
+
+    dbus_connection_flush( pConnection );
+}
+
+static void
+unregisterBluez5Profile(DBusConnection* pConnection)
+{
+    DBusMessage* pMsg = dbus_message_new_method_call("org.bluez", "/org/bluez",
+                                        "org.bluez.ProfileManager1", "UnregisterProfile");
+    DBusMessageIter it;
+    dbus_message_iter_init_append(pMsg, &it);
+
+    const char *pPath = "/org/libreoffice/bluez/profile1";
+    dbus_message_iter_append_basic(&it, DBUS_TYPE_OBJECT_PATH, &pPath);
+
+    pMsg = sendUnrefAndWaitForReply( pConnection, pMsg );
+
+    if (pMsg)
+        dbus_message_unref(pMsg);
+
+    dbus_connection_unregister_object_path( pConnection, "/org/libreoffice/bluez/profile1");
+
+    dbus_connection_flush(pConnection);
+}
+
+static bool
+registerBluez5Profile(DBusConnection* pConnection, std::vector<Communicator*>* pCommunicators)
+{
+    setupBluez5Profile1(pConnection, pCommunicators);
+
+    DBusMessage *pMsg;
+    DBusMessageIter it;
+
+    pMsg = dbus_message_new_method_call("org.bluez", "/org/bluez",
+                                        "org.bluez.ProfileManager1", "RegisterProfile");
+    dbus_message_iter_init_append(pMsg, &it);
+
+    const char *pPath = "/org/libreoffice/bluez/profile1";
+    dbus_message_iter_append_basic(&it, DBUS_TYPE_OBJECT_PATH, &pPath);
+    const char *pUUID =  "spp"; // Bluez translates this to 0x1101 for spp
+    dbus_message_iter_append_basic(&it, DBUS_TYPE_STRING, &pUUID);
+
+    DBusMessageIter aOptionsIter;
+    dbus_message_iter_open_container(&it, DBUS_TYPE_ARRAY, "{sv}", &aOptionsIter);
+
+    DBusMessageIter aEntry;
+
+    {
+        dbus_message_iter_open_container(&aOptionsIter, DBUS_TYPE_DICT_ENTRY, NULL, &aEntry);
+
+        const char *pString = "Name";
+        dbus_message_iter_append_basic(&aEntry, DBUS_TYPE_STRING, &pString);
+
+        const char *pValue = "LibreOffice Impress Remote";
+        DBusMessageIter aValue;
+        dbus_message_iter_open_container(&aEntry, DBUS_TYPE_VARIANT, "s", &aValue);
+        dbus_message_iter_append_basic(&aValue, DBUS_TYPE_STRING, &pValue);
+        dbus_message_iter_close_container(&aEntry, &aValue);
+        dbus_message_iter_close_container(&aOptionsIter, &aEntry);
+    }
+
+    dbus_message_iter_close_container(&it, &aOptionsIter);
+
+    // Other properties that we could set (but don't, since they appear
+    // to be useless for us):
+    // "Service": "0x1101" (not needed, but we used to have it in the manually defined profile).
+    // "Role": setting this to "server" breaks things, although we think we're a server?
+    // "Channel": seems to be dealt with automatically (but we used to use 5 in the manual profile).
+
+    bool bSuccess = true;
+
+    pMsg = sendUnrefAndWaitForReply( pConnection, pMsg );
+
+    DBusError aError;
+    dbus_error_init(&aError);
+    if (pMsg && dbus_set_error_from_message( &aError, pMsg ))
+    {
+        bSuccess = false;
+        SAL_WARN("sdremote.bluetooth",
+                 "Failed to register our Profile1 with bluez ProfileManager "
+                 << (const char *)(aError.message ? aError.message : "<null>"));
+    }
+
+    dbus_error_free(&aError);
+    if (pMsg)
+        dbus_message_unref(pMsg);
+
+    dbus_connection_flush(pConnection);
+
+    return bSuccess;
+}
+
 #endif // LINUX_BLUETOOTH
 
 BluetoothServer::BluetoothServer( std::vector<Communicator*>* pCommunicators )
@@ -642,14 +1137,11 @@ void BluetoothServer::doEnsureDiscoverable()
     if( !pAdapter )
         return;
 
-    bool bDiscoverable;
-    if( getBooleanProperty( spServer->mpImpl->mpConnection, pAdapter,
-                            "Discoverable", &bDiscoverable ) )
-    {
-        spServer->meWasDiscoverable = bDiscoverable ? DISCOVERABLE : NOT_DISCOVERABLE;
-        if( !bDiscoverable )
-            setDiscoverable( spServer->mpImpl->mpConnection, pAdapter, true );
-    }
+    bool bDiscoverable = getDiscoverable(spServer->mpImpl->mpConnection, pAdapter );
+
+    spServer->meWasDiscoverable = bDiscoverable ? DISCOVERABLE : NOT_DISCOVERABLE;
+    if( !bDiscoverable )
+        setDiscoverable( spServer->mpImpl->mpConnection, pAdapter, true );
 
     delete pAdapter;
 #endif
@@ -690,6 +1182,56 @@ void SAL_CALL BluetoothServer::run()
     if( !pConnection )
         return;
 
+
+    // For either implementation we need to poll the dbus fd
+    int fd = -1;
+    GPollFD aDBusFD;
+    if( dbus_connection_get_unix_fd( pConnection, &fd ) && fd >= 0 )
+    {
+        aDBusFD.fd = fd;
+        aDBusFD.events = G_IO_IN | G_IO_PRI;
+        g_main_context_add_poll( mpImpl->mpContext, &aDBusFD, G_PRIORITY_DEFAULT );
+    }
+    else
+        SAL_WARN( "sdremote.bluetooth", "failed to poll for incoming dbus signals" );
+
+    if (isBluez5Available(pConnection))
+    {
+        SAL_INFO("sdremote.bluetooth", "Using Bluez 5");
+        registerBluez5Profile(pConnection, mpCommunicators);
+        mpImpl->mpConnection = pConnection;
+        mpImpl->maBluezVersion = Impl::BLUEZ5;
+
+        // We don't need to listen to adapter changes anymore -- profile
+        // registration is done globally for the entirety of bluez, so we only
+        // need adapters when setting discovereability, which can be done
+        // dyanmically without the need to listen for changes.
+
+        // TODO: exit on SD deinit
+        // Probably best to do that in SdModule::~SdModule?
+        while (!mpImpl->mbExitMainloop)
+        {
+            aDBusFD.revents = 0;
+            g_main_context_iteration( mpImpl->mpContext, TRUE );
+            if( aDBusFD.revents )
+            {
+                dbus_connection_read_write( pConnection, 0 );
+                while (DBUS_DISPATCH_DATA_REMAINS == dbus_connection_get_dispatch_status( pConnection ))
+                    dbus_connection_dispatch( pConnection );
+            }
+        }
+        unregisterBluez5Profile( pConnection );
+        g_main_context_unref( mpImpl->mpContext );
+        mpImpl->mpConnection = NULL;
+        mpImpl->mpContext = NULL;
+        return;
+    }
+
+    // Otherwise we could be on Bluez 4 and continue as usual.
+    mpImpl->maBluezVersion = Impl::BLUEZ4;
+
+    // Try to setup the default adapter, otherwise wait for add/remove signal
+    mpImpl->mpService = registerWithDefaultAdapter( pConnection );
     // listen for connection state and power changes - we need to close
     // and re-create our socket code on suspend / resume, enable/disable
     DBusError aError;
@@ -705,18 +1247,6 @@ void SAL_CALL BluetoothServer::run()
     if( mpImpl->mpService )
         bluezCreateAttachListeningSocket( mpImpl->mpContext, &aSocketFD );
 
-    // also poll on our dbus connection
-    int fd = -1;
-    GPollFD aDBusFD;
-    if( dbus_connection_get_unix_fd( pConnection, &fd ) && fd >= 0 )
-    {
-        aDBusFD.fd = fd;
-        aDBusFD.events = G_IO_IN | G_IO_PRI;
-        g_main_context_add_poll( mpImpl->mpContext, &aDBusFD, G_PRIORITY_DEFAULT );
-    }
-    else
-        SAL_WARN( "sdremote.bluetooth", "failed to poll for incoming dbus signals" );
-
     mpImpl->mpConnection = pConnection;
 
     while( !mpImpl->mbExitMainloop )
@@ -779,6 +1309,7 @@ void SAL_CALL BluetoothServer::run()
         }
     }
 
+    unregisterBluez5Profile( pConnection );
     g_main_context_unref( mpImpl->mpContext );
     mpImpl->mpConnection = NULL;
     mpImpl->mpContext = NULL;
diff --git a/sd/source/ui/remotecontrol/BufferedStreamSocket.cxx b/sd/source/ui/remotecontrol/BufferedStreamSocket.cxx
index 4b4c1ce..4417e09 100644
--- a/sd/source/ui/remotecontrol/BufferedStreamSocket.cxx
+++ b/sd/source/ui/remotecontrol/BufferedStreamSocket.cxx
@@ -61,7 +61,7 @@ sal_Int32 BufferedStreamSocket::write( const void* pBuffer, sal_uInt32 n )
 
 void BufferedStreamSocket::close()
 {
-    if( usingCSocket )
+    if( usingCSocket && mSocket != -1 )
     {
 #ifdef WIN32
         ::closesocket( mSocket );
diff --git a/sd/source/ui/remotecontrol/Communicator.cxx b/sd/source/ui/remotecontrol/Communicator.cxx
index 4b2dc84..d3af697 100644
--- a/sd/source/ui/remotecontrol/Communicator.cxx
+++ b/sd/source/ui/remotecontrol/Communicator.cxx
@@ -122,6 +122,8 @@ void Communicator::execute()
     pTransmitter->join();
     pTransmitter = NULL;
 
+    if( mpSocket )
+        mpSocket->close();
     delete mpSocket;
 
 
commit 8a89ab94cbcced6256fede5ff4d281dcad024f28
Author: Caolán McNamara <caolanm at redhat.com>
Date:   Wed Apr 16 20:24:33 2014 +0100

    Resolves: fdo#76916 'User paths' is missing in tab MotionMotion Paths tab
    
    (cherry picked from commit 8b9858b0aeae8bfb3af6dd8fcfce6cecdb9b8fab)
    
    Conflicts:
    	sd/source/ui/animations/CustomAnimationCreateDialog.cxx
    
    Change-Id: I38deeae3135badde23b9d454d548193af654caab
    Reviewed-on: https://gerrit.libreoffice.org/9076
    Reviewed-by: Andras Timar <andras.timar at collabora.com>
    Tested-by: Andras Timar <andras.timar at collabora.com>

diff --git a/sd/source/ui/animations/CustomAnimationCreateDialog.cxx b/sd/source/ui/animations/CustomAnimationCreateDialog.cxx
index 0eb084a..6117f9d 100644
--- a/sd/source/ui/animations/CustomAnimationCreateDialog.cxx
+++ b/sd/source/ui/animations/CustomAnimationCreateDialog.cxx
@@ -174,7 +174,7 @@ void CategoryListBox::MouseButtonUp( const MouseEvent& rMEvt )
 class CustomAnimationCreateTabPage : public TabPage
 {
 public:
-    CustomAnimationCreateTabPage( Window* pParent, CustomAnimationCreateDialog* pDialogParent, sal_uInt16 nTabId, const PresetCategoryList& rCategoryList, bool bHasText );
+    CustomAnimationCreateTabPage( Window* pParent, CustomAnimationCreateDialog* pDialogParent, sal_uInt16 nTabId, const PresetCategoryList& rCategoryList, bool bHasText, bool bIsMotionPath = false );
     ~CustomAnimationCreateTabPage();
 
     PathKind getCreatePathKind() const;
@@ -235,7 +235,7 @@ bool ImplStlEffectCategorySortHelper::operator()( const CustomAnimationPresetPtr
     return mxCollator->compareString(p1->getLabel(), p2->getLabel()) == -1;
 }
 
-CustomAnimationCreateTabPage::CustomAnimationCreateTabPage( Window* pParent, CustomAnimationCreateDialog* pDialogParent, sal_uInt16 nTabId, const PresetCategoryList& rCategoryList, bool bHasText )
+CustomAnimationCreateTabPage::CustomAnimationCreateTabPage( Window* pParent, CustomAnimationCreateDialog* pDialogParent, sal_uInt16 nTabId, const PresetCategoryList& rCategoryList, bool bHasText, bool bIsMotionPath )
 : TabPage( pParent, "CustomAnimationCreateTab", "modules/simpress/ui/customanimationcreatetab.ui" )
 , mpParent( pDialogParent )
 , mnId( nTabId )
@@ -256,7 +256,7 @@ CustomAnimationCreateTabPage::CustomAnimationCreateTabPage( Window* pParent, Cus
 
     sal_uInt16 nFirstEffect = LISTBOX_ENTRY_NOTFOUND;
 
-    if( nTabId == MOTIONPATH )
+    if( bIsMotionPath )
     {
         mpLBEffects->InsertCategory( sMotionPathLabel );
 
@@ -523,7 +523,7 @@ CustomAnimationCreateDialog::CustomAnimationCreateDialog( Window* pParent, Custo
     mpTabControl->SetTabPage( mnEmphasisId, mpTabPages[EMPHASIS] );
     mpTabPages[EXIT] = new CustomAnimationCreateTabPage( mpTabControl, this, mnExitId, rPresets.getExitPresets(), bHasText );
     mpTabControl->SetTabPage( mnExitId, mpTabPages[EXIT] );
-    mpTabPages[MOTIONPATH] = new CustomAnimationCreateTabPage( mpTabControl, this, mnMPathId, rPresets.getMotionPathsPresets(), bHasText );
+    mpTabPages[MOTIONPATH] = new CustomAnimationCreateTabPage( mpTabControl, this, mnMPathId, rPresets.getMotionPathsPresets(), bHasText, true );
     mpTabControl->SetTabPage( mnMPathId, mpTabPages[MOTIONPATH] );
     mpTabPages[MISCEFFECTS] = new CustomAnimationCreateTabPage( mpTabControl, this, mnMiscId, rPresets.getMiscPresets(), bHasText );
     mpTabControl->SetTabPage( mnMiscId, mpTabPages[MISCEFFECTS] );
commit 93b128c8d7d778c3d5eb828162bf6fb74f371aaf
Author: Markus Mohrhard <markus.mohrhard at googlemail.com>
Date:   Thu Apr 17 02:19:53 2014 +0200

    missing header include
    
    Change-Id: I5bb1f1f5a457d4d390318fc793b15df078423c8c

diff --git a/sc/inc/scopetools.hxx b/sc/inc/scopetools.hxx
index 802aea1..40f1dec 100644
--- a/sc/inc/scopetools.hxx
+++ b/sc/inc/scopetools.hxx
@@ -10,6 +10,8 @@
 #ifndef SC_SCOPETOOLS_HXX
 #define SC_SCOPETOOLS_HXX
 
+#include "scdllapi.h"
+
 class ScDocument;
 
 namespace sc {
commit 4660880bc7e02ae9f11b5e9cfcafd26c219c2cea
Author: Kohei Yoshida <kohei.yoshida at collabora.com>
Date:   Wed Apr 16 15:17:13 2014 -0400

    fdo#74687: Undo & redo of format-only changes don't need broadcasting.
    
    Also discovered that the undo path was broadcasting twice.  Let's only
    do it once.
    
    Change-Id: I169f1659aecb1eb78be3a497e244f79c5883e50f
    (cherry picked from commit 1d1fbbe81b4435765d3f69c6bcae2840dc629912)
    Reviewed-on: https://gerrit.libreoffice.org/9075
    Tested-by: Markus Mohrhard <markus.mohrhard at googlemail.com>
    Reviewed-by: Markus Mohrhard <markus.mohrhard at googlemail.com>

diff --git a/sc/source/ui/undo/undoblk3.cxx b/sc/source/ui/undo/undoblk3.cxx
index 3239b1c..a06a076 100644
--- a/sc/source/ui/undo/undoblk3.cxx
+++ b/sc/source/ui/undo/undoblk3.cxx
@@ -141,7 +141,6 @@ void ScUndoDeleteContents::DoChange( const sal_Bool bUndo )
         aCopyRange.aEnd.SetTab(nTabCount-1);
 
         pUndoDoc->CopyToDocument( aCopyRange, nUndoFlags, bMulti, pDoc, &aMarkData );
-        BroadcastChanges(aCopyRange);
 
         DoSdrUndoAction( pDrawUndo, pDoc );
 
@@ -183,7 +182,10 @@ void ScUndoDeleteContents::Undo()
     DoChange( sal_True );
     EndUndo();
 
-    BroadcastChanges(aRange);
+    if (nFlags & IDF_CONTENTS)
+        // Broadcast only when the content changes. fdo#74687
+        BroadcastChanges(aRange);
+
     HelperNotifyChanges::NotifyIfChangesListeners(*pDocShell, aRange);
 }
 
@@ -193,7 +195,10 @@ void ScUndoDeleteContents::Redo()
     DoChange( false );
     EndRedo();
 
-    BroadcastChanges(aRange);
+    if (nFlags & IDF_CONTENTS)
+        // Broadcast only when the content changes. fdo#74687
+        BroadcastChanges(aRange);
+
     HelperNotifyChanges::NotifyIfChangesListeners(*pDocShell, aRange);
 }
 
commit 82f0cbb54c2040105f8b44784fdf640886588f1d
Author: Kohei Yoshida <kohei.yoshida at collabora.com>
Date:   Wed Apr 16 14:40:09 2014 -0400

    fdo#74555: Avoid excessive calls to GetPreviewCellStyle().
    
    GetOptimalHeight() gets called *all the time* and is very performance
    sensitive.  Let's not do an expensive operation such as GetPreviewCellStyle()
    which slows down pretty much everything else after the non-default font is
    applied.
    
    Change-Id: I5d5b2e706dd5dd98173044642b98ccaedd9536f0
    (cherry picked from commit 947177a5cb79e03a415d9c3d1203420c874d2b35)
    Reviewed-on: https://gerrit.libreoffice.org/9074
    Tested-by: Markus Mohrhard <markus.mohrhard at googlemail.com>
    Reviewed-by: Markus Mohrhard <markus.mohrhard at googlemail.com>

diff --git a/sc/source/core/data/column2.cxx b/sc/source/core/data/column2.cxx
index f6825e2..465ae23 100644
--- a/sc/source/core/data/column2.cxx
+++ b/sc/source/core/data/column2.cxx
@@ -775,15 +775,6 @@ void ScColumn::GetOptimalHeight(
     ::boost::ptr_vector<ScPatternAttr> aAltPatterns;
     while ( pPattern )
     {
-        // GetOptimalHeight called for preview style needs to
-        // use really use the style
-        if ( ScStyleSheet* pStyle = pDocument->GetPreviewCellStyle( nCol, nStartRow, nTab ) )
-        {
-            aAltPatterns.push_back( new ScPatternAttr( *pPattern ) );
-            ScPatternAttr* pModifiedPatt = &aAltPatterns.back();
-            pModifiedPatt->SetStyleSheet( pStyle );
-            pPattern = pModifiedPatt;
-        }
         const ScMergeAttr*      pMerge = (const ScMergeAttr*)&pPattern->GetItem(ATTR_MERGE);
         const ScMergeFlagAttr*  pFlag = (const ScMergeFlagAttr*)&pPattern->GetItem(ATTR_MERGE_FLAG);
         if ( pMerge->GetRowMerge() > 1 || pFlag->IsOverlapped() )
commit 3236313ab830d782ba5c68a82bb832b7e85f5d0d
Author: Kohei Yoshida <kohei.yoshida at collabora.com>
Date:   Tue Apr 15 14:37:47 2014 -0400

    fdo#75665: Truncate string when clipped on screen.
    
    This improves performance of text layouting by HarfBuzz for very long strings.
    HarfBuzz's layout algorithm appears to be more expensive than ICU's.
    
    (cherry picked from commit 087a79db1272858f107656c5ca3c6efb45680986)
    (cherry picked from commit 6fa4d31d6a7e363285f22d4c0012521d10073652)
    (cherry picked from commit 8e50a6c7b1cb9481cce42c71ff07e921fb4292d0)
    (cherry picked from commit 21fc47e115530780ad45ae64e8076dc5e9fedb5e)
    
    Conflicts:
    	sc/inc/scopetools.hxx
    	sc/source/core/tool/scopetools.cxx
    	sc/source/ui/view/output2.cxx
    
    Change-Id: Ic9738b7b8f0f1a29c51c83b147763118939b90ef
    Reviewed-on: https://gerrit.libreoffice.org/9057
    Tested-by: Markus Mohrhard <markus.mohrhard at googlemail.com>
    Reviewed-by: Markus Mohrhard <markus.mohrhard at googlemail.com>

diff --git a/sc/inc/scopetools.hxx b/sc/inc/scopetools.hxx
index 3544b79..802aea1 100644
--- a/sc/inc/scopetools.hxx
+++ b/sc/inc/scopetools.hxx
@@ -35,6 +35,15 @@ public:
     ~ExpandRefsSwitch();
 };
 
+class SC_DLLPUBLIC IdleSwitch
+{
+    ScDocument& mrDoc;
+    bool mbOldValue;
+public:
+    IdleSwitch(ScDocument& rDoc, bool bEnableIdle);
+    ~IdleSwitch();
+};
+
 }
 
 #endif
diff --git a/sc/source/core/tool/scopetools.cxx b/sc/source/core/tool/scopetools.cxx
index af65cff..6f423d0 100644
--- a/sc/source/core/tool/scopetools.cxx
+++ b/sc/source/core/tool/scopetools.cxx
@@ -34,6 +34,17 @@ ExpandRefsSwitch::~ExpandRefsSwitch()
     mrDoc.SetExpandRefs(mbOldValue);
 }
 
+IdleSwitch::IdleSwitch(ScDocument& rDoc, bool bEnableIdle) :
+    mrDoc(rDoc), mbOldValue(rDoc.IsIdleEnabled())
+{
+    mrDoc.EnableIdle(bEnableIdle);
+}
+
+IdleSwitch::~IdleSwitch()
+{
+    mrDoc.EnableIdle(mbOldValue);
+}
+
 }
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/ui/inc/output.hxx b/sc/source/ui/inc/output.hxx
index 03952a8..a34dab6 100644
--- a/sc/source/ui/inc/output.hxx
+++ b/sc/source/ui/inc/output.hxx
@@ -70,6 +70,8 @@ private:
         Rectangle   maAlignRect;
         Rectangle   maClipRect;
         long        mnColWidth;
+        long        mnLeftClipLength; /// length of the string getting cut off on the left.
+        long        mnRightClipLength; /// length of the string getting cut off on the right.
         bool        mbLeftClip;
         bool        mbRightClip;
     };
diff --git a/sc/source/ui/view/output2.cxx b/sc/source/ui/view/output2.cxx
index 544e737..75739d4 100644
--- a/sc/source/ui/view/output2.cxx
+++ b/sc/source/ui/view/output2.cxx
@@ -60,6 +60,7 @@
 #include "markdata.hxx"
 #include "stlsheet.hxx"
 #include "spellcheckcontext.hxx"
+#include <scopetools.hxx>
 
 #include <com/sun/star/i18n/DirectionProperty.hpp>
 #include <comphelper/string.hxx>
@@ -1245,8 +1246,8 @@ void ScOutputData::GetOutputArea( SCCOL nX, SCSIZE nArrY, long nPosX, long nPosY
     --nMergeSizeX;      // leave out the grid horizontally, also for alignment (align between grid lines)
 

... etc. - the rest is truncated


More information about the Libreoffice-commits mailing list