Kaydet (Commit) 5187d3ae authored tarafından heiko tietze's avatar heiko tietze Kaydeden (comit) Heiko Tietze

Resolves: tdf#69042 - Add a "What's New" infobar

Shows an infobar with a link to the respective wiki page
Adds a button to the About dialog
Replaces If6eb1542d2ad310226f76850f480f2f99070b803

Change-Id: I1eeb504994a6364feb90cfa447029875e0ec1969
Reviewed-on: https://gerrit.libreoffice.org/72218
Tested-by: Jenkins
Reviewed-by: 's avatarHeiko Tietze <tietze.heiko@gmail.com>
Tested-by: 's avatarHeiko Tietze <tietze.heiko@gmail.com>
üst 9e35b5a7
...@@ -76,6 +76,7 @@ AboutDialog::AboutDialog(vcl::Window* pParent) ...@@ -76,6 +76,7 @@ AboutDialog::AboutDialog(vcl::Window* pParent)
m_aCopyrightTextStr = m_pCopyrightText->GetText(); m_aCopyrightTextStr = m_pCopyrightText->GetText();
get(m_pWebsiteButton, "website"); get(m_pWebsiteButton, "website");
get(m_pCreditsButton, "credits"); get(m_pCreditsButton, "credits");
get(m_pReleaseNotesButton, "btnReleaseNotes");
m_aCreditsLinkStr = get<FixedText>("link")->GetText(); m_aCreditsLinkStr = get<FixedText>("link")->GetText();
m_sBuildStr = get<FixedText>("buildid")->GetText(); m_sBuildStr = get<FixedText>("buildid")->GetText();
m_aVendorTextStr = get<FixedText>("vendor")->GetText(); m_aVendorTextStr = get<FixedText>("vendor")->GetText();
...@@ -100,6 +101,7 @@ AboutDialog::AboutDialog(vcl::Window* pParent) ...@@ -100,6 +101,7 @@ AboutDialog::AboutDialog(vcl::Window* pParent)
// Connect all handlers // Connect all handlers
m_pCreditsButton->SetClickHdl( LINK( this, AboutDialog, HandleClick ) ); m_pCreditsButton->SetClickHdl( LINK( this, AboutDialog, HandleClick ) );
m_pWebsiteButton->SetClickHdl( LINK( this, AboutDialog, HandleClick ) ); m_pWebsiteButton->SetClickHdl( LINK( this, AboutDialog, HandleClick ) );
m_pReleaseNotesButton->SetClickHdl( LINK( this, AboutDialog, HandleClick ) );
get<PushButton>("close")->GrabFocus(); get<PushButton>("close")->GrabFocus();
} }
...@@ -119,6 +121,7 @@ void AboutDialog::dispose() ...@@ -119,6 +121,7 @@ void AboutDialog::dispose()
m_pCreditsButton.clear(); m_pCreditsButton.clear();
m_pWebsiteButton.clear(); m_pWebsiteButton.clear();
m_pBuildIdLink.clear(); m_pBuildIdLink.clear();
m_pReleaseNotesButton.clear();
SfxModalDialog::dispose(); SfxModalDialog::dispose();
} }
...@@ -134,6 +137,12 @@ IMPL_LINK( AboutDialog, HandleClick, Button*, pButton, void ) ...@@ -134,6 +137,12 @@ IMPL_LINK( AboutDialog, HandleClick, Button*, pButton, void )
sURL = officecfg::Office::Common::Help::StartCenter::InfoURL::get(); sURL = officecfg::Office::Common::Help::StartCenter::InfoURL::get();
localizeWebserviceURI(sURL); localizeWebserviceURI(sURL);
} }
else if (pButton == m_pReleaseNotesButton)
{
sURL = officecfg::Office::Common::Menus::ReleaseNotesURL::get() +
"?LOvers=" + utl::ConfigManager::getProductVersion() +
"&LOlocale=" + LanguageTag(utl::ConfigManager::getUILocale()).getLanguage();
}
// If the URL is empty, don't do anything // If the URL is empty, don't do anything
if ( sURL.isEmpty() ) if ( sURL.isEmpty() )
......
...@@ -43,6 +43,7 @@ private: ...@@ -43,6 +43,7 @@ private:
VclPtr<FixedText> m_pLogoReplacement; VclPtr<FixedText> m_pLogoReplacement;
VclPtr<PushButton> m_pCreditsButton; VclPtr<PushButton> m_pCreditsButton;
VclPtr<PushButton> m_pWebsiteButton; VclPtr<PushButton> m_pWebsiteButton;
VclPtr<PushButton> m_pReleaseNotesButton;
OUString m_aVersionTextStr; OUString m_aVersionTextStr;
OUString m_aVendorTextStr; OUString m_aVendorTextStr;
......
...@@ -20,6 +20,21 @@ ...@@ -20,6 +20,21 @@
<object class="GtkButtonBox" id="dialog-action_area1"> <object class="GtkButtonBox" id="dialog-action_area1">
<property name="can_focus">False</property> <property name="can_focus">False</property>
<property name="layout_style">end</property> <property name="layout_style">end</property>
<child>
<object class="GtkButton" id="btnReleaseNotes">
<property name="label" translatable="yes" context="aboutdialog|releasenotes">_Release Notes</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="use_underline">True</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
<property name="secondary">True</property>
</packing>
</child>
<child> <child>
<object class="GtkButton" id="credits"> <object class="GtkButton" id="credits">
<property name="label" translatable="yes" context="aboutdialog|credits">Cre_dits</property> <property name="label" translatable="yes" context="aboutdialog|credits">Cre_dits</property>
...@@ -31,7 +46,7 @@ ...@@ -31,7 +46,7 @@
<packing> <packing>
<property name="expand">False</property> <property name="expand">False</property>
<property name="fill">True</property> <property name="fill">True</property>
<property name="position">0</property> <property name="position">1</property>
<property name="secondary">True</property> <property name="secondary">True</property>
</packing> </packing>
</child> </child>
...@@ -46,7 +61,7 @@ ...@@ -46,7 +61,7 @@
<packing> <packing>
<property name="expand">False</property> <property name="expand">False</property>
<property name="fill">True</property> <property name="fill">True</property>
<property name="position">1</property> <property name="position">2</property>
<property name="secondary">True</property> <property name="secondary">True</property>
</packing> </packing>
</child> </child>
...@@ -63,7 +78,7 @@ ...@@ -63,7 +78,7 @@
<packing> <packing>
<property name="expand">False</property> <property name="expand">False</property>
<property name="fill">True</property> <property name="fill">True</property>
<property name="position">2</property> <property name="position">3</property>
</packing> </packing>
</child> </child>
</object> </object>
...@@ -311,6 +326,7 @@ ...@@ -311,6 +326,7 @@
</object> </object>
</child> </child>
<action-widgets> <action-widgets>
<action-widget response="0">btnReleaseNotes</action-widget>
<action-widget response="0">credits</action-widget> <action-widget response="0">credits</action-widget>
<action-widget response="0">website</action-widget> <action-widget response="0">website</action-widget>
<action-widget response="-7">close</action-widget> <action-widget response="-7">close</action-widget>
......
...@@ -94,6 +94,8 @@ class SvxSearchItem; ...@@ -94,6 +94,8 @@ class SvxSearchItem;
#define SID_DOCUMENTATION (SID_SFX_START + 423) #define SID_DOCUMENTATION (SID_SFX_START + 423)
#define SID_DONATION (SID_SFX_START + 424) #define SID_DONATION (SID_SFX_START + 424)
#define SID_GETINVOLVED (SID_SFX_START + 425) #define SID_GETINVOLVED (SID_SFX_START + 425)
#define SID_WHATSNEW (SID_SFX_START + 426)
#define SID_SHOW_LICENSE (SID_SFX_START + 1683) #define SID_SHOW_LICENSE (SID_SFX_START + 1683)
#define SID_SHOW_CREDITS (SID_SFX_START + 1711) #define SID_SHOW_CREDITS (SID_SFX_START + 1711)
......
...@@ -246,8 +246,10 @@ ...@@ -246,8 +246,10 @@
#define STR_NONCHECKEDOUT_DOCUMENT NC_("STR_NONCHECKEDOUT_DOCUMENT", "This document is not checked out on the server.") #define STR_NONCHECKEDOUT_DOCUMENT NC_("STR_NONCHECKEDOUT_DOCUMENT", "This document is not checked out on the server.")
#define STR_GET_INVOLVED_TEXT NC_("STR_GET_INVOLVED_TEXT", "Help us make %PRODUCTNAME even better!") #define STR_GET_INVOLVED_TEXT NC_("STR_GET_INVOLVED_TEXT", "Help us make %PRODUCTNAME even better!")
#define STR_GET_INVOLVED_BUTTON NC_("STR_GET_INVOLVED_BUTTON", "Get involved") #define STR_GET_INVOLVED_BUTTON NC_("STR_GET_INVOLVED_BUTTON", "Get involved")
#define STR_GET_DONATE_TEXT NC_("STR_GET_DONATE_TEXT", "Your donations support our worldwide community.") #define STR_DONATE_TEXT NC_("STR_DONATE_TEXT", "Your donations support our worldwide community.")
#define STR_GET_DONATE_BUTTON NC_("STR_GET_DONATE_BUTTON", "Donate") #define STR_DONATE_BUTTON NC_("STR_DONATE_BUTTON", "Donate")
#define STR_WHATSNEW_TEXT NC_("STR_WHATSNEW", "You are running version %PRODUCTVERSION of %PRODUCTNAME for the first time. Do you want to learn what's new?")
#define STR_WHATSNEW_BUTTON NC_("STR_WHATSNEW_BUTTON", "Release Notes")
#define STR_READONLY_DOCUMENT NC_("STR_READONLY_DOCUMENT", "This document is open in read-only mode.") #define STR_READONLY_DOCUMENT NC_("STR_READONLY_DOCUMENT", "This document is open in read-only mode.")
#define STR_READONLY_PDF NC_("STR_READONLY_PDF", "This PDF is open in read-only mode to allow signing the existing file.") #define STR_READONLY_PDF NC_("STR_READONLY_PDF", "This PDF is open in read-only mode to allow signing the existing file.")
#define STR_CLASSIFIED_DOCUMENT NC_("STR_CLASSIFIED_DOCUMENT", "The classification label of this document is %1.") #define STR_CLASSIFIED_DOCUMENT NC_("STR_CLASSIFIED_DOCUMENT", "The classification label of this document is %1.")
......
...@@ -57,7 +57,8 @@ protected: ...@@ -57,7 +57,8 @@ protected:
virtual void Notify( SfxBroadcaster& rBC, const SfxHint& rHint ) override; virtual void Notify( SfxBroadcaster& rBC, const SfxHint& rHint ) override;
DECL_LINK(GetInvolvedHandler, Button*, void); DECL_LINK(GetInvolvedHandler, Button*, void);
DECL_LINK(GetDonateHandler, Button*, void); DECL_LINK(DonationHandler, Button*, void);
DECL_LINK(WhatsNewHandler, Button*, void);
DECL_LINK(SwitchReadOnlyHandler, Button*, void); DECL_LINK(SwitchReadOnlyHandler, Button*, void);
DECL_LINK(SignDocumentHandler, Button*, void); DECL_LINK(SignDocumentHandler, Button*, void);
SAL_DLLPRIVATE void KillDispatcher_Impl(); SAL_DLLPRIVATE void KillDispatcher_Impl();
......
...@@ -53,6 +53,8 @@ public: ...@@ -53,6 +53,8 @@ public:
static OUString getProductVersion(); static OUString getProductVersion();
static OUString getLastProductVersion();
static OUString getVendor(); static OUString getVendor();
static void storeConfigItems(); static void storeConfigItems();
......
...@@ -394,6 +394,9 @@ ...@@ -394,6 +394,9 @@
<prop oor:name="DonationURL" oor:type="xs:string"> <prop oor:name="DonationURL" oor:type="xs:string">
<value>https://hub.libreoffice.org/donation/</value> <value>https://hub.libreoffice.org/donation/</value>
</prop> </prop>
<prop oor:name="ReleaseNotesURL" oor:type="xs:string">
<value>https://hub.libreoffice.org/ReleaseNotes/</value>
</prop>
</node> </node>
<node oor:name="Forms"> <node oor:name="Forms">
<node oor:name="ControlLayout"> <node oor:name="ControlLayout">
......
...@@ -2075,6 +2075,11 @@ ...@@ -2075,6 +2075,11 @@
<desc>Specifies the URL used with the UNO command Donation (SID_DONATION).</desc> <desc>Specifies the URL used with the UNO command Donation (SID_DONATION).</desc>
</info> </info>
</prop> </prop>
<prop oor:name="ReleaseNotesURL" oor:type="xs:string" oor:nillable="false">
<info>
<desc>Specifies the URL used with the UNO command WhatsNew (SID_WHATSNEW).</desc>
</info>
</prop>
</group> </group>
<group oor:name="History"> <group oor:name="History">
<!-- OldLocation: soffice.ini --> <!-- OldLocation: soffice.ini -->
......
...@@ -260,6 +260,13 @@ ...@@ -260,6 +260,13 @@
<!-- JB: Empty default inserted into empty property node. Remove if NIL <!-- JB: Empty default inserted into empty property node. Remove if NIL
was intended --> was intended -->
</prop> </prop>
<prop oor:name="ooSetupLastVersion" oor:type="xs:string" oor:nillable="true">
<info>
<desc>Specifies the version number of the previously used product for
whats-new comparison.</desc>
</info>
<value/>
</prop>
<prop oor:name="ooSetupVersionAboutBox" oor:type="xs:string" oor:nillable="false"> <prop oor:name="ooSetupVersionAboutBox" oor:type="xs:string" oor:nillable="false">
<info> <info>
<desc>Specifies the complete (major.minor.micro) version number of the <desc>Specifies the complete (major.minor.micro) version number of the
......
...@@ -136,6 +136,10 @@ interface Application ...@@ -136,6 +136,10 @@ interface Application
[ [
ExecMethod = MiscExec_Impl ; ExecMethod = MiscExec_Impl ;
] ]
SID_WHATSNEW
[
ExecMethod = MiscExec_Impl ;
]
SID_SHOW_LICENSE SID_SHOW_LICENSE
[ [
ExecMethod = MiscExec_Impl ; ExecMethod = MiscExec_Impl ;
......
...@@ -4945,7 +4945,21 @@ SfxVoidItem GetInvolved SID_GETINVOLVED ...@@ -4945,7 +4945,21 @@ SfxVoidItem GetInvolved SID_GETINVOLVED
MenuConfig = TRUE, MenuConfig = TRUE,
GroupId = SfxGroupId::Application; GroupId = SfxGroupId::Application;
] ]
SfxVoidItem WhatsNew SID_WHATSNEW
()
[
AutoUpdate = FALSE,
FastCall = FALSE,
ReadOnlyDoc = TRUE,
Toggle = FALSE,
Container = FALSE,
RecordAbsolute = FALSE,
RecordPerSet;
AccelConfig = TRUE,
MenuConfig = TRUE,
GroupId = SfxGroupId::Application;
]
SfxVoidItem ShowLicense SID_SHOW_LICENSE SfxVoidItem ShowLicense SID_SHOW_LICENSE
() ()
[ [
......
...@@ -585,6 +585,15 @@ void SfxApplication::MiscExec_Impl( SfxRequest& rReq ) ...@@ -585,6 +585,15 @@ void SfxApplication::MiscExec_Impl( SfxRequest& rReq )
sfx2::openUriExternally(sURL, false); sfx2::openUriExternally(sURL, false);
break; break;
} }
case SID_WHATSNEW:
{
// Open release notes depending on version and locale
OUString sURL(officecfg::Office::Common::Menus::ReleaseNotesURL::get() + //https://hub.libreoffice.org/ReleaseNotes/
"?LOvers=" + utl::ConfigManager::getProductVersion() +
"&LOlocale=" + LanguageTag(utl::ConfigManager::getUILocale()).getLanguage() );
sfx2::openUriExternally(sURL, false);
break;
}
case SID_SHOW_LICENSE: case SID_SHOW_LICENSE:
{ {
LicenseDialog aDialog(rReq.GetFrameWeld()); LicenseDialog aDialog(rReq.GetFrameWeld());
......
...@@ -1221,14 +1221,39 @@ void SfxViewFrame::Notify( SfxBroadcaster& /*rBC*/, const SfxHint& rHint ) ...@@ -1221,14 +1221,39 @@ void SfxViewFrame::Notify( SfxBroadcaster& /*rBC*/, const SfxHint& rHint )
const auto t0 = std::chrono::system_clock::now().time_since_epoch(); const auto t0 = std::chrono::system_clock::now().time_since_epoch();
// show tip-of-the-day dialog
const bool bShowTipOfTheDay = officecfg::Office::Common::Misc::ShowTipOfTheDay::get();
bool bIsUITest = false; //uitest.uicheck fails when the dialog is open bool bIsUITest = false; //uitest.uicheck fails when the dialog is open
for( sal_uInt16 i = 0; i < Application::GetCommandLineParamCount(); i++ ) for( sal_uInt16 i = 0; i < Application::GetCommandLineParamCount(); i++ )
{ {
if( Application::GetCommandLineParam(i) == "--nologo" ) if( Application::GetCommandLineParam(i) == "--nologo" )
bIsUITest = true; bIsUITest = true;
} }
//what's new infobar
if (!officecfg::Setup::Product::ooSetupLastVersion::isReadOnly()) //don't show/update when readonly
{
OUString sSetupVersion = utl::ConfigManager::getProductVersion();
sal_Int32 iCurrent = sSetupVersion.getToken(0,'.').toInt32() * 10 + sSetupVersion.getToken(1,'.').toInt32();
OUString sLastVersion = utl::ConfigManager::getLastProductVersion();
if (sLastVersion.isEmpty()) sLastVersion="0.0";
sal_Int32 iLast = sLastVersion.getToken(0,'.').toInt32() * 10 + sLastVersion.getToken(1,'.').toInt32();
if ((iCurrent > iLast) && !Application::IsHeadlessModeEnabled() && !bIsUITest)
{
VclPtr<SfxInfoBarWindow> pInfoBar = AppendInfoBar("whatsnew", SfxResId(STR_WHATSNEW_TEXT), InfoBarType::Info);
VclPtrInstance<PushButton> xWhatsNewButton(&GetWindow());
xWhatsNewButton->SetText(SfxResId(STR_WHATSNEW_BUTTON));
xWhatsNewButton->SetSizePixel(xWhatsNewButton->GetOptimalSize());
xWhatsNewButton->SetClickHdl(LINK(this, SfxViewFrame, WhatsNewHandler));
pInfoBar->addButton(xWhatsNewButton);
//update lastversion
std::shared_ptr<comphelper::ConfigurationChanges> batch(comphelper::ConfigurationChanges::create());
officecfg::Setup::Product::ooSetupLastVersion::set(sSetupVersion, batch);
batch->commit();
}
}
// show tip-of-the-day dialog
const bool bShowTipOfTheDay = officecfg::Office::Common::Misc::ShowTipOfTheDay::get();
if (bShowTipOfTheDay && !Application::IsHeadlessModeEnabled() && !bIsUITest) { if (bShowTipOfTheDay && !Application::IsHeadlessModeEnabled() && !bIsUITest) {
const sal_Int32 nLastTipOfTheDay = officecfg::Office::Common::Misc::LastTipOfTheDayShown::get(); const sal_Int32 nLastTipOfTheDay = officecfg::Office::Common::Misc::LastTipOfTheDayShown::get();
const sal_Int32 nDay = std::chrono::duration_cast<std::chrono::hours>(t0).count()/24; // days since 1970-01-01 const sal_Int32 nDay = std::chrono::duration_cast<std::chrono::hours>(t0).count()/24; // days since 1970-01-01
...@@ -1279,13 +1304,13 @@ void SfxViewFrame::Notify( SfxBroadcaster& /*rBC*/, const SfxHint& rHint ) ...@@ -1279,13 +1304,13 @@ void SfxViewFrame::Notify( SfxBroadcaster& /*rBC*/, const SfxHint& rHint )
{ {
bUpdateLastTimeDonateShown = true; bUpdateLastTimeDonateShown = true;
VclPtr<SfxInfoBarWindow> pInfoBar = AppendInfoBar("getdonate", SfxResId(STR_GET_DONATE_TEXT), InfoBarType::Info); VclPtr<SfxInfoBarWindow> pInfoBar = AppendInfoBar("donate", SfxResId(STR_DONATE_TEXT), InfoBarType::Info);
VclPtrInstance<PushButton> xGetDonateButton(&GetWindow()); VclPtrInstance<PushButton> xDonateButton(&GetWindow());
xGetDonateButton->SetText(SfxResId(STR_GET_DONATE_BUTTON)); xDonateButton->SetText(SfxResId(STR_DONATE_BUTTON));
xGetDonateButton->SetSizePixel(xGetDonateButton->GetOptimalSize()); xDonateButton->SetSizePixel(xDonateButton->GetOptimalSize());
xGetDonateButton->SetClickHdl(LINK(this, SfxViewFrame, GetDonateHandler)); xDonateButton->SetClickHdl(LINK(this, SfxViewFrame, DonationHandler));
pInfoBar->addButton(xGetDonateButton); pInfoBar->addButton(xDonateButton);
} }
if (bUpdateLastTimeDonateShown if (bUpdateLastTimeDonateShown
...@@ -1419,12 +1444,17 @@ void SfxViewFrame::Notify( SfxBroadcaster& /*rBC*/, const SfxHint& rHint ) ...@@ -1419,12 +1444,17 @@ void SfxViewFrame::Notify( SfxBroadcaster& /*rBC*/, const SfxHint& rHint )
} }
} }
IMPL_LINK_NOARG(SfxViewFrame, WhatsNewHandler, Button*, void)
{
GetDispatcher()->Execute(SID_WHATSNEW);
}
IMPL_LINK_NOARG(SfxViewFrame, GetInvolvedHandler, Button*, void) IMPL_LINK_NOARG(SfxViewFrame, GetInvolvedHandler, Button*, void)
{ {
GetDispatcher()->Execute(SID_GETINVOLVED); GetDispatcher()->Execute(SID_GETINVOLVED);
} }
IMPL_LINK_NOARG(SfxViewFrame, GetDonateHandler, Button*, void) IMPL_LINK_NOARG(SfxViewFrame, DonationHandler, Button*, void)
{ {
GetDispatcher()->Execute(SID_DONATION); GetDispatcher()->Execute(SID_DONATION);
} }
......
...@@ -22,6 +22,9 @@ ...@@ -22,6 +22,9 @@
<prop oor:name="ShowTipOfTheDay"> <prop oor:name="ShowTipOfTheDay">
<value>false</value> <value>false</value>
</prop> </prop>
<prop oor:name="LastTipOfTheDayShown">
<value>"32767"</value> <!-- some arbitray high value (sal_Int32) -->
</prop>
</node> </node>
<node oor:name="Filter"> <node oor:name="Filter">
<node oor:name="Graphic"> <node oor:name="Graphic">
......
...@@ -135,6 +135,12 @@ OUString utl::ConfigManager::getProductVersion() { ...@@ -135,6 +135,12 @@ OUString utl::ConfigManager::getProductVersion() {
"Product/ooSetupVersion"); "Product/ooSetupVersion");
} }
OUString utl::ConfigManager::getLastProductVersion() {
return getConfigurationString(
"/org.openoffice.Setup",
"Product/ooSetupLastVersion");
}
OUString utl::ConfigManager::getVendor() { OUString utl::ConfigManager::getVendor() {
return getConfigurationString( return getConfigurationString(
"/org.openoffice.Setup", "/org.openoffice.Setup",
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment