autorecovery.cxx (9f813b30) autorecovery.cxx (1fbfd7a2)
1/**************************************************************
1/**************************************************************
2 *
2 *
3 * Licensed to the Apache Software Foundation (ASF) under one
4 * or more contributor license agreements. See the NOTICE file
5 * distributed with this work for additional information
6 * regarding copyright ownership. The ASF licenses this file
7 * to you under the Apache License, Version 2.0 (the
8 * "License"); you may not use this file except in compliance
9 * with the License. You may obtain a copy of the License at
3 * Licensed to the Apache Software Foundation (ASF) under one
4 * or more contributor license agreements. See the NOTICE file
5 * distributed with this work for additional information
6 * regarding copyright ownership. The ASF licenses this file
7 * to you under the Apache License, Version 2.0 (the
8 * "License"); you may not use this file except in compliance
9 * with the License. You may obtain a copy of the License at
10 *
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
12 *
13 * Unless required by applicable law or agreed to in writing,
14 * software distributed under the License is distributed on an
15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 * KIND, either express or implied. See the License for the
17 * specific language governing permissions and limitations
18 * under the License.
13 * Unless required by applicable law or agreed to in writing,
14 * software distributed under the License is distributed on an
15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 * KIND, either express or implied. See the License for the
17 * specific language governing permissions and limitations
18 * under the License.
19 *
19 *
20 *************************************************************/
21
22
23
24// MARKER(update_precomp.py): autogen include statement, do not remove
25#include "precompiled_framework.hxx"
26
27#include "services/autorecovery.hxx"

--- 190 unchanged lines hidden (view full) ---

218#define SAVE_IN_PROGRESS sal_True
219#define SAVE_FINISHED sal_False
220
221#define LOCK_FOR_CACHE_ADD_REMOVE sal_True
222#define LOCK_FOR_CACHE_USE sal_False
223
224#define MIN_TIME_FOR_USER_IDLE 10000 // 10s user idle
225
20 *************************************************************/
21
22
23
24// MARKER(update_precomp.py): autogen include statement, do not remove
25#include "precompiled_framework.hxx"
26
27#include "services/autorecovery.hxx"

--- 190 unchanged lines hidden (view full) ---

218#define SAVE_IN_PROGRESS sal_True
219#define SAVE_FINISHED sal_False
220
221#define LOCK_FOR_CACHE_ADD_REMOVE sal_True
222#define LOCK_FOR_CACHE_USE sal_False
223
224#define MIN_TIME_FOR_USER_IDLE 10000 // 10s user idle
225
226// enable the following defines in case you whish to simulate a full disc for debug purposes .-)
226// enable the following defines in case you wish to simulate a full disc for debug purposes .-)
227
228// this define throws every time a document is stored or a configuration change
229// should be flushed an exception ... so the special error handler for this scenario is triggered
230// #define TRIGGER_FULL_DISC_CHECK
231
232// force "return sal_False" for the method impl_enoughDiscSpace().
233// #define SIMULATE_FULL_DISC
234

--- 110 unchanged lines hidden (view full) ---

345 }
346};
347
348//-----------------------------------------------
349class CacheLockGuard
350{
351 private:
352
227
228// this define throws every time a document is stored or a configuration change
229// should be flushed an exception ... so the special error handler for this scenario is triggered
230// #define TRIGGER_FULL_DISC_CHECK
231
232// force "return sal_False" for the method impl_enoughDiscSpace().
233// #define SIMULATE_FULL_DISC
234

--- 110 unchanged lines hidden (view full) ---

345 }
346};
347
348//-----------------------------------------------
349class CacheLockGuard
350{
351 private:
352
353 // holds the outside calli alive, so it's shared resources
354 // are valid everytimes
353 // holds the outside calli alive, so its shared resources
354 // are valid every time
355 css::uno::Reference< css::uno::XInterface > m_xOwner;
356
357 // mutex shared with outside calli !
358 LockHelper& m_rSharedMutex;
359
360 // this variable knows the state of the "cache lock"
361 sal_Int32& m_rCacheLock;
362

--- 186 unchanged lines hidden (view full) ---

549 */
550
551 // read configuration to know if autosave/recovery is on/off etcpp...
552 implts_readConfig();
553
554 implts_startListening();
555
556 // establish callback for our internal used timer.
355 css::uno::Reference< css::uno::XInterface > m_xOwner;
356
357 // mutex shared with outside calli !
358 LockHelper& m_rSharedMutex;
359
360 // this variable knows the state of the "cache lock"
361 sal_Int32& m_rCacheLock;
362

--- 186 unchanged lines hidden (view full) ---

549 */
550
551 // read configuration to know if autosave/recovery is on/off etcpp...
552 implts_readConfig();
553
554 implts_startListening();
555
556 // establish callback for our internal used timer.
557 // Note: Its only active, if the timer will be started ...
557 // Note: It's only active, if the timer will be started ...
558 m_aTimer.SetTimeoutHdl(LINK(this, AutoRecovery, implts_timerExpired));
559/*
560 DbgListener* pListener = new DbgListener();
561 pListener->startListening(this);
562*/
563 }
564 )
565

--- 64 unchanged lines hidden (view full) ---

630 // it's important to set a flag internally, so AutoRecovery will be suppressed - even if it's requested.
631 m_eJob |= eNewJob;
632 implts_stopTimer();
633 implts_stopListening();
634 return;
635 }
636
637 // disable/enable AutoSave for this office session only
558 m_aTimer.SetTimeoutHdl(LINK(this, AutoRecovery, implts_timerExpired));
559/*
560 DbgListener* pListener = new DbgListener();
561 pListener->startListening(this);
562*/
563 }
564 )
565

--- 64 unchanged lines hidden (view full) ---

630 // it's important to set a flag internally, so AutoRecovery will be suppressed - even if it's requested.
631 m_eJob |= eNewJob;
632 implts_stopTimer();
633 implts_stopListening();
634 return;
635 }
636
637 // disable/enable AutoSave for this office session only
638 // independend from the configuration entry.
638 // independent from the configuration entry.
639 if ((eNewJob & AutoRecovery::E_SET_AUTOSAVE_STATE) == AutoRecovery::E_SET_AUTOSAVE_STATE)
640 {
641 sal_Bool bOn = lArgs.getUnpackedValueOrDefault(PROP_AUTOSAVE_STATE, (sal_Bool)sal_True);
642 if (bOn)
643 {
639 if ((eNewJob & AutoRecovery::E_SET_AUTOSAVE_STATE) == AutoRecovery::E_SET_AUTOSAVE_STATE)
640 {
641 sal_Bool bOn = lArgs.getUnpackedValueOrDefault(PROP_AUTOSAVE_STATE, (sal_Bool)sal_True);
642 if (bOn)
643 {
644 // dont enable AutoSave hardly !
644 // don't enable AutoSave hardly !
645 // reload configuration to know the current state.
646 implts_readAutoSaveConfig();
647 implts_updateTimer();
648 // can it happen that might be the listener was stopped ? .-)
645 // reload configuration to know the current state.
646 implts_readAutoSaveConfig();
647 implts_updateTimer();
648 // can it happen that might be the listener was stopped ? .-)
649 // make sure it runs always ... even if AutoSave itself was disabled temporarly.
649 // make sure it runs always ... even if AutoSave itself was disabled temporarily.
650 implts_startListening();
651 }
652 else
653 {
654 implts_stopTimer();
655 m_eJob &= ~AutoRecovery::E_AUTO_SAVE;
656 m_eTimerType = AutoRecovery::E_DONT_START_TIMER;
657 }

--- 22 unchanged lines hidden (view full) ---

680void AutoRecovery::implts_dispatch(const DispatchParams& aParams)
681{
682 // SAFE -> ----------------------------------
683 WriteGuard aWriteLock(m_aLock);
684 sal_Int32 eJob = m_eJob;
685 aWriteLock.unlock();
686 // <- SAFE ----------------------------------
687
650 implts_startListening();
651 }
652 else
653 {
654 implts_stopTimer();
655 m_eJob &= ~AutoRecovery::E_AUTO_SAVE;
656 m_eTimerType = AutoRecovery::E_DONT_START_TIMER;
657 }

--- 22 unchanged lines hidden (view full) ---

680void AutoRecovery::implts_dispatch(const DispatchParams& aParams)
681{
682 // SAFE -> ----------------------------------
683 WriteGuard aWriteLock(m_aLock);
684 sal_Int32 eJob = m_eJob;
685 aWriteLock.unlock();
686 // <- SAFE ----------------------------------
687
688 // in case a new dispatch overwrites a may ba active AutoSave session
688 // in case a new dispatch overwrites a maybe active AutoSave session
689 // we must restore this session later. see below ...
690 sal_Bool bWasAutoSaveActive = ((eJob & AutoRecovery::E_AUTO_SAVE) == AutoRecovery::E_AUTO_SAVE);
691
692 // On the other side it make no sense to reactivate the AutoSave operation
693 // if the new dispatch indicates a final decision ...
694 // E.g. an EmergencySave/SessionSave indicates the end of life of the current office session.
695 // It make no sense to reactivate an AutoSave then.
696 // But a Recovery or SessionRestore should reactivate a may be already active AutoSave.

--- 316 unchanged lines hidden (view full) ---

1013 }
1014
1015 // dispose from one of our cached documents ?
1016 // Normally they should send a OnUnload message ...
1017 // But some stacktraces shows another possible use case .-)
1018 css::uno::Reference< css::frame::XModel > xDocument(aEvent.Source, css::uno::UNO_QUERY);
1019 if (xDocument.is())
1020 {
689 // we must restore this session later. see below ...
690 sal_Bool bWasAutoSaveActive = ((eJob & AutoRecovery::E_AUTO_SAVE) == AutoRecovery::E_AUTO_SAVE);
691
692 // On the other side it make no sense to reactivate the AutoSave operation
693 // if the new dispatch indicates a final decision ...
694 // E.g. an EmergencySave/SessionSave indicates the end of life of the current office session.
695 // It make no sense to reactivate an AutoSave then.
696 // But a Recovery or SessionRestore should reactivate a may be already active AutoSave.

--- 316 unchanged lines hidden (view full) ---

1013 }
1014
1015 // dispose from one of our cached documents ?
1016 // Normally they should send a OnUnload message ...
1017 // But some stacktraces shows another possible use case .-)
1018 css::uno::Reference< css::frame::XModel > xDocument(aEvent.Source, css::uno::UNO_QUERY);
1019 if (xDocument.is())
1020 {
1021 implts_deregisterDocument(xDocument, sal_False); // sal_False => dont call removeEventListener() .. because it's not needed here
1021 implts_deregisterDocument(xDocument, sal_False); // sal_False => don't call removeEventListener() .. because it's not needed here
1022 return;
1023 }
1024
1025 // <- SAFE ----------------------------------
1026}
1027
1028//-----------------------------------------------
1029css::uno::Reference< css::container::XNameAccess > AutoRecovery::implts_openConfig()
1030{
1031 // SAFE -> ----------------------------------
1032 WriteGuard aWriteLock(m_aLock);
1033
1034 if (m_xRecoveryCFG.is())
1035 return m_xRecoveryCFG;
1036 css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR = m_xSMGR;
1037
1038 aWriteLock.unlock();
1039 // <- SAFE ----------------------------------
1040
1022 return;
1023 }
1024
1025 // <- SAFE ----------------------------------
1026}
1027
1028//-----------------------------------------------
1029css::uno::Reference< css::container::XNameAccess > AutoRecovery::implts_openConfig()
1030{
1031 // SAFE -> ----------------------------------
1032 WriteGuard aWriteLock(m_aLock);
1033
1034 if (m_xRecoveryCFG.is())
1035 return m_xRecoveryCFG;
1036 css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR = m_xSMGR;
1037
1038 aWriteLock.unlock();
1039 // <- SAFE ----------------------------------
1040
1041 // throws a RuntimeException if an error occure!
1041 // throws a RuntimeException if an error occurs!
1042 css::uno::Reference< css::container::XNameAccess > xCFG(
1043 ::comphelper::ConfigurationHelper::openConfig(xSMGR, CFG_PACKAGE_RECOVERY, ::comphelper::ConfigurationHelper::E_STANDARD),
1044 css::uno::UNO_QUERY);
1045
1046 sal_Int32 nMinSpaceDocSave = MIN_DISCSPACE_DOCSAVE;
1047 sal_Int32 nMinSpaceConfigSave = MIN_DISCSPACE_CONFIGSAVE;
1048
1049 try

--- 7 unchanged lines hidden (view full) ---

1057 ::comphelper::ConfigurationHelper::readDirectKey(xSMGR,
1058 CFG_PACKAGE_RECOVERY,
1059 CFG_PATH_AUTOSAVE,
1060 CFG_ENTRY_MINSPACE_CONFIGSAVE,
1061 ::comphelper::ConfigurationHelper::E_STANDARD) >>= nMinSpaceConfigSave;
1062 }
1063 catch(const css::uno::Exception&)
1064 {
1042 css::uno::Reference< css::container::XNameAccess > xCFG(
1043 ::comphelper::ConfigurationHelper::openConfig(xSMGR, CFG_PACKAGE_RECOVERY, ::comphelper::ConfigurationHelper::E_STANDARD),
1044 css::uno::UNO_QUERY);
1045
1046 sal_Int32 nMinSpaceDocSave = MIN_DISCSPACE_DOCSAVE;
1047 sal_Int32 nMinSpaceConfigSave = MIN_DISCSPACE_CONFIGSAVE;
1048
1049 try

--- 7 unchanged lines hidden (view full) ---

1057 ::comphelper::ConfigurationHelper::readDirectKey(xSMGR,
1058 CFG_PACKAGE_RECOVERY,
1059 CFG_PATH_AUTOSAVE,
1060 CFG_ENTRY_MINSPACE_CONFIGSAVE,
1061 ::comphelper::ConfigurationHelper::E_STANDARD) >>= nMinSpaceConfigSave;
1062 }
1063 catch(const css::uno::Exception&)
1064 {
1065 // These config keys are not sooooo important, that
1065 // These config keys are not so important, that
1066 // we are interested on errors here really .-)
1067 nMinSpaceDocSave = MIN_DISCSPACE_DOCSAVE;
1068 nMinSpaceConfigSave = MIN_DISCSPACE_CONFIGSAVE;
1069 }
1070
1071 // SAFE -> ----------------------------------
1072 aWriteLock.lock();
1073 m_xRecoveryCFG = xCFG;

--- 294 unchanged lines hidden (view full) ---

1368 sIDBuf.append(RECOVERY_ITEM_BASE_IDENTIFIER);
1369 sIDBuf.append((sal_Int32)rInfo.ID);
1370 ::rtl::OUString sID = sIDBuf.makeStringAndClear();
1371
1372 // remove
1373 if (bRemoveIt)
1374 {
1375 // Catch NoSuchElementException.
1066 // we are interested on errors here really .-)
1067 nMinSpaceDocSave = MIN_DISCSPACE_DOCSAVE;
1068 nMinSpaceConfigSave = MIN_DISCSPACE_CONFIGSAVE;
1069 }
1070
1071 // SAFE -> ----------------------------------
1072 aWriteLock.lock();
1073 m_xRecoveryCFG = xCFG;

--- 294 unchanged lines hidden (view full) ---

1368 sIDBuf.append(RECOVERY_ITEM_BASE_IDENTIFIER);
1369 sIDBuf.append((sal_Int32)rInfo.ID);
1370 ::rtl::OUString sID = sIDBuf.makeStringAndClear();
1371
1372 // remove
1373 if (bRemoveIt)
1374 {
1375 // Catch NoSuchElementException.
1376 // Its not a good idea inside multithreaded environments to call hasElement - removeElement.
1376 // It's not a good idea inside multithreaded environments to call hasElement - removeElement.
1377 // DO IT!
1378 try
1379 {
1380 xModify->removeByName(sID);
1381 }
1382 catch(const css::container::NoSuchElementException&)
1383 { return; }
1384 }

--- 111 unchanged lines hidden (view full) ---

1496 }
1497}
1498
1499//-----------------------------------------------
1500void AutoRecovery::implts_stopListening()
1501{
1502 // SAFE -> ----------------------------------
1503 ReadGuard aReadLock(m_aLock);
1377 // DO IT!
1378 try
1379 {
1380 xModify->removeByName(sID);
1381 }
1382 catch(const css::container::NoSuchElementException&)
1383 { return; }
1384 }

--- 111 unchanged lines hidden (view full) ---

1496 }
1497}
1498
1499//-----------------------------------------------
1500void AutoRecovery::implts_stopListening()
1501{
1502 // SAFE -> ----------------------------------
1503 ReadGuard aReadLock(m_aLock);
1504 // Attention: Dont reset our internal members here too.
1505 // May be we must work with our configuration, but dont wish to be informed
1504 // Attention: Don't reset our internal members here too.
1505 // May be we must work with our configuration, but don't wish to be informed
1506 // about changes any longer. Needed e.g. during EMERGENCY_SAVE!
1507 css::uno::Reference< css::util::XChangesNotifier > xCFG (m_xRecoveryCFG , css::uno::UNO_QUERY);
1508 css::uno::Reference< css::document::XEventBroadcaster > xGlobalEventBroadcaster(m_xNewDocBroadcaster, css::uno::UNO_QUERY);
1509 aReadLock.unlock();
1510 // <- SAFE ----------------------------------
1511
1512 if (
1513 (xGlobalEventBroadcaster.is()) &&

--- 48 unchanged lines hidden (view full) ---

1562void AutoRecovery::implts_updateTimer()
1563{
1564 implts_stopTimer();
1565
1566 // SAFE -> ----------------------------------
1567 WriteGuard aWriteLock(m_aLock);
1568
1569 if (
1506 // about changes any longer. Needed e.g. during EMERGENCY_SAVE!
1507 css::uno::Reference< css::util::XChangesNotifier > xCFG (m_xRecoveryCFG , css::uno::UNO_QUERY);
1508 css::uno::Reference< css::document::XEventBroadcaster > xGlobalEventBroadcaster(m_xNewDocBroadcaster, css::uno::UNO_QUERY);
1509 aReadLock.unlock();
1510 // <- SAFE ----------------------------------
1511
1512 if (
1513 (xGlobalEventBroadcaster.is()) &&

--- 48 unchanged lines hidden (view full) ---

1562void AutoRecovery::implts_updateTimer()
1563{
1564 implts_stopTimer();
1565
1566 // SAFE -> ----------------------------------
1567 WriteGuard aWriteLock(m_aLock);
1568
1569 if (
1570 (m_eJob == AutoRecovery::E_NO_JOB ) || // TODO may be superflous - E_DONT_START_TIMER should be used only
1570 (m_eJob == AutoRecovery::E_NO_JOB ) || // TODO may be superfluous - E_DONT_START_TIMER should be used only
1571 (m_eTimerType == AutoRecovery::E_DONT_START_TIMER)
1572 )
1573 return;
1574
1575 sal_uLong nMilliSeconds = 0;
1576 if (m_eTimerType == AutoRecovery::E_NORMAL_AUTOSAVE_INTERVALL)
1577 {
1578 nMilliSeconds = (m_nAutoSaveTimeIntervall*60000); // [min] => 60.000 ms

--- 55 unchanged lines hidden (view full) ---

1634 // But so we are more "safe" .-)
1635 // SAFE -> ----------------------------------
1636 ReadGuard aReadLock(m_aLock);
1637 if ((m_eJob & AutoRecovery::E_DISABLE_AUTORECOVERY) == AutoRecovery::E_DISABLE_AUTORECOVERY)
1638 return 0;
1639 aReadLock.unlock();
1640 // <- SAFE ----------------------------------
1641
1571 (m_eTimerType == AutoRecovery::E_DONT_START_TIMER)
1572 )
1573 return;
1574
1575 sal_uLong nMilliSeconds = 0;
1576 if (m_eTimerType == AutoRecovery::E_NORMAL_AUTOSAVE_INTERVALL)
1577 {
1578 nMilliSeconds = (m_nAutoSaveTimeIntervall*60000); // [min] => 60.000 ms

--- 55 unchanged lines hidden (view full) ---

1634 // But so we are more "safe" .-)
1635 // SAFE -> ----------------------------------
1636 ReadGuard aReadLock(m_aLock);
1637 if ((m_eJob & AutoRecovery::E_DISABLE_AUTORECOVERY) == AutoRecovery::E_DISABLE_AUTORECOVERY)
1638 return 0;
1639 aReadLock.unlock();
1640 // <- SAFE ----------------------------------
1641
1642 // check some "states", where its not allowed (better: not a good idea) to
1642 // check some "states", where it's not allowed (better: not a good idea) to
1643 // start an AutoSave. (e.g. if the user makes drag & drop ...)
1644 // Then we poll till this "disallowed" state is gone.
1645 sal_Bool bAutoSaveNotAllowed = Application::IsUICaptured();
1646 if (bAutoSaveNotAllowed)
1647 {
1648 // SAFE -> ------------------------------
1649 WriteGuard aWriteLock(m_aLock);
1650 m_eTimerType = AutoRecovery::E_POLL_TILL_AUTOSAVE_IS_ALLOWED;

--- 88 unchanged lines hidden (view full) ---

1739 return;
1740
1741 CacheLockGuard aCacheLock(this, m_aLock, m_nDocCacheLock, LOCK_FOR_CACHE_USE);
1742
1743 // notification for already existing document !
1744 // Can happen if events came in asynchronous on recovery time.
1745 // Then our cache was filled from the configuration ... but now we get some
1746 // asynchronous events from the global event broadcaster. We must be sure that
1643 // start an AutoSave. (e.g. if the user makes drag & drop ...)
1644 // Then we poll till this "disallowed" state is gone.
1645 sal_Bool bAutoSaveNotAllowed = Application::IsUICaptured();
1646 if (bAutoSaveNotAllowed)
1647 {
1648 // SAFE -> ------------------------------
1649 WriteGuard aWriteLock(m_aLock);
1650 m_eTimerType = AutoRecovery::E_POLL_TILL_AUTOSAVE_IS_ALLOWED;

--- 88 unchanged lines hidden (view full) ---

1739 return;
1740
1741 CacheLockGuard aCacheLock(this, m_aLock, m_nDocCacheLock, LOCK_FOR_CACHE_USE);
1742
1743 // notification for already existing document !
1744 // Can happen if events came in asynchronous on recovery time.
1745 // Then our cache was filled from the configuration ... but now we get some
1746 // asynchronous events from the global event broadcaster. We must be sure that
1747 // we dont add the same document more then once.
1747 // we don't add the same document more then once.
1748 AutoRecovery::TDocumentList::iterator pIt = AutoRecovery::impl_searchDocument(m_lDocCache, xDocument);
1749 if (pIt != m_lDocCache.end())
1750 {
1751 // Normally nothing must be done for this "late" notification.
1748 AutoRecovery::TDocumentList::iterator pIt = AutoRecovery::impl_searchDocument(m_lDocCache, xDocument);
1749 if (pIt != m_lDocCache.end())
1750 {
1751 // Normally nothing must be done for this "late" notification.
1752 // But maybe the modified state was changed inbetween.
1752 // But maybe the modified state was changed in between.
1753 // Check it ...
1754 implts_updateModifiedState(xDocument);
1755 return;
1756 }
1757
1758 aCacheLock.unlock();
1759
1760 ::comphelper::MediaDescriptor lDescriptor(xDocument->getArgs());
1761
1762 // check if this document must be ignored for recovery !
1753 // Check it ...
1754 implts_updateModifiedState(xDocument);
1755 return;
1756 }
1757
1758 aCacheLock.unlock();
1759
1760 ::comphelper::MediaDescriptor lDescriptor(xDocument->getArgs());
1761
1762 // check if this document must be ignored for recovery !
1763 // Some use cases dont wish support for AutoSave/Recovery ... as e.g. OLE-Server / ActiveX Control etcpp.
1763 // Some use cases don't wish support for AutoSave/Recovery ... as e.g. OLE-Server / ActiveX Control etcpp.
1764 sal_Bool bNoAutoSave = lDescriptor.getUnpackedValueOrDefault(::comphelper::MediaDescriptor::PROP_NOAUTOSAVE(), (sal_Bool)(sal_False));
1765 if (bNoAutoSave)
1766 return;
1767
1768 // Check if doc is well known on the desktop. Otherwise ignore it!
1769 // Other frames mostly are used from external programs - e.g. the bean ...
1770 css::uno::Reference< css::frame::XController > xController = xDocument->getCurrentController();
1771 if (!xController.is())

--- 9 unchanged lines hidden (view full) ---

1781 if ( !xDocRecovery.is() )
1782 return;
1783
1784 // get all needed informations of this document
1785 // We need it to update our cache or to locate already existing elements there!
1786 AutoRecovery::TDocumentInfo aNew;
1787 aNew.Document = xDocument;
1788
1764 sal_Bool bNoAutoSave = lDescriptor.getUnpackedValueOrDefault(::comphelper::MediaDescriptor::PROP_NOAUTOSAVE(), (sal_Bool)(sal_False));
1765 if (bNoAutoSave)
1766 return;
1767
1768 // Check if doc is well known on the desktop. Otherwise ignore it!
1769 // Other frames mostly are used from external programs - e.g. the bean ...
1770 css::uno::Reference< css::frame::XController > xController = xDocument->getCurrentController();
1771 if (!xController.is())

--- 9 unchanged lines hidden (view full) ---

1781 if ( !xDocRecovery.is() )
1782 return;
1783
1784 // get all needed informations of this document
1785 // We need it to update our cache or to locate already existing elements there!
1786 AutoRecovery::TDocumentInfo aNew;
1787 aNew.Document = xDocument;
1788
1789 // TODO replace getLocation() with getURL() ... its a workaround currently only!
1789 // TODO replace getLocation() with getURL() ... it's a workaround currently only!
1790 css::uno::Reference< css::frame::XStorable > xDoc(aNew.Document, css::uno::UNO_QUERY_THROW);
1791 aNew.OrgURL = xDoc->getLocation();
1792
1793 css::uno::Reference< css::frame::XTitle > xTitle(aNew.Document, css::uno::UNO_QUERY_THROW);
1794 aNew.Title = xTitle->getTitle ();
1795
1796 // SAFE -> ----------------------------------
1797 ReadGuard aReadLock(m_aLock);
1798 css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR = m_xSMGR;
1799 aReadLock.unlock();
1800 // <- SAFE ----------------------------------
1801
1802 // classify the used application module, which is used by this document.
1803 implts_specifyAppModuleAndFactory(aNew);
1804
1805 // Hack! Check for "illegal office documents" ... as e.g. the Basic IDE
1790 css::uno::Reference< css::frame::XStorable > xDoc(aNew.Document, css::uno::UNO_QUERY_THROW);
1791 aNew.OrgURL = xDoc->getLocation();
1792
1793 css::uno::Reference< css::frame::XTitle > xTitle(aNew.Document, css::uno::UNO_QUERY_THROW);
1794 aNew.Title = xTitle->getTitle ();
1795
1796 // SAFE -> ----------------------------------
1797 ReadGuard aReadLock(m_aLock);
1798 css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR = m_xSMGR;
1799 aReadLock.unlock();
1800 // <- SAFE ----------------------------------
1801
1802 // classify the used application module, which is used by this document.
1803 implts_specifyAppModuleAndFactory(aNew);
1804
1805 // Hack! Check for "illegal office documents" ... as e.g. the Basic IDE
1806 // Its not really a full featured office document. It doesn't provide an URL, any filter, a factory URL etcpp.
1807 // TODO file bug to Basci IDE developers. They must remove the office document API from its service.
1806 // It's not really a full featured office document. It doesn't provide an URL, any filter, a factory URL etcpp.
1807 // TODO file bug to Basic IDE developers. They must remove the office document API from its service.
1808 if (
1809 (!aNew.OrgURL.getLength() ) &&
1810 (!aNew.FactoryURL.getLength())
1811 )
1812 {
1813 OSL_ENSURE( false, "AutoRecovery::implts_registerDocument: this should not happen anymore!" );
1814 // nowadays, the Basic IDE should already die on the "supports XDocumentRecovery" check. And no other known
1815 // document type fits in here ...

--- 47 unchanged lines hidden (view full) ---

1863//-----------------------------------------------
1864void AutoRecovery::implts_deregisterDocument(const css::uno::Reference< css::frame::XModel >& xDocument ,
1865 sal_Bool bStopListening)
1866{
1867
1868 // SAFE -> ----------------------------------
1869 WriteGuard aWriteLock(m_aLock);
1870
1808 if (
1809 (!aNew.OrgURL.getLength() ) &&
1810 (!aNew.FactoryURL.getLength())
1811 )
1812 {
1813 OSL_ENSURE( false, "AutoRecovery::implts_registerDocument: this should not happen anymore!" );
1814 // nowadays, the Basic IDE should already die on the "supports XDocumentRecovery" check. And no other known
1815 // document type fits in here ...

--- 47 unchanged lines hidden (view full) ---

1863//-----------------------------------------------
1864void AutoRecovery::implts_deregisterDocument(const css::uno::Reference< css::frame::XModel >& xDocument ,
1865 sal_Bool bStopListening)
1866{
1867
1868 // SAFE -> ----------------------------------
1869 WriteGuard aWriteLock(m_aLock);
1870
1871 // Attention: Dont leave SAFE section, if you work with pIt!
1871 // Attention: Don't leave SAFE section, if you work with pIt!
1872 // Because it points directly into the m_lDocCache list ...
1873 CacheLockGuard aCacheLock(this, m_aLock, m_nDocCacheLock, LOCK_FOR_CACHE_USE);
1874
1875 AutoRecovery::TDocumentList::iterator pIt = AutoRecovery::impl_searchDocument(m_lDocCache, xDocument);
1876 if (pIt == m_lDocCache.end())
1877 return; // unknown document => not a runtime error! Because we register only a few documents. see registration ...
1878
1879 AutoRecovery::TDocumentInfo aInfo = *pIt;

--- 38 unchanged lines hidden (view full) ---

1918 WriteGuard aWriteLock(m_aLock);
1919
1920 AutoRecovery::TDocumentList::iterator pIt = AutoRecovery::impl_searchDocument(m_lDocCache, xDocument);
1921 if (pIt != m_lDocCache.end())
1922 {
1923 AutoRecovery::TDocumentInfo& rInfo = *pIt;
1924
1925 /* Now we know, that this document was modified again and must be saved next time.
1872 // Because it points directly into the m_lDocCache list ...
1873 CacheLockGuard aCacheLock(this, m_aLock, m_nDocCacheLock, LOCK_FOR_CACHE_USE);
1874
1875 AutoRecovery::TDocumentList::iterator pIt = AutoRecovery::impl_searchDocument(m_lDocCache, xDocument);
1876 if (pIt == m_lDocCache.end())
1877 return; // unknown document => not a runtime error! Because we register only a few documents. see registration ...
1878
1879 AutoRecovery::TDocumentInfo aInfo = *pIt;

--- 38 unchanged lines hidden (view full) ---

1918 WriteGuard aWriteLock(m_aLock);
1919
1920 AutoRecovery::TDocumentList::iterator pIt = AutoRecovery::impl_searchDocument(m_lDocCache, xDocument);
1921 if (pIt != m_lDocCache.end())
1922 {
1923 AutoRecovery::TDocumentInfo& rInfo = *pIt;
1924
1925 /* Now we know, that this document was modified again and must be saved next time.
1926 But we dont need this information for every e.g. key input of the user.
1926 But we don't need this information for every e.g. key input of the user.
1927 So we stop listening here.
1928 But if the document was saved as temp. file we start listening for this event again.
1929 */
1930 implts_stopModifyListeningOnDoc(rInfo);
1931 }
1932
1933 aWriteLock.unlock();
1934 // <- SAFE ----------------------------------

--- 59 unchanged lines hidden (view full) ---

1994 WriteGuard aWriteLock(m_aLock);
1995
1996 AutoRecovery::TDocumentList::iterator pIt = AutoRecovery::impl_searchDocument(m_lDocCache, xDocument);
1997 if (pIt == m_lDocCache.end())
1998 return;
1999 AutoRecovery::TDocumentInfo& rInfo = *pIt;
2000
2001 rInfo.DocumentState = AutoRecovery::E_UNKNOWN;
1927 So we stop listening here.
1928 But if the document was saved as temp. file we start listening for this event again.
1929 */
1930 implts_stopModifyListeningOnDoc(rInfo);
1931 }
1932
1933 aWriteLock.unlock();
1934 // <- SAFE ----------------------------------

--- 59 unchanged lines hidden (view full) ---

1994 WriteGuard aWriteLock(m_aLock);
1995
1996 AutoRecovery::TDocumentList::iterator pIt = AutoRecovery::impl_searchDocument(m_lDocCache, xDocument);
1997 if (pIt == m_lDocCache.end())
1998 return;
1999 AutoRecovery::TDocumentInfo& rInfo = *pIt;
2000
2001 rInfo.DocumentState = AutoRecovery::E_UNKNOWN;
2002 // TODO replace getLocation() with getURL() ... its a workaround currently only!
2002 // TODO replace getLocation() with getURL() ... it's a workaround currently only!
2003 css::uno::Reference< css::frame::XStorable > xDoc(rInfo.Document, css::uno::UNO_QUERY);
2004 rInfo.OrgURL = xDoc->getLocation();
2005
2006 ::rtl::OUString sRemoveURL1 = rInfo.OldTempURL;
2007 ::rtl::OUString sRemoveURL2 = rInfo.NewTempURL;
2008 rInfo.OldTempURL = ::rtl::OUString();
2009 rInfo.NewTempURL = ::rtl::OUString();
2010

--- 120 unchanged lines hidden (view full) ---

2131 AutoRecovery::TDocumentList::iterator pIt;
2132 for ( pIt = m_lDocCache.begin();
2133 pIt != m_lDocCache.end() ;
2134 ++pIt )
2135 {
2136 AutoRecovery::TDocumentInfo& rInfo = *pIt;
2137
2138 // WORKAROUND... Since the documents are not closed the lock file must be removed explicitly
2003 css::uno::Reference< css::frame::XStorable > xDoc(rInfo.Document, css::uno::UNO_QUERY);
2004 rInfo.OrgURL = xDoc->getLocation();
2005
2006 ::rtl::OUString sRemoveURL1 = rInfo.OldTempURL;
2007 ::rtl::OUString sRemoveURL2 = rInfo.NewTempURL;
2008 rInfo.OldTempURL = ::rtl::OUString();
2009 rInfo.NewTempURL = ::rtl::OUString();
2010

--- 120 unchanged lines hidden (view full) ---

2131 AutoRecovery::TDocumentList::iterator pIt;
2132 for ( pIt = m_lDocCache.begin();
2133 pIt != m_lDocCache.end() ;
2134 ++pIt )
2135 {
2136 AutoRecovery::TDocumentInfo& rInfo = *pIt;
2137
2138 // WORKAROUND... Since the documents are not closed the lock file must be removed explicitly
2139 // it is not done on documents saving since shutdown can be cancelled
2139 // it is not done on documents saving since shutdown can be canceled
2140 lc_removeLockFile( rInfo );
2141
2142 // Prevent us from deregistration of these documents.
2143 // Because we close these documents by ourself (see XClosable below) ...
2144 // it's fact, that we reach our deregistration method. There we
2145 // must not(!) update our configuration ... Otherwise all
2146 // session data are lost !!!
2147 rInfo.IgnoreClosing = sal_True;
2148
2149 // reset modified flag of these documents (ignoring the notification about it!)
2150 // Otherwise a message box is shown on closing these models.
2151 implts_stopModifyListeningOnDoc(rInfo);
2152
2153 // if the session save is still running the documents should not be thrown away,
2140 lc_removeLockFile( rInfo );
2141
2142 // Prevent us from deregistration of these documents.
2143 // Because we close these documents by ourself (see XClosable below) ...
2144 // it's fact, that we reach our deregistration method. There we
2145 // must not(!) update our configuration ... Otherwise all
2146 // session data are lost !!!
2147 rInfo.IgnoreClosing = sal_True;
2148
2149 // reset modified flag of these documents (ignoring the notification about it!)
2150 // Otherwise a message box is shown on closing these models.
2151 implts_stopModifyListeningOnDoc(rInfo);
2152
2153 // if the session save is still running the documents should not be thrown away,
2154 // actually that would be a bad sign, that means that the SessionManager tryes
2154 // actually that would be a bad sign, that means that the SessionManager tries
2155 // to kill the session before the saving is ready
2156 if ((m_eJob & AutoRecovery::E_SESSION_SAVE) != AutoRecovery::E_SESSION_SAVE)
2157 {
2158 css::uno::Reference< css::util::XModifiable > xModify(rInfo.Document, css::uno::UNO_QUERY);
2159 if (xModify.is())
2160 xModify->setModified(sal_False);
2161
2162 // close the model.

--- 30 unchanged lines hidden (view full) ---

2193
2194 #i64599#
2195
2196 Normally the MediaDescriptor argument NoAutoSave indicates,
2197 that a document must be ignored for AutoSave and Recovery.
2198 But sometimes XModel->getArgs() does not contained this information
2199 if implts_registerDocument() was called.
2200 So we have to check a second time, if this property is set ....
2155 // to kill the session before the saving is ready
2156 if ((m_eJob & AutoRecovery::E_SESSION_SAVE) != AutoRecovery::E_SESSION_SAVE)
2157 {
2158 css::uno::Reference< css::util::XModifiable > xModify(rInfo.Document, css::uno::UNO_QUERY);
2159 if (xModify.is())
2160 xModify->setModified(sal_False);
2161
2162 // close the model.

--- 30 unchanged lines hidden (view full) ---

2193
2194 #i64599#
2195
2196 Normally the MediaDescriptor argument NoAutoSave indicates,
2197 that a document must be ignored for AutoSave and Recovery.
2198 But sometimes XModel->getArgs() does not contained this information
2199 if implts_registerDocument() was called.
2200 So we have to check a second time, if this property is set ....
2201 Best place doing so is to check it immeditaly before saving
2202 and supressingd saving the document then.
2201 Best place doing so is to check it immediately before saving
2202 and suppressing saving the document then.
2203 Of course removing the corresponding cache entry isn't an option.
2204 Because it would disturb iteration over the cache !
2205 So we ignore such documents only ...
2206 Hopefully next time they are not inserted in our cache.
2207*/
2208sal_Bool lc_checkIfSaveForbiddenByArguments(AutoRecovery::TDocumentInfo& rInfo)
2209{
2210 if (! rInfo.Document.is())

--- 31 unchanged lines hidden (view full) ---

2242 if (xActiveController.is())
2243 xActiveModel = xActiveController->getModel();
2244
2245 // Set the default timer action for our calli.
2246 // Default = NORMAL_AUTOSAVE
2247 // We return a suggestion for an active timer only.
2248 // It will be ignored if the timer was disabled by the user ...
2249 // Further this state can be set to USER_IDLE only later in this method.
2203 Of course removing the corresponding cache entry isn't an option.
2204 Because it would disturb iteration over the cache !
2205 So we ignore such documents only ...
2206 Hopefully next time they are not inserted in our cache.
2207*/
2208sal_Bool lc_checkIfSaveForbiddenByArguments(AutoRecovery::TDocumentInfo& rInfo)
2209{
2210 if (! rInfo.Document.is())

--- 31 unchanged lines hidden (view full) ---

2242 if (xActiveController.is())
2243 xActiveModel = xActiveController->getModel();
2244
2245 // Set the default timer action for our calli.
2246 // Default = NORMAL_AUTOSAVE
2247 // We return a suggestion for an active timer only.
2248 // It will be ignored if the timer was disabled by the user ...
2249 // Further this state can be set to USER_IDLE only later in this method.
2250 // Its not allowed to reset such state then. Because we must know, if
2250 // It's not allowed to reset such state then. Because we must know, if
2251 // there exists POSTPONED documents. see below ...
2252 AutoRecovery::ETimerType eTimer = AutoRecovery::E_NORMAL_AUTOSAVE_INTERVALL;
2253
2254 sal_Int32 eJob = m_eJob;
2255
2256 CacheLockGuard aCacheLock(this, m_aLock, m_nDocCacheLock, LOCK_FOR_CACHE_USE);
2257
2258 // SAFE -> ----------------------------------

--- 166 unchanged lines hidden (view full) ---

2425 if (xExternalProgress.is())
2426 lNewArgs[::comphelper::MediaDescriptor::PROP_STATUSINDICATOR()] <<= xExternalProgress;
2427 impl_establishProgress(rInfo, lNewArgs, css::uno::Reference< css::frame::XFrame >());
2428
2429 // #i66598# use special handling of property "DocumentBaseURL" (it must be an empty string!)
2430 // for make hyperlinks working
2431 lNewArgs[::comphelper::MediaDescriptor::PROP_DOCUMENTBASEURL()] <<= ::rtl::OUString();
2432
2251 // there exists POSTPONED documents. see below ...
2252 AutoRecovery::ETimerType eTimer = AutoRecovery::E_NORMAL_AUTOSAVE_INTERVALL;
2253
2254 sal_Int32 eJob = m_eJob;
2255
2256 CacheLockGuard aCacheLock(this, m_aLock, m_nDocCacheLock, LOCK_FOR_CACHE_USE);
2257
2258 // SAFE -> ----------------------------------

--- 166 unchanged lines hidden (view full) ---

2425 if (xExternalProgress.is())
2426 lNewArgs[::comphelper::MediaDescriptor::PROP_STATUSINDICATOR()] <<= xExternalProgress;
2427 impl_establishProgress(rInfo, lNewArgs, css::uno::Reference< css::frame::XFrame >());
2428
2429 // #i66598# use special handling of property "DocumentBaseURL" (it must be an empty string!)
2430 // for make hyperlinks working
2431 lNewArgs[::comphelper::MediaDescriptor::PROP_DOCUMENTBASEURL()] <<= ::rtl::OUString();
2432
2433 // try to save this document as a new temp file everytimes.
2433 // try to save this document as a new temp file every time.
2434 // Mark AutoSave state as "INCOMPLETE" if it failed.
2435 // Because the last temp file is to old and does not include all changes.
2436 Reference< XDocumentRecovery > xDocRecover(rInfo.Document, css::uno::UNO_QUERY_THROW);
2437
2438 // safe the state about "trying to save"
2439 // ... we need it for recovery if e.g. a crash occurs inside next line!
2440 rInfo.DocumentState |= AutoRecovery::E_TRY_SAVE;
2441 implts_flushConfigItem(rInfo);

--- 38 unchanged lines hidden (view full) ---

2480
2481 --nRetry;
2482 }
2483 }
2484 while(nRetry>0);
2485
2486 if (! bError)
2487 {
2434 // Mark AutoSave state as "INCOMPLETE" if it failed.
2435 // Because the last temp file is to old and does not include all changes.
2436 Reference< XDocumentRecovery > xDocRecover(rInfo.Document, css::uno::UNO_QUERY_THROW);
2437
2438 // safe the state about "trying to save"
2439 // ... we need it for recovery if e.g. a crash occurs inside next line!
2440 rInfo.DocumentState |= AutoRecovery::E_TRY_SAVE;
2441 implts_flushConfigItem(rInfo);

--- 38 unchanged lines hidden (view full) ---

2480
2481 --nRetry;
2482 }
2483 }
2484 while(nRetry>0);
2485
2486 if (! bError)
2487 {
2488 // safe the state about success
2488 // save the state about success
2489 // ... you know the reason: to know it on recovery time if next line crash .-)
2490 rInfo.DocumentState &= ~AutoRecovery::E_TRY_SAVE;
2491 rInfo.DocumentState |= AutoRecovery::E_HANDLED;
2492 rInfo.DocumentState |= AutoRecovery::E_SUCCEDED;
2493 }
2494 else
2495 {
2489 // ... you know the reason: to know it on recovery time if next line crash .-)
2490 rInfo.DocumentState &= ~AutoRecovery::E_TRY_SAVE;
2491 rInfo.DocumentState |= AutoRecovery::E_HANDLED;
2492 rInfo.DocumentState |= AutoRecovery::E_SUCCEDED;
2493 }
2494 else
2495 {
2496 // safe the state about error ...
2496 // save the state about error ...
2497 rInfo.NewTempURL = ::rtl::OUString();
2498 rInfo.DocumentState &= ~AutoRecovery::E_TRY_SAVE;
2499 rInfo.DocumentState |= AutoRecovery::E_HANDLED;
2500 rInfo.DocumentState |= AutoRecovery::E_INCOMPLETE;
2501 }
2502
2503 // make sure the progress isn't referred any longer
2504 impl_forgetProgress(rInfo, lNewArgs, css::uno::Reference< css::frame::XFrame >());

--- 27 unchanged lines hidden (view full) ---

2532 AutoRecovery::TDocumentList::iterator pIt;
2533 for ( pIt = m_lDocCache.begin();
2534 pIt != m_lDocCache.end() ;
2535 ++pIt )
2536 {
2537 AutoRecovery::TDocumentInfo& rInfo = *pIt;
2538
2539 // Such documents are already loaded by the last loop.
2497 rInfo.NewTempURL = ::rtl::OUString();
2498 rInfo.DocumentState &= ~AutoRecovery::E_TRY_SAVE;
2499 rInfo.DocumentState |= AutoRecovery::E_HANDLED;
2500 rInfo.DocumentState |= AutoRecovery::E_INCOMPLETE;
2501 }
2502
2503 // make sure the progress isn't referred any longer
2504 impl_forgetProgress(rInfo, lNewArgs, css::uno::Reference< css::frame::XFrame >());

--- 27 unchanged lines hidden (view full) ---

2532 AutoRecovery::TDocumentList::iterator pIt;
2533 for ( pIt = m_lDocCache.begin();
2534 pIt != m_lDocCache.end() ;
2535 ++pIt )
2536 {
2537 AutoRecovery::TDocumentInfo& rInfo = *pIt;
2538
2539 // Such documents are already loaded by the last loop.
2540 // Dont check E_SUCCEDED here! Its may be the final state of an AutoSave
2540 // Don't check E_SUCCEDED here! It may be the final state of an AutoSave
2541 // operation before!!!
2542 if ((rInfo.DocumentState & AutoRecovery::E_HANDLED) == AutoRecovery::E_HANDLED)
2543 continue;
2544
2545 // a1,b1,c1,d2,e2,f2)
2546 if ((rInfo.DocumentState & AutoRecovery::E_DAMAGED) == AutoRecovery::E_DAMAGED)
2547 {
2541 // operation before!!!
2542 if ((rInfo.DocumentState & AutoRecovery::E_HANDLED) == AutoRecovery::E_HANDLED)
2543 continue;
2544
2545 // a1,b1,c1,d2,e2,f2)
2546 if ((rInfo.DocumentState & AutoRecovery::E_DAMAGED) == AutoRecovery::E_DAMAGED)
2547 {
2548 // dont forget to inform listener! May be this document was
2548 // don't forget to inform listener! May be this document was
2549 // damaged on last saving time ...
2550 // Then our listener need this notification.
2551 // If it was damaged during last "try to open" ...
2552 // it will be notified more then once. SH.. HAPPENS ...
2553 // <- SAFE --------------------------
2554 aWriteLock.unlock();
2555 implts_informListener(eJob,
2556 AutoRecovery::implst_createFeatureStateEvent(eJob, OPERATION_UPDATE, &rInfo));
2557 aWriteLock.lock();
2558 // SAFE -> --------------------------
2559 continue;
2560 }
2561
2562 ::comphelper::MediaDescriptor lDescriptor;
2563
2549 // damaged on last saving time ...
2550 // Then our listener need this notification.
2551 // If it was damaged during last "try to open" ...
2552 // it will be notified more then once. SH.. HAPPENS ...
2553 // <- SAFE --------------------------
2554 aWriteLock.unlock();
2555 implts_informListener(eJob,
2556 AutoRecovery::implst_createFeatureStateEvent(eJob, OPERATION_UPDATE, &rInfo));
2557 aWriteLock.lock();
2558 // SAFE -> --------------------------
2559 continue;
2560 }
2561
2562 ::comphelper::MediaDescriptor lDescriptor;
2563
2564 // its an UI feature - so the "USER" itself must be set as referer
2564 // it's an UI feature - so the "USER" itself must be set as referrer
2565 lDescriptor[::comphelper::MediaDescriptor::PROP_REFERRER()] <<= REFERRER_USER;
2566 lDescriptor[::comphelper::MediaDescriptor::PROP_SALVAGEDFILE()] <<= ::rtl::OUString();
2567
2568 // recovered documents are loaded hidden, and shown all at once, later
2569 lDescriptor[::comphelper::MediaDescriptor::PROP_HIDDEN()] <<= true;
2570
2571 if (aParams.m_xProgress.is())
2572 lDescriptor[::comphelper::MediaDescriptor::PROP_STATUSINDICATOR()] <<= aParams.m_xProgress;

--- 4 unchanged lines hidden (view full) ---

2577 );
2578 sal_Bool bOriginalWasTried = ((rInfo.DocumentState & AutoRecovery::E_TRY_LOAD_ORIGINAL) == AutoRecovery::E_TRY_LOAD_ORIGINAL);
2579
2580 if (bBackupWasTried)
2581 {
2582 if (!bOriginalWasTried)
2583 {
2584 rInfo.DocumentState |= AutoRecovery::E_INCOMPLETE;
2565 lDescriptor[::comphelper::MediaDescriptor::PROP_REFERRER()] <<= REFERRER_USER;
2566 lDescriptor[::comphelper::MediaDescriptor::PROP_SALVAGEDFILE()] <<= ::rtl::OUString();
2567
2568 // recovered documents are loaded hidden, and shown all at once, later
2569 lDescriptor[::comphelper::MediaDescriptor::PROP_HIDDEN()] <<= true;
2570
2571 if (aParams.m_xProgress.is())
2572 lDescriptor[::comphelper::MediaDescriptor::PROP_STATUSINDICATOR()] <<= aParams.m_xProgress;

--- 4 unchanged lines hidden (view full) ---

2577 );
2578 sal_Bool bOriginalWasTried = ((rInfo.DocumentState & AutoRecovery::E_TRY_LOAD_ORIGINAL) == AutoRecovery::E_TRY_LOAD_ORIGINAL);
2579
2580 if (bBackupWasTried)
2581 {
2582 if (!bOriginalWasTried)
2583 {
2584 rInfo.DocumentState |= AutoRecovery::E_INCOMPLETE;
2585 // try original URL ... ! dont continue with next item here ...
2585 // try original URL ... ! don't continue with next item here ...
2586 }
2587 else
2588 {
2589 rInfo.DocumentState |= AutoRecovery::E_DAMAGED;
2590 continue;
2591 }
2592 }
2593

--- 108 unchanged lines hidden (view full) ---

2702 But directly after one document as recovered ... we must start listening.
2703 Otherwise the first "modify" doesn't reach us. Because we ourselves called setModified()
2704 on the document via API. And currently we don't listen for any events (not at the GlobalEventBroadcaster
2705 nor at any document!).
2706 */
2707 implts_startModifyListeningOnDoc(rInfo);
2708
2709 // SAFE -> ------------------------------
2586 }
2587 else
2588 {
2589 rInfo.DocumentState |= AutoRecovery::E_DAMAGED;
2590 continue;
2591 }
2592 }
2593

--- 108 unchanged lines hidden (view full) ---

2702 But directly after one document as recovered ... we must start listening.
2703 Otherwise the first "modify" doesn't reach us. Because we ourselves called setModified()
2704 on the document via API. And currently we don't listen for any events (not at the GlobalEventBroadcaster
2705 nor at any document!).
2706 */
2707 implts_startModifyListeningOnDoc(rInfo);
2708
2709 // SAFE -> ------------------------------
2710 // Needed for next loop. Dont unlock it again!
2710 // Needed for next loop. Don't unlock it again!
2711 aWriteLock.lock();
2712 }
2713
2714 aWriteLock.unlock();
2715 // <- SAFE ----------------------------------
2716
2717 return eTimer;
2718}

--- 130 unchanged lines hidden (view full) ---

2849 // <- SAFE ----------------------------------
2850
2851 // specify URL for saving (which points to a temp file inside backup directory)
2852 // and define an unique name, so we can locate it later.
2853 // This unique name must solve an optimization problem too!
2854 // In case we are asked to save unmodified documents too - and one of them
2855 // is an empty one (because it was new created using e.g. an URL private:factory/...)
2856 // we should not save it really. Then we put the information about such "empty document"
2711 aWriteLock.lock();
2712 }
2713
2714 aWriteLock.unlock();
2715 // <- SAFE ----------------------------------
2716
2717 return eTimer;
2718}

--- 130 unchanged lines hidden (view full) ---

2849 // <- SAFE ----------------------------------
2850
2851 // specify URL for saving (which points to a temp file inside backup directory)
2852 // and define an unique name, so we can locate it later.
2853 // This unique name must solve an optimization problem too!
2854 // In case we are asked to save unmodified documents too - and one of them
2855 // is an empty one (because it was new created using e.g. an URL private:factory/...)
2856 // we should not save it really. Then we put the information about such "empty document"
2857 // into the configuration and dont create any recovery file on disk.
2857 // into the configuration and don't create any recovery file on disk.
2858 // We use the title of the document to make it unique.
2859 ::rtl::OUStringBuffer sUniqueName;
2860 if (rInfo.OrgURL.getLength())
2861 {
2862 css::uno::Reference< css::util::XURLTransformer > xParser(xSMGR->createInstance(SERVICENAME_URLTRANSFORMER), css::uno::UNO_QUERY);
2863 css::util::URL aURL;
2864 aURL.Complete = rInfo.OrgURL;
2865 xParser->parseStrict(aURL);
2866 sUniqueName.append(aURL.Name);
2867 }
2868 else
2869 if (rInfo.FactoryURL.getLength())
2870 sUniqueName.appendAscii("untitled");
2871 sUniqueName.appendAscii("_");
2872
2858 // We use the title of the document to make it unique.
2859 ::rtl::OUStringBuffer sUniqueName;
2860 if (rInfo.OrgURL.getLength())
2861 {
2862 css::uno::Reference< css::util::XURLTransformer > xParser(xSMGR->createInstance(SERVICENAME_URLTRANSFORMER), css::uno::UNO_QUERY);
2863 css::util::URL aURL;
2864 aURL.Complete = rInfo.OrgURL;
2865 xParser->parseStrict(aURL);
2866 sUniqueName.append(aURL.Name);
2867 }
2868 else
2869 if (rInfo.FactoryURL.getLength())
2870 sUniqueName.appendAscii("untitled");
2871 sUniqueName.appendAscii("_");
2872
2873 // TODO: Must we strip some illegal signes - if we use the title?
2873 // TODO: Must we strip some illegal signs - if we use the title?
2874
2875 String sName (sUniqueName.makeStringAndClear());
2876 String sExtension(rInfo.Extension );
2877 String sPath (sBackupPath );
2878 ::utl::TempFile aTempFile(sName, &sExtension, &sPath);
2879
2880 rInfo.NewTempURL = aTempFile.GetURL();
2881}

--- 27 unchanged lines hidden (view full) ---

2909//-----------------------------------------------
2910::rtl::OUString AutoRecovery::implst_getJobDescription(sal_Int32 eJob)
2911{
2912 // describe the current running operation
2913 ::rtl::OUStringBuffer sFeature(256);
2914 sFeature.append(CMD_PROTOCOL);
2915
2916 // Attention: Because "eJob" is used as a flag field the order of checking these
2874
2875 String sName (sUniqueName.makeStringAndClear());
2876 String sExtension(rInfo.Extension );
2877 String sPath (sBackupPath );
2878 ::utl::TempFile aTempFile(sName, &sExtension, &sPath);
2879
2880 rInfo.NewTempURL = aTempFile.GetURL();
2881}

--- 27 unchanged lines hidden (view full) ---

2909//-----------------------------------------------
2910::rtl::OUString AutoRecovery::implst_getJobDescription(sal_Int32 eJob)
2911{
2912 // describe the current running operation
2913 ::rtl::OUStringBuffer sFeature(256);
2914 sFeature.append(CMD_PROTOCOL);
2915
2916 // Attention: Because "eJob" is used as a flag field the order of checking these
2917 // flags is importent. We must preferr job with higher priorities!
2917 // flags is important. We must prefer job with higher priorities!
2918 // E.g. EmergencySave has an higher prio then AutoSave ...
2919 // On the other side there exist a well defined order between two different jobs.
2920 // e.g. PrepareEmergencySave must be done before EmergencySave is started of course.
2921
2922 if ((eJob & AutoRecovery::E_PREPARE_EMERGENCY_SAVE) == AutoRecovery::E_PREPARE_EMERGENCY_SAVE)
2923 sFeature.append(CMD_DO_PREPARE_EMERGENCY_SAVE);
2924 else
2925 if ((eJob & AutoRecovery::E_EMERGENCY_SAVE) == AutoRecovery::E_EMERGENCY_SAVE)

--- 132 unchanged lines hidden (view full) ---

3058
3059 // hide all docs, so the user can't disturb our emergency save .-)
3060 implts_changeAllDocVisibility(sal_False);
3061}
3062
3063//-----------------------------------------------
3064void AutoRecovery::implts_doEmergencySave(const DispatchParams& aParams)
3065{
2918 // E.g. EmergencySave has an higher prio then AutoSave ...
2919 // On the other side there exist a well defined order between two different jobs.
2920 // e.g. PrepareEmergencySave must be done before EmergencySave is started of course.
2921
2922 if ((eJob & AutoRecovery::E_PREPARE_EMERGENCY_SAVE) == AutoRecovery::E_PREPARE_EMERGENCY_SAVE)
2923 sFeature.append(CMD_DO_PREPARE_EMERGENCY_SAVE);
2924 else
2925 if ((eJob & AutoRecovery::E_EMERGENCY_SAVE) == AutoRecovery::E_EMERGENCY_SAVE)

--- 132 unchanged lines hidden (view full) ---

3058
3059 // hide all docs, so the user can't disturb our emergency save .-)
3060 implts_changeAllDocVisibility(sal_False);
3061}
3062
3063//-----------------------------------------------
3064void AutoRecovery::implts_doEmergencySave(const DispatchParams& aParams)
3065{
3066 // Write a hint "we chrashed" into the configuration, so
3066 // Write a hint "we crashed" into the configuration, so
3067 // the error report tool is started too in case no recovery
3068 // documents exists and was saved.
3069 ::comphelper::ConfigurationHelper::writeDirectKey(
3070 m_xSMGR,
3071 CFG_PACKAGE_RECOVERY,
3072 CFG_PATH_RECOVERYINFO,
3073 CFG_ENTRY_CRASHED,
3074 css::uno::makeAny(sal_True),

--- 64 unchanged lines hidden (view full) ---

3139//-----------------------------------------------
3140void AutoRecovery::implts_doSessionSave(const DispatchParams& aParams)
3141{
3142 LOG_RECOVERY("AutoRecovery::implts_doSessionSave()")
3143
3144 // Be sure to know all open documents really .-)
3145 implts_verifyCacheAgainstDesktopDocumentList();
3146
3067 // the error report tool is started too in case no recovery
3068 // documents exists and was saved.
3069 ::comphelper::ConfigurationHelper::writeDirectKey(
3070 m_xSMGR,
3071 CFG_PACKAGE_RECOVERY,
3072 CFG_PATH_RECOVERYINFO,
3073 CFG_ENTRY_CRASHED,
3074 css::uno::makeAny(sal_True),

--- 64 unchanged lines hidden (view full) ---

3139//-----------------------------------------------
3140void AutoRecovery::implts_doSessionSave(const DispatchParams& aParams)
3141{
3142 LOG_RECOVERY("AutoRecovery::implts_doSessionSave()")
3143
3144 // Be sure to know all open documents really .-)
3145 implts_verifyCacheAgainstDesktopDocumentList();
3146
3147 // for all docs, store their current view/names in the configurtion
3147 // for all docs, store their current view/names in the configuration
3148 implts_persistAllActiveViewNames();
3149
3150 // The called method for saving documents runs
3151 // during normal AutoSave more then once. Because
3152 // it postpone active documents and save it later.
3153 // That is normally done by recalling it from a timer.
3154 // Here we must do it immediately!
3155 // Of course this method returns the right state -

--- 27 unchanged lines hidden (view full) ---

3183 // try to make sure next time office will be started user won't be
3184 // notified about any other might be running office instance
3185 // remove ".lock" file from disc !
3186 // it is done as a first action for session save since Gnome sessions
3187 // do not provide enough time for shutdown, and the dialog looks to be
3188 // confusing for the user
3189 AutoRecovery::st_impl_removeLockFile();
3190
3148 implts_persistAllActiveViewNames();
3149
3150 // The called method for saving documents runs
3151 // during normal AutoSave more then once. Because
3152 // it postpone active documents and save it later.
3153 // That is normally done by recalling it from a timer.
3154 // Here we must do it immediately!
3155 // Of course this method returns the right state -

--- 27 unchanged lines hidden (view full) ---

3183 // try to make sure next time office will be started user won't be
3184 // notified about any other might be running office instance
3185 // remove ".lock" file from disc !
3186 // it is done as a first action for session save since Gnome sessions
3187 // do not provide enough time for shutdown, and the dialog looks to be
3188 // confusing for the user
3189 AutoRecovery::st_impl_removeLockFile();
3190
3191 // reset all modified documents, so the dont show any UI on closing ...
3191 // reset all modified documents, so the don't show any UI on closing ...
3192 // and close all documents, so we can shutdown the OS!
3193 implts_prepareSessionShutdown();
3194
3195 // Write a hint for "stored session data" into the configuration, so
3196 // the on next startup we know what's happen last time
3197 ::comphelper::ConfigurationHelper::writeDirectKey(
3198 m_xSMGR,
3199 CFG_PACKAGE_RECOVERY,

--- 70 unchanged lines hidden (view full) ---

3270 continue; // nothing real to save! An unmodified but new created document.
3271
3272 INetURLObject aParser(sSourceURL);
3273 // AutoRecovery::EFailureSafeResult eResult =
3274 implts_copyFile(sSourceURL, aParams.m_sSavePath, aParser.getName());
3275
3276 // TODO: Check eResult and react for errors (InteractionHandler!?)
3277 // Currently we ignore it ...
3192 // and close all documents, so we can shutdown the OS!
3193 implts_prepareSessionShutdown();
3194
3195 // Write a hint for "stored session data" into the configuration, so
3196 // the on next startup we know what's happen last time
3197 ::comphelper::ConfigurationHelper::writeDirectKey(
3198 m_xSMGR,
3199 CFG_PACKAGE_RECOVERY,

--- 70 unchanged lines hidden (view full) ---

3270 continue; // nothing real to save! An unmodified but new created document.
3271
3272 INetURLObject aParser(sSourceURL);
3273 // AutoRecovery::EFailureSafeResult eResult =
3274 implts_copyFile(sSourceURL, aParams.m_sSavePath, aParser.getName());
3275
3276 // TODO: Check eResult and react for errors (InteractionHandler!?)
3277 // Currently we ignore it ...
3278 // DONT UPDATE THE CACHE OR REMOVE ANY TEMP. FILES FROM DISK.
3278 // DON'T UPDATE THE CACHE OR REMOVE ANY TEMP. FILES FROM DISK.
3279 // That has to be forced from outside explicitly.
3280 // See implts_cleanUpWorkingEntry() for further details.
3281 }
3282}
3283
3284//-----------------------------------------------
3285void AutoRecovery::implts_cleanUpWorkingEntry(const DispatchParams& aParams)
3286{

--- 8 unchanged lines hidden (view full) ---

3295 if (rInfo.ID != aParams.m_nWorkingEntryID)
3296 continue;
3297
3298 AutoRecovery::st_impl_removeFile(rInfo.OldTempURL);
3299 AutoRecovery::st_impl_removeFile(rInfo.NewTempURL);
3300 implts_flushConfigItem(rInfo, sal_True); // sal_True => remove it from xml config!
3301
3302 m_lDocCache.erase(pIt);
3279 // That has to be forced from outside explicitly.
3280 // See implts_cleanUpWorkingEntry() for further details.
3281 }
3282}
3283
3284//-----------------------------------------------
3285void AutoRecovery::implts_cleanUpWorkingEntry(const DispatchParams& aParams)
3286{

--- 8 unchanged lines hidden (view full) ---

3295 if (rInfo.ID != aParams.m_nWorkingEntryID)
3296 continue;
3297
3298 AutoRecovery::st_impl_removeFile(rInfo.OldTempURL);
3299 AutoRecovery::st_impl_removeFile(rInfo.NewTempURL);
3300 implts_flushConfigItem(rInfo, sal_True); // sal_True => remove it from xml config!
3301
3302 m_lDocCache.erase(pIt);
3303 break; /// !!! pIt is not defined any longer ... further this function has finished it's work
3303 break; /// !!! pIt is not defined any longer ... further this function has finished its work
3304 }
3305}
3306
3307//-----------------------------------------------
3308AutoRecovery::EFailureSafeResult AutoRecovery::implts_copyFile(const ::rtl::OUString& sSource ,
3309 const ::rtl::OUString& sTargetPath,
3310 const ::rtl::OUString& sTargetName)
3311{

--- 176 unchanged lines hidden (view full) ---

3488 continue;
3489 }
3490 // can happen in multithreaded environments, that frames was removed from the container during this loop runs!
3491 // Ignore it.
3492 catch(const css::lang::IndexOutOfBoundsException&)
3493 { continue; }
3494
3495 // We are interested on visible documents only.
3304 }
3305}
3306
3307//-----------------------------------------------
3308AutoRecovery::EFailureSafeResult AutoRecovery::implts_copyFile(const ::rtl::OUString& sSource ,
3309 const ::rtl::OUString& sTargetPath,
3310 const ::rtl::OUString& sTargetName)
3311{

--- 176 unchanged lines hidden (view full) ---

3488 continue;
3489 }
3490 // can happen in multithreaded environments, that frames was removed from the container during this loop runs!
3491 // Ignore it.
3492 catch(const css::lang::IndexOutOfBoundsException&)
3493 { continue; }
3494
3495 // We are interested on visible documents only.
3496 // Note: It's n optional interface .-(
3496 // Note: It's an optional interface .-(
3497 css::uno::Reference< css::awt::XWindow2 > xVisibleCheck(
3498 xFrame->getContainerWindow(),
3499 css::uno::UNO_QUERY);
3500 if (
3501 (!xVisibleCheck.is() ) ||
3502 (!xVisibleCheck->isVisible())
3503 )
3504 {

--- 8 unchanged lines hidden (view full) ---

3513 xController = xFrame->getController();
3514 if (xController.is())
3515 xModel = xController->getModel();
3516 if (!xModel.is())
3517 continue;
3518
3519 // insert model into cache ...
3520 // If the model is already well known inside cache
3497 css::uno::Reference< css::awt::XWindow2 > xVisibleCheck(
3498 xFrame->getContainerWindow(),
3499 css::uno::UNO_QUERY);
3500 if (
3501 (!xVisibleCheck.is() ) ||
3502 (!xVisibleCheck->isVisible())
3503 )
3504 {

--- 8 unchanged lines hidden (view full) ---

3513 xController = xFrame->getController();
3514 if (xController.is())
3515 xModel = xController->getModel();
3516 if (!xModel.is())
3517 continue;
3518
3519 // insert model into cache ...
3520 // If the model is already well known inside cache
3521 // it's information set will be updated by asking the
3522 // model again for it's new states.
3521 // its information set will be updated by asking the
3522 // model again for its new states.
3523 implts_registerDocument(xModel);
3524 }
3525 }
3526 catch(const css::uno::RuntimeException& exRun)
3527 { throw exRun; }
3528 catch(const css::uno::Exception&)
3529 {}
3530

--- 74 unchanged lines hidden (view full) ---

3605 // Any outside progress must be used ...
3606 // Only if there is no progress, we can create our own one.
3607 css::uno::Reference< css::task::XStatusIndicator > xInternalProgress;
3608 css::uno::Reference< css::task::XStatusIndicator > xExternalProgress = rArgs.getUnpackedValueOrDefault(
3609 ::comphelper::MediaDescriptor::PROP_STATUSINDICATOR(),
3610 css::uno::Reference< css::task::XStatusIndicator >() );
3611
3612 // Normally a progress is set from outside (e.g. by the CrashSave/Recovery dialog, which uses our dispatch API).
3523 implts_registerDocument(xModel);
3524 }
3525 }
3526 catch(const css::uno::RuntimeException& exRun)
3527 { throw exRun; }
3528 catch(const css::uno::Exception&)
3529 {}
3530

--- 74 unchanged lines hidden (view full) ---

3605 // Any outside progress must be used ...
3606 // Only if there is no progress, we can create our own one.
3607 css::uno::Reference< css::task::XStatusIndicator > xInternalProgress;
3608 css::uno::Reference< css::task::XStatusIndicator > xExternalProgress = rArgs.getUnpackedValueOrDefault(
3609 ::comphelper::MediaDescriptor::PROP_STATUSINDICATOR(),
3610 css::uno::Reference< css::task::XStatusIndicator >() );
3611
3612 // Normally a progress is set from outside (e.g. by the CrashSave/Recovery dialog, which uses our dispatch API).
3613 // But for a normal auto save we dont have such "external progress"... because this function is triggered by our own timer then.
3613 // But for a normal auto save we don't have such "external progress"... because this function is triggered by our own timer then.
3614 // In such case we must create our own progress !
3615 if (
3616 (! xExternalProgress.is()) &&
3617 (xFrame.is() )
3618 )
3619 {
3620 css::uno::Reference< css::task::XStatusIndicatorFactory > xProgressFactory(xFrame, css::uno::UNO_QUERY);
3621 if (xProgressFactory.is())
3622 xInternalProgress = xProgressFactory->createStatusIndicator();
3623 }
3624
3625 // HACK
3626 // An external provided progress (most given by the CrashSave/Recovery dialog)
3614 // In such case we must create our own progress !
3615 if (
3616 (! xExternalProgress.is()) &&
3617 (xFrame.is() )
3618 )
3619 {
3620 css::uno::Reference< css::task::XStatusIndicatorFactory > xProgressFactory(xFrame, css::uno::UNO_QUERY);
3621 if (xProgressFactory.is())
3622 xInternalProgress = xProgressFactory->createStatusIndicator();
3623 }
3624
3625 // HACK
3626 // An external provided progress (most given by the CrashSave/Recovery dialog)
3627 // must be preferred. But we know that some application filters query it's own progress instance
3627 // must be preferred. But we know that some application filters query its own progress instance
3628 // at the frame method Frame::createStatusIndicator().
3629 // So we use a two step mechanism:
3630 // 1) we set the progress inside the MediaDescriptor, which will be provided to the filter
3628 // at the frame method Frame::createStatusIndicator().
3629 // So we use a two step mechanism:
3630 // 1) we set the progress inside the MediaDescriptor, which will be provided to the filter
3631 // 2) and we set a special Frame property, which overwrites the normal behaviour of Frame::createStatusIndicator .-)
3631 // 2) and we set a special Frame property, which overwrites the normal behavior of Frame::createStatusIndicator .-)
3632 // But we suppress 2) in case we uses an internal progress. Because then it doesn't matter
3633 // if our applications make it wrong. In such case the internal progress resists at the same frame
3634 // and there is no need to forward progress activities to e.g. an outside dialog .-)
3635 if (
3636 (xExternalProgress.is()) &&
3637 (xFrame.is() )
3638 )
3639 {
3640 css::uno::Reference< css::beans::XPropertySet > xFrameProps(xFrame, css::uno::UNO_QUERY);
3641 if (xFrameProps.is())
3642 xFrameProps->setPropertyValue(FRAME_PROPNAME_INDICATORINTERCEPTION, css::uno::makeAny(xExternalProgress));
3643 }
3644
3645 // But inside the MediaDescriptor we must set our own create progress ...
3632 // But we suppress 2) in case we uses an internal progress. Because then it doesn't matter
3633 // if our applications make it wrong. In such case the internal progress resists at the same frame
3634 // and there is no need to forward progress activities to e.g. an outside dialog .-)
3635 if (
3636 (xExternalProgress.is()) &&
3637 (xFrame.is() )
3638 )
3639 {
3640 css::uno::Reference< css::beans::XPropertySet > xFrameProps(xFrame, css::uno::UNO_QUERY);
3641 if (xFrameProps.is())
3642 xFrameProps->setPropertyValue(FRAME_PROPNAME_INDICATORINTERCEPTION, css::uno::makeAny(xExternalProgress));
3643 }
3644
3645 // But inside the MediaDescriptor we must set our own create progress ...
3646 // in case there is not already anothe rprogress set.
3646 // in case there is not already another progress set.
3647 rArgs.createItemIfMissing(::comphelper::MediaDescriptor::PROP_STATUSINDICATOR(), xInternalProgress);
3648}
3649
3650//-----------------------------------------------
3651void AutoRecovery::impl_forgetProgress(const AutoRecovery::TDocumentInfo& rInfo ,
3652 ::comphelper::MediaDescriptor& rArgs ,
3653 const css::uno::Reference< css::frame::XFrame >& xNewFrame)
3654{

--- 89 unchanged lines hidden ---
3647 rArgs.createItemIfMissing(::comphelper::MediaDescriptor::PROP_STATUSINDICATOR(), xInternalProgress);
3648}
3649
3650//-----------------------------------------------
3651void AutoRecovery::impl_forgetProgress(const AutoRecovery::TDocumentInfo& rInfo ,
3652 ::comphelper::MediaDescriptor& rArgs ,
3653 const css::uno::Reference< css::frame::XFrame >& xNewFrame)
3654{

--- 89 unchanged lines hidden ---