summaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
authorCaolán McNamara <caolanm@redhat.com>2019-08-05 17:26:53 +0100
committerCaolán McNamara <caolanm@redhat.com>2019-08-22 16:37:16 +0200
commit69057064d8957804c76e623d57c103c3413b7cbc (patch)
tree8026201f2750300a3b9f831a04dcc34016d54a95 /include
parente724f245e9652230d4c1f58c353be150006affcd (diff)
weld ODbTypeWizDialogSetup
split up RoadmapWizard to sit its wizard logic on top of a a native GtkAssistant a) awkwardly GtkAssistant is not a GtkDialog, but derives directly from GtkWindow so some shuffling around required due to that b) hidden/unused pages are shuffled to the end of the list of pages and their titles turned off in order to hide them from the roadmap c) some nonstandard hackery required to get the gtk roadmap titles to wrap Change-Id: I0d2346c489fef744136a2785f33c846d97bd8dc6 Reviewed-on: https://gerrit.libreoffice.org/76876 Tested-by: Jenkins Reviewed-by: Caolán McNamara <caolanm@redhat.com> Tested-by: Caolán McNamara <caolanm@redhat.com>
Diffstat (limited to 'include')
-rw-r--r--include/svtools/helpids.h3
-rw-r--r--include/tools/wintypes.hxx5
-rw-r--r--include/vcl/roadmapwizard.hxx146
-rw-r--r--include/vcl/vclenum.hxx15
-rw-r--r--include/vcl/weld.hxx42
-rw-r--r--include/vcl/wizardmachine.hxx251
6 files changed, 434 insertions, 28 deletions
diff --git a/include/svtools/helpids.h b/include/svtools/helpids.h
index 0c296ba613c2..ce1b29cf6cd6 100644
--- a/include/svtools/helpids.h
+++ b/include/svtools/helpids.h
@@ -45,9 +45,6 @@
#define HID_FILEOPEN_IMAGE_TEMPLATE "SVT_HID_FILEOPEN_IMAGE_TEMPLATE"
#define HID_FILEOPEN_IMAGE_ANCHOR "SVT_HID_FILEOPEN_IMAGE_ANCHOR"
-#define HID_WIZARD_NEXT "SVT_HID_WIZARD_NEXT"
-#define HID_WIZARD_PREVIOUS "SVT_HID_WIZARD_PREVIOUS"
-
#endif
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/tools/wintypes.hxx b/include/tools/wintypes.hxx
index 4fa4eab908f9..5bcaec41aa17 100644
--- a/include/tools/wintypes.hxx
+++ b/include/tools/wintypes.hxx
@@ -257,7 +257,10 @@ enum class StandardButtonType
Ignore = 8,
Abort = 9,
Less = 10,
- Count = 11,
+ Back = 11,
+ Next = 12,
+ Finish = 13,
+ Count = 14,
};
// prominent place for ListBox window types
diff --git a/include/vcl/roadmapwizard.hxx b/include/vcl/roadmapwizard.hxx
index 6764d40f8c6e..df0632af5085 100644
--- a/include/vcl/roadmapwizard.hxx
+++ b/include/vcl/roadmapwizard.hxx
@@ -75,6 +75,12 @@ namespace vcl
void SetRoadmapInteractive( bool _bInteractive );
+ void InsertRoadmapItem(int nIndex, const OUString& rLabel, int nId, bool bEnabled);
+ void DeleteRoadmapItems();
+ int GetCurrentRoadmapItemID() const;
+ void SelectRoadmapItemByID(int nId);
+ void SetItemSelectHdl( const Link<LinkParamNone*,void>& _rHdl );
+
// returns whether a given state is enabled
bool isStateEnabled( WizardState _nState ) const;
@@ -213,6 +219,146 @@ namespace vcl
VCL_DLLPRIVATE void impl_construct();
};
+ class VCL_DLLPUBLIC RoadmapWizardMachine : public vcl::WizardMachine, public RoadmapWizardTypes
+ {
+ private:
+ std::unique_ptr<RoadmapWizardImpl> m_pImpl;
+
+ public:
+ RoadmapWizardMachine(weld::Window* _pParent);
+ virtual ~RoadmapWizardMachine( ) override;
+
+ void SetRoadmapHelpId( const OString& _rId );
+
+ void SetRoadmapInteractive( bool _bInteractive );
+
+ // returns whether a given state is enabled
+ bool isStateEnabled( WizardState _nState ) const;
+
+ // WizardDialog overridables
+ virtual bool canAdvance() const override;
+ virtual void updateTravelUI() override;
+
+ protected:
+ /** declares a valid path in the wizard
+
+ The very first path which is declared is automatically activated.
+
+ Note that all paths which are declared must have the very first state in
+ common. Also note that due to a restriction of the very base class (WizardDialog),
+ this common first state must be 0.
+
+ You cannot declare new paths once the wizard started, so it's recommended that
+ you do all declarations within your derivee's constructor.
+
+ @see activatePath
+
+ @param _nId
+ the unique id you wish to give this path. This id can later on be used
+ to refer to the path which you just declared
+ */
+ void declarePath( PathId _nPathId, const WizardPath& _lWizardStates);
+
+ /** provides basic information about a state
+
+ The given display name is used in the default implementation of getStateDisplayName,
+ and the given factory is used in the default implementation of createPage.
+ */
+ void describeState( WizardState _nState, const OUString& _rStateDisplayName, RoadmapPageFactory _pPageFactory );
+
+ /** activates a path which has previously been declared with <member>declarePath</member>
+
+ You can only activate paths which share the first <code>k</code> states with the path
+ which is previously active (if any), where <code>k</code> is the index of the
+ current state within the current path.
+
+ <example>
+ Say you have paths, <code>(0,1,2,5)</code> and <code>(0,1,4,5)</code>. This means that after
+ step <code>1</code>, you either continue with state <code>2</code> or state <code>4</code>,
+ and after this, you finish in state <code>5</code>.<br/>
+ Now if the first path is active, and your current state is <code>1</code>, then you can
+ easily switch to the second path, since both paths start with <code>(0,1)</code>.<br/>
+ However, if your current state is <code>2</code>, then you can not switch to the second
+ path anymore.
+ </example>
+
+ @param _nPathId
+ the id of the path. The path must have been declared (under this id) with
+ <member>declarePath</member> before it can be activated.
+
+ @param _bDecideForIt
+ If <TRUE/>, the path will be completely activated, even if it is a conflicting path
+ (i.e. there is another path which shares the first <code>k</code> states with
+ the to-be-activated path.)<br/>
+ If <FALSE/>, then the new path is checked for conflicts with other paths. If such
+ conflicts exists, the path is not completely activated, but only up to the point
+ where it does <em>not</em> conflict.<br/>
+ With the paths in the example above, if you activate the second path (when both are
+ already declared), then only steps <code>0</code> and <code>1</code> are activated,
+ since they are common to both paths.
+ */
+ void activatePath( PathId _nPathId, bool _bDecideForIt = false );
+
+ /** determine the next state to travel from the given one
+
+ This method (which is declared in OWizardMachine and overwritten here)
+ ensures that traveling happens along the active path.
+
+ @see activatePath
+ */
+ virtual WizardState determineNextState( WizardState _nCurrentState ) const override;
+
+ /** en- or disables a state
+
+ In the wizard's roadmap, states to travel to can be freely chosen. To prevent
+ users from selecting a state which is currently not available, you can declare this
+ state as being disabled.
+
+ A situation where you need this may be when you have a checkbox which, when checked
+ by the user, enables a page with additional settings. As long as this checkbox is
+ not checked, the respective state would be disabled.
+
+ Note that in theory, you can declare multiple paths, instead of disabling states.
+ For instance, if you have a path where one state can be potentially disabled, then
+ you could declare a second path, which does not contain this state. However, the
+ disadvantage is that then, not the complete path would be visible in the roadmap,
+ but only all steps up to the point where the both paths diverge.<br/>
+ Another disadvantage is that the number of needed paths grows exponentially with
+ the number of states which can be potentially disabled.
+
+ @see declarePath
+ */
+ void enableState( WizardState _nState, bool _bEnable = true );
+
+ /** returns true if and only if the given state is known in at least one declared path
+ */
+ bool knowsState( WizardState _nState ) const;
+
+ // OWizardMachine overriables
+ virtual void enterState( WizardState _nState ) override;
+
+ /** returns a human readable name for a given state
+
+ There is a default implementation for this method, which returns the display name
+ as given in a call to describeState. If there is no description for the given state,
+ this is worth an assertion in a non-product build, and then an empty string is
+ returned.
+ */
+ virtual OUString getStateDisplayName( WizardState _nState ) const;
+
+ /** asks for a new label of the wizard page
+
+ */
+ void updateRoadmapItemLabel( WizardState _nState );
+
+ private:
+ DECL_DLLPRIVATE_LINK( OnRoadmapItemSelected, const OString&, bool );
+
+ /** updates the roadmap control to show the given path, as far as possible
+ (modulo conflicts with other paths)
+ */
+ VCL_DLLPRIVATE void implUpdateRoadmap( );
+ };
} // namespace vcl
diff --git a/include/vcl/vclenum.hxx b/include/vcl/vclenum.hxx
index 1e8f59428e3f..c7ced830da49 100644
--- a/include/vcl/vclenum.hxx
+++ b/include/vcl/vclenum.hxx
@@ -273,6 +273,21 @@ enum class VclPolicyType
NEVER
};
+enum class WizardButtonFlags : sal_Int16
+{
+ NONE = 0x0000,
+ NEXT = 0x0001,
+ PREVIOUS = 0x0002,
+ FINISH = 0x0004,
+ CANCEL = 0x0008,
+ HELP = 0x0010,
+};
+
+namespace o3tl
+{
+ template<> struct typed_flags<WizardButtonFlags> : is_typed_flags<WizardButtonFlags, 0x001f> {};
+}
+
#endif // INCLUDED_VCL_VCLENUM_HXX
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/vcl/weld.hxx b/include/vcl/weld.hxx
index 198b7a72f0d6..d4b688243c68 100644
--- a/include/vcl/weld.hxx
+++ b/include/vcl/weld.hxx
@@ -250,6 +250,8 @@ class VCL_DLLPUBLIC Container : virtual public Widget
public:
//remove and add in one go
virtual void move(weld::Widget* pWidget, weld::Container* pNewParent) = 0;
+ //recursively unset has-default on any buttons in the widget hierarchy
+ virtual void recursively_unset_default_buttons() = 0;
};
class VCL_DLLPUBLIC ScrolledWindow : virtual public Container
@@ -423,7 +425,7 @@ public:
virtual void add_button(const OUString& rText, int response, const OString& rHelpId = OString())
= 0;
virtual void set_default_response(int response) = 0;
- virtual Button* get_widget_for_response(int response) = 0;
+ virtual Button* weld_widget_for_response(int response) = 0;
virtual Container* weld_content_area() = 0;
// shrink the dialog down to shown just these widgets
@@ -457,6 +459,30 @@ public:
virtual void set_background(const css::uno::Reference<css::graphic::XGraphic>& rImage) = 0;
};
+class VCL_DLLPUBLIC Assistant : virtual public Dialog
+{
+protected:
+ Link<const OString&, bool> m_aJumpPageHdl;
+
+ bool signal_jump_page(const OString& rIdent) { return m_aJumpPageHdl.Call(rIdent); }
+
+public:
+ virtual int get_current_page() const = 0;
+ virtual int get_n_pages() const = 0;
+ virtual OString get_page_ident(int nPage) const = 0;
+ virtual OString get_current_page_ident() const = 0;
+ virtual void set_current_page(int nPage) = 0;
+ virtual void set_current_page(const OString& rIdent) = 0;
+ // move the page rIdent to position nIndex
+ virtual void set_page_index(const OString& rIdent, int nIndex) = 0;
+ virtual void set_page_title(const OString& rIdent, const OUString& rTitle) = 0;
+ virtual OUString get_page_title(const OString& rIdent) const = 0;
+ virtual void set_page_sensitive(const OString& rIdent, bool bSensitive) = 0;
+ virtual weld::Container* append_page(const OString& rIdent) = 0;
+
+ void connect_jump_page(const Link<const OString&, bool>& rLink) { m_aJumpPageHdl = rLink; }
+};
+
struct VCL_DLLPUBLIC ComboBoxEntry
{
OUString sString;
@@ -1785,6 +1811,8 @@ public:
virtual std::unique_ptr<AboutDialog> weld_about_dialog(const OString& id,
bool bTakeOwnership = true)
= 0;
+ virtual std::unique_ptr<Assistant> weld_assistant(const OString& id, bool bTakeOwnership = true)
+ = 0;
virtual std::unique_ptr<Window> weld_window(const OString& id, bool bTakeOwnership = true) = 0;
virtual std::unique_ptr<Widget> weld_widget(const OString& id, bool bTakeOwnership = false) = 0;
virtual std::unique_ptr<Container> weld_container(const OString& id,
@@ -1907,6 +1935,18 @@ public:
OUString get_primary_text() const { return m_xDialog->get_primary_text(); }
void set_default_response(int nResponse) { m_xDialog->set_default_response(nResponse); }
};
+
+class VCL_DLLPUBLIC AssistantController : public DialogController
+{
+protected:
+ std::unique_ptr<weld::Builder> m_xBuilder;
+ std::unique_ptr<weld::Assistant> m_xAssistant;
+
+public:
+ AssistantController(weld::Widget* pParent, const OUString& rUIFile, const OString& rDialogId);
+ virtual Dialog* getDialog() override;
+ virtual ~AssistantController() override;
+};
}
#endif
diff --git a/include/vcl/wizardmachine.hxx b/include/vcl/wizardmachine.hxx
index 0b0afbce1576..c840af3f0745 100644
--- a/include/vcl/wizardmachine.hxx
+++ b/include/vcl/wizardmachine.hxx
@@ -31,20 +31,6 @@ namespace weld {
class Container;
}
-enum class WizardButtonFlags
-{
- NONE = 0x0000,
- NEXT = 0x0001,
- PREVIOUS = 0x0002,
- FINISH = 0x0004,
- CANCEL = 0x0008,
- HELP = 0x0010,
-};
-namespace o3tl
-{
- template<> struct typed_flags<WizardButtonFlags> : is_typed_flags<WizardButtonFlags, 0x001f> {};
-}
-
namespace vcl
{
@@ -152,9 +138,6 @@ namespace vcl
class VCL_DLLPUBLIC OWizardMachine : public WizardDialog, public WizardTypes
{
private:
- // restrict access to some aspects of our base class
- using WizardDialog::AddPage;
- using WizardDialog::SetPage;
// TabPage* GetPage( sal_uInt16 nLevel ) const { return WizardDialog::GetPage(nLevel); }
// TODO: probably the complete page handling (next, previous etc.) should be prohibited ...
@@ -163,7 +146,7 @@ namespace vcl
// here (e.g. committing page data) depend on having full control over page traveling.
// So use the travelXXX methods if you need to travel
- protected:
+ public:
VclPtr<OKButton> m_pFinish;
VclPtr<CancelButton> m_pCancel;
VclPtr<PushButton> m_pNextPage;
@@ -358,23 +341,245 @@ namespace vcl
VCL_DLLPRIVATE void implConstruct( const WizardButtonFlags _nButtonFlags );
};
+ class VCL_DLLPUBLIC WizardMachine : public weld::AssistantController, public WizardTypes
+ {
+ private:
+ VclPtr<TabPage> m_xCurTabPage;
+
+ WizardState m_nCurState;
+ ImplWizPageData* m_pFirstPage;
+
+ protected:
+ std::unique_ptr<weld::Button> m_xFinish;
+ std::unique_ptr<weld::Button> m_xCancel;
+ std::unique_ptr<weld::Button> m_xNextPage;
+ std::unique_ptr<weld::Button> m_xPrevPage;
+ std::unique_ptr<weld::Button> m_xHelp;
+
+ private:
+ // hold members in this structure to allow keeping compatible when members are added
+ std::unique_ptr<WizardMachineImplData> m_pImpl;
+
+ public:
+ WizardMachine(weld::Window* _pParent, WizardButtonFlags _nButtonFlags );
+ virtual ~WizardMachine() override;
+
+ bool Finish(short nResult = RET_CANCEL);
+ bool ShowPage(WizardState nState);
+
+ void AddPage( TabPage* pPage );
+ void SetPage( WizardState nLevel, TabPage* pPage );
+ TabPage* GetPage( WizardState eState ) const;
+
+ /// enable (or disable) buttons
+ void enableButtons(WizardButtonFlags _nWizardButtonFlags, bool _bEnable);
+ /// set the default style for a button
+ void defaultButton(WizardButtonFlags _nWizardButtonFlags);
+ /// set the default style for a button
+ void defaultButton(weld::Button* _pNewDefButton);
+
+ /// set the base of the title to use - the title of the current page is appended
+ void setTitleBase(const OUString& _rTitleBase);
+
+ /// determines whether there is a next state to which we can advance
+ virtual bool canAdvance() const;
+
+ /** updates the user interface which deals with traveling in the wizard
+
+ The default implementation simply checks whether both the current page and the wizard
+ itself allow to advance to the next state (<code>canAdvance</code>), and enables the "Next"
+ button if and only if this is the case.
+ */
+ virtual void updateTravelUI();
+
+ protected:
+ // WizardDialog overridables
+ virtual void ActivatePage();
+ virtual bool DeactivatePage();
+
+ // our own overridables
+
+ /// to override to create new pages
+ virtual VclPtr<TabPage> createPage(WizardState _nState) = 0;
+
+ /// will be called when a new page is about to be displayed
+ virtual void enterState(WizardState _nState);
+
+ /** will be called when the current state is about to be left for the given reason
+
+ The base implementation in this class will simply call <member>OWizardPage::commitPage</member>
+ for the current page, and return whatever this call returns.
+
+ @param _eReason
+ The reason why the state is to be left.
+ @return
+ <TRUE/> if and only if the page is allowed to be left
+ */
+ virtual bool prepareLeaveCurrentState( CommitPageReason _eReason );
+
+ /** will be called when the given state is left
+
+ This is the very last possibility for derived classes to veto the deactivation
+ of a page.
+
+ @todo Normally, we would not need the return value here - derived classes now have
+ the possibility to veto page deactivations in <member>prepareLeaveCurrentState</member>. However,
+ changing this return type is too incompatible at the moment ...
+
+ @return
+ <TRUE/> if and only if the page is allowed to be left
+ */
+ virtual bool leaveState( WizardState _nState );
+
+ /** determine the next state to travel from the given one
+
+ The default behaviour is linear traveling, overwrite this to change it
+
+ Return WZS_INVALID_STATE to prevent traveling.
+ */
+ virtual WizardState determineNextState( WizardState _nCurrentState ) const;
+
+ /** called when the finish button is pressed
+ <p>By default, only the base class' Finish method (which is not virtual) is called</p>
+ */
+ virtual bool onFinish();
+
+ /// travel to the next state
+ bool travelNext();
+
+ /// travel to the previous state
+ bool travelPrevious();
+
+ /** enables the automatic enabled/disabled state of the "Next" button
+
+ If this is <TRUE/>, then upon entering a new state, the "Next" button will automatically be
+ enabled if and only if determineNextState does not return WZS_INVALID_STATE.
+ */
+ void enableAutomaticNextButtonState();
+ bool isAutomaticNextButtonStateEnabled() const;
+
+ /** removes a page from the history. Should be called when the page is being disabled
+ */
+ void removePageFromHistory( WizardState nToRemove );
+
+ /** skip a state
+
+ The method behaves as if from the current state, <arg>_nSteps</arg> <method>travelNext</method>s were
+ called, but without actually creating or displaying the \EDntermediate pages. Only the
+ (<arg>_nSteps</arg> + 1)th page is created.
+
+ The skipped states appear in the state history, so <method>travelPrevious</method> will make use of them.
+
+ A very essential precondition for using this method is that your <method>determineNextState</method>
+ method is able to determine the next state without actually having the page of the current state.
+
+ @see skipUntil
+ @see skipBackwardUntil
+ */
+ void skip();
+
+ /** skips one or more states, until a given state is reached
+
+ The method behaves as if from the current state, <method>travelNext</method>s were called
+ successively, until <arg>_nTargetState</arg> is reached, but without actually creating or
+ displaying the \EDntermediate pages.
+
+ The skipped states appear in the state history, so <method>travelPrevious</method> will make use of them.
+
+ @return
+ <TRUE/> if and only if traveling was successful
+
+ @see skip
+ @see skipBackwardUntil
+ */
+ bool skipUntil( WizardState _nTargetState );
+
+ /** moves back one or more states, until a given state is reached
+
+ This method allows traveling backwards more than one state without actually showing the intermediate
+ states.
+
+ For instance, if you want to travel two steps backward at a time, you could used
+ two travelPrevious calls, but this would <em>show</em> both pages, which is not necessary,
+ since you're interested in the target page only. Using <member>skipBackwardUntil</member> relieves
+ you of this.
+
+ @return
+ <TRUE/> if and only if traveling was successful
+
+ @see skipUntil
+ @see skip
+ */
+ bool skipBackwardUntil( WizardState _nTargetState );
+
+ /** returns the current state of the machine
+
+ Vulgo, this is the identifier of the current tab page :)
+ */
+ WizardState getCurrentState() const { return m_nCurState; }
+
+ virtual IWizardPageController*
+ getPageController( TabPage* _pCurrentPage ) const;
+
+ /** retrieves a copy of the state history, i.e. all states we already visited
+ */
+ void getStateHistory( ::std::vector< WizardState >& _out_rHistory );
+
+ public:
+ class AccessGuard
+ {
+ friend class WizardTravelSuspension;
+ private:
+ AccessGuard() { }
+ };
+
+ void suspendTraveling( AccessGuard );
+ void resumeTraveling( AccessGuard );
+ bool isTravelingSuspended() const;
+
+ protected:
+ TabPage* GetOrCreatePage( const WizardState i_nState );
+
+ private:
+ DECL_DLLPRIVATE_LINK(OnNextPage, weld::Button&, void);
+ DECL_DLLPRIVATE_LINK(OnPrevPage, weld::Button&, void);
+ DECL_DLLPRIVATE_LINK(OnFinish, weld::Button&, void);
+ DECL_DLLPRIVATE_LINK(OnCancel, weld::Button&, void);
+
+ VCL_DLLPRIVATE void implUpdateTitle();
+ VCL_DLLPRIVATE void implConstruct( const WizardButtonFlags _nButtonFlags );
+ };
+
+
/// helper class to temporarily suspend any traveling in the wizard
class WizardTravelSuspension
{
public:
- WizardTravelSuspension( OWizardMachine& _rWizard )
- :m_rWizard( _rWizard )
+ WizardTravelSuspension(OWizardMachine& rWizard)
+ : m_pOWizard(&rWizard)
+ , m_pWizard(nullptr)
+ {
+ m_pOWizard->suspendTraveling(OWizardMachine::AccessGuard());
+ }
+
+ WizardTravelSuspension(WizardMachine& rWizard)
+ : m_pOWizard(nullptr)
+ , m_pWizard(&rWizard)
{
- m_rWizard.suspendTraveling( OWizardMachine::AccessGuard() );
+ m_pWizard->suspendTraveling(WizardMachine::AccessGuard());
}
~WizardTravelSuspension()
{
- m_rWizard.resumeTraveling( OWizardMachine::AccessGuard() );
+ if (m_pOWizard)
+ m_pOWizard->resumeTraveling(OWizardMachine::AccessGuard());
+ if (m_pWizard)
+ m_pWizard->resumeTraveling(WizardMachine::AccessGuard());
}
private:
- OWizardMachine& m_rWizard;
+ VclPtr<OWizardMachine> m_pOWizard;
+ WizardMachine* m_pWizard;
};