/** * @RDE_HEADER@ * Bottom Button Box for Dialogs which need actions * $Id$ * $HeadURL$ * $Author$ * * Created by Mike Wille, SLSE, 2016-08-17 */ #pragma once #include "lts_widgets_export.h" #include "lts_message_dialog.h" #include #include namespace Ui { class LtsDialogButtonBox; } namespace LtsWidgets { enum class DialogButton { // Do not connect these: ReadOnly, Ok, Apply, Close, Yes, No, // You can connect these: Remove, Hide, Add, Help, Edit, Save, Load, Show, Import, Export, CenterMap, ZoomMapTo, Library, Print, #ifdef LTS_DEBUG _debug_, #endif }; // TODO: doc: close is now autoconnected by NEW LtsDialogs not running in compatibility mode ! /** * @brief The LtsDialogButtonBox class is a replacement for the NGLDialogButtonBox. With the significant difference that * Actions ('Ok', 'Close', etc.) are select in code, not in the designer. * * Pro: * > no dead/unconnected buttons * > no designer plugin needed * > no killed dialog boxes after editing uis * > auto connecting the close button to the Dialogs accept / Widgets close (important for close requests on dialogs before closing) * > solid connections only (safer & faster than connections by char*) [also con] * * Con: * > no possibility to see which Actions are available for a specific dialog * > solid connections only (more complicated) [also pro] * * To make Actions visible & usable, use 'connectButton' with the coherant Action (DialogButton). * 'connectButton' works similar to Qt's Connect mechanism, with the main difference that there is neither a sender nor a signal to specify. * * Example: connectButton(DialogButton::Ok, this, &ThisDialog::accept); * * * >>You have overloaded slots?<< * For example you have: slotSomethingChanged(int) and slotSomethingChanged(QString) * For the 'int'-version the result should look like: connect(DialogButton::Ok, this, static_cast(&ThisDialog::slotSOmethingChanged)); * Unfortunately this is the Qt version to solve this problem.. * */ class LTSWIDGETS_EXPORT LtsDialogButtonBox : public QWidget { Q_OBJECT public: explicit LtsDialogButtonBox(QWidget *parent); ~LtsDialogButtonBox(); /** * @brief connectButton connects a Button (like 'Apply', 'Ok', etc.) to the given receiver + slot. * This method prevents the existence of dead buttons (not connected) and that a missing Designer plugin messes up the button properties. * So, to make a button visible, use this method. * * Important: only solid connections possible (yet) * Example: connectButton(DialogButton::Ok, this, &ThisDialog::accept); * * @param button the DialogButton to make visible and connect it to the given 'slot' * @param receiver the receiver of the signal when a DialogButton is clicked - like the receiver in Qt's connect method * @param slot the slot on the 'receiver' called when the clicked signal is called by a DialogButton - like the slot in the Qt's connect method * @param type Qt::ConnectionType (does not need bo be set) */ template void connectButton(DialogButton button, const typename QtPrivate::FunctionPointer::Object *receiver, Func2 slot, Qt::ConnectionType type = Qt::AutoConnection) { //if (!LtsDialog::plan_editor_compatibility) { switch (button) { #ifdef LTS_DEBUG case DialogButton::_debug_: #endif case DialogButton::Close: case DialogButton::Ok: case DialogButton::ReadOnly: case DialogButton::Apply: case DialogButton::Help: { LtsMessageDialog::showMessage(this, QStringLiteral("Bitte den fuer das Plugin verantwortlichen kontaktieren:
" "m_buttonBox nicht mit Ok, Apply, Help, _debug_ oder Close verbinden
" "Note: Bitte nur m_buttonBox verwenden, keine LtsDialogButtonBox selber erstellen" "Ok & Apply werden automatisch zur virtual Methode 'apply()' im LtsDialog weitergeleitet.
" "Close schließt einfach den Dialog - im Destruktor oder in 'aboutToClose()' ist der 'Close Code' gut aufgehoben.
" "
" "FIXEN !!!!!"), QStringLiteral("--- STOP --- !!! FIXEN !!! ---")); break; } default: break; } } QPushButton *theSender = getButton(button); if (!theSender) return; // special cases for Buttons with embedded Dialogs switch (button) { case DialogButton::Remove: { connect(this, &LtsDialogButtonBox::signalRemoveClicked, receiver, slot, type); connect(theSender, &QPushButton::clicked, this, &LtsDialogButtonBox::slotRemoveClicked); break; } case DialogButton::Export: case DialogButton::Import: { if (m_isTablet) { theSender->setVisible(false); return; } Q_FALLTHROUGH(); } default: connect(theSender, &QPushButton::clicked, receiver, slot, type); break; } setButtonsVisible(theSender); // this method's magic } template bool connectLibraryButton(const typename QtPrivate::FunctionPointer::Object *receiver, Func1 slotLoad, Func2 slotSave, Qt::ConnectionType type = Qt::AutoConnection) { QPushButton *theSender = getButton(DialogButton::Library); if (!theSender) return false; if (m_isTablet) { theSender->setVisible(false); return true; } setButtonsVisible(theSender); type = static_cast(type | Qt::UniqueConnection); return (connect(this, &LtsDialogButtonBox::signalLibraryLoadClicked, receiver, slotLoad, type) && connect(this, &LtsDialogButtonBox::signalLibrarySaveClicked, receiver, slotSave, type)); } /** * @brief setText changes the text of a DialogButton to the 'text' specified. * @param button the DialogButton to rename * @param text new text of DialogButton */ void setText(DialogButton button, const QString &text); void setToolTip(DialogButton button, const QString &text); void setIcon(DialogButton button, const QIcon &icon); void setMenu(DialogButton button, QMenu *menu); /** * @brief setButtonEnabled enables / disables a DialogButton. * @param button the DialogButton to dis-/enable * @param enabled true = enabled; false = disabled */ void setButtonEnabled(DialogButton button, bool enabled = true); bool isButtonEnabled(DialogButton button) const; void setButtonVisible(DialogButton button, bool visible = true); bool isButtonVisible(DialogButton button) const; /** * Do not use! * @brief getButton DialogButton to real QPushButton* widget (do not use outside of this class!) * @param button * @return Pointer to QPushButton or nullptr when not found / available */ QPushButton *getButton(DialogButton button) const; /** * @brief _showAll Do not use. */ void _setVisibilityForAll(bool visible); signals: void signalRemoveClicked(); void signalHelpClicked(); void signalLibraryLoadClicked(); void signalLibrarySaveClicked(); private slots: void slotRemoveClicked(); private: const bool m_isTablet; /** * @brief setButtonVisible makes a QPushButton visible and also shows the horizontal line, etc. when it's first called (every button box is empty before one button was made visible) * @param pb */ void setButtonsVisible(QPushButton *pb); Ui::LtsDialogButtonBox *m_ui; }; } // namespace LtsWidgets