@ -36,6 +36,7 @@
# include <KXMLGUIFactory>
# include <QApplication>
# include <QDBusConnection>
# include <QDockWidget>
# include <QDragMoveEvent>
# include <QFileDialog>
# include <QMenuBar>
@ -62,6 +63,86 @@ static const char *shouldShowToolBarComingFromFullScreen = "shouldShowToolBarCom
static const char * const SESSION_URL_KEY = " Urls " ;
static const char * const SESSION_TAB_KEY = " ActiveTab " ;
static constexpr char SIDEBAR_LOCKED_KEY [ ] = " LockSidebar " ;
static constexpr char SIDEBAR_VISIBLE_KEY [ ] = " ShowSidebar " ;
/**
* Groups sidebar containers in a QDockWidget .
*
* This control groups all the sidebar containers provided by each tab ( the Part object ) ,
* allowing the user to dock it to the left and right sides of the window ,
* or detach it from the window altogether .
*/
class Sidebar : public QDockWidget
{
Q_OBJECT
public :
explicit Sidebar ( QWidget * parent = nullptr )
: QDockWidget ( parent )
{
setAllowedAreas ( Qt : : LeftDockWidgetArea | Qt : : RightDockWidgetArea ) ;
setFeatures ( defaultFeatures ( ) ) ;
m_stackedWidget = new QStackedWidget ;
setWidget ( m_stackedWidget ) ;
}
bool isLocked ( ) const
{
return features ( ) . testFlag ( NoDockWidgetFeatures ) ;
}
void setLocked ( bool locked )
{
setFeatures ( locked ? NoDockWidgetFeatures : defaultFeatures ( ) ) ;
// show titlebar only if not locked
if ( locked ) {
if ( ! m_dumbTitleWidget ) {
m_dumbTitleWidget = new QWidget ;
}
setTitleBarWidget ( m_dumbTitleWidget ) ;
} else {
setTitleBarWidget ( nullptr ) ;
}
}
int indexOf ( QWidget * widget ) const
{
return m_stackedWidget - > indexOf ( widget ) ;
}
void addWidget ( QWidget * widget )
{
m_stackedWidget - > addWidget ( widget ) ;
}
void removeWidget ( QWidget * widget )
{
m_stackedWidget - > removeWidget ( widget ) ;
}
void setCurrentWidget ( QWidget * widget )
{
m_stackedWidget - > setCurrentWidget ( widget ) ;
}
private :
static DockWidgetFeatures defaultFeatures ( )
{
DockWidgetFeatures dockFeatures = DockWidgetClosable | DockWidgetMovable ;
if ( ! KWindowSystem : : isPlatformWayland ( ) ) { // TODO : Remove this check when QTBUG-87332 is fixed
dockFeatures | = DockWidgetFloatable ;
}
return dockFeatures ;
}
QStackedWidget * m_stackedWidget = nullptr ;
QWidget * m_dumbTitleWidget = nullptr ;
} ;
Shell : : Shell ( const QString & serializedOptions )
: KParts : : MainWindow ( )
, m_menuBarWasShown ( true )
@ -126,12 +207,27 @@ Shell::Shell(const QString &serializedOptions)
connect ( m_tabWidget , & QTabWidget : : tabCloseRequested , this , & Shell : : closeTab ) ;
connect ( m_tabWidget - > tabBar ( ) , & QTabBar : : tabMoved , this , & Shell : : moveTabData ) ;
m_sidebar = new Sidebar ;
m_sidebar - > setObjectName ( QStringLiteral ( " okular_sidebar " ) ) ;
m_sidebar - > setContextMenuPolicy ( Qt : : ActionsContextMenu ) ;
m_sidebar - > setWindowTitle ( i18n ( " Sidebar " ) ) ;
connect ( m_sidebar , & QDockWidget : : visibilityChanged , this , [ this ] ( bool visible ) {
// sync sidebar visibility with the m_showSidebarAction only if welcome screen is hidden
if ( m_showSidebarAction & & m_centralStackedWidget - > currentWidget ( ) ! = m_welcomeScreen ) {
m_showSidebarAction - > setChecked ( visible ) ;
}
} ) ;
addDockWidget ( Qt : : LeftDockWidgetArea , m_sidebar ) ;
// then, setup our actions
setupActions ( ) ;
connect ( QCoreApplication : : instance ( ) , & QCoreApplication : : aboutToQuit , this , & QObject : : deleteLater ) ;
// and integrate the part's GUI with the shell's
setupGUI ( Keys | ToolBar | Save ) ;
// NOTE : apply default sidebar width only after calling setupGUI(...)
resizeDocks ( { m_sidebar } , { 200 } , Qt : : Horizontal ) ;
m_tabs . append ( TabState ( firstPart ) ) ;
m_tabWidget - > addTab ( firstPart - > widget ( ) , QString ( ) ) ; // triggers setActiveTab that calls createGUI( part )
@ -367,11 +463,25 @@ void Shell::readSettings()
m_menuBarWasShown = group . readEntry ( shouldShowMenuBarComingFromFullScreen , true ) ;
m_toolBarWasShown = group . readEntry ( shouldShowToolBarComingFromFullScreen , true ) ;
}
const KConfigGroup sidebarGroup = KSharedConfig : : openConfig ( ) - > group ( " General " ) ;
m_sidebar - > setVisible ( sidebarGroup . readEntry ( SIDEBAR_VISIBLE_KEY , true ) ) ;
m_sidebar - > setLocked ( sidebarGroup . readEntry ( SIDEBAR_LOCKED_KEY , true ) ) ;
m_showSidebarAction - > setChecked ( m_sidebar - > isVisibleTo ( this ) ) ;
m_lockSidebarAction - > setChecked ( m_sidebar - > isLocked ( ) ) ;
}
void Shell : : writeSettings ( )
{
saveRecents ( ) ;
KConfigGroup sidebarGroup = KSharedConfig : : openConfig ( ) - > group ( " General " ) ;
sidebarGroup . writeEntry ( SIDEBAR_LOCKED_KEY , m_sidebar - > isLocked ( ) ) ;
// NOTE : Consider whether the m_showSidebarAction is checked, because
// the sidebar can be forcibly hidden if the welcome screen is displayed
sidebarGroup . writeEntry ( SIDEBAR_VISIBLE_KEY , m_sidebar - > isVisibleTo ( this ) | | m_showSidebarAction - > isChecked ( ) ) ;
KConfigGroup group = KSharedConfig : : openConfig ( ) - > group ( " Desktop Entry " ) ;
group . writeEntry ( " FullScreen " , m_fullScreenAction - > isChecked ( ) ) ;
if ( m_fullScreenAction - > isChecked ( ) ) {
@ -425,6 +535,19 @@ void Shell::setupActions()
m_undoCloseTab - > setIcon ( QIcon : : fromTheme ( QStringLiteral ( " edit-undo " ) ) ) ;
m_undoCloseTab - > setEnabled ( false ) ;
connect ( m_undoCloseTab , & QAction : : triggered , this , & Shell : : undoCloseTab ) ;
m_showSidebarAction = actionCollection ( ) - > addAction ( QStringLiteral ( " okular_show_sidebar " ) ) ;
m_showSidebarAction - > setCheckable ( true ) ;
m_showSidebarAction - > setIcon ( QIcon : : fromTheme ( QStringLiteral ( " sidebar-show-symbolic " ) ) ) ;
m_showSidebarAction - > setText ( i18n ( " Show Sidebar " ) ) ;
connect ( m_showSidebarAction , & QAction : : triggered , m_sidebar , & Sidebar : : setVisible ) ;
m_lockSidebarAction = actionCollection ( ) - > addAction ( QStringLiteral ( " okular_lock_sidebar " ) ) ;
m_lockSidebarAction - > setCheckable ( true ) ;
m_lockSidebarAction - > setIcon ( QIcon : : fromTheme ( QStringLiteral ( " lock " ) ) ) ;
m_lockSidebarAction - > setText ( i18n ( " Lock Sidebar " ) ) ;
connect ( m_lockSidebarAction , & QAction : : triggered , m_sidebar , & Sidebar : : setLocked ) ;
m_sidebar - > addAction ( m_lockSidebarAction ) ;
}
void Shell : : saveProperties ( KConfigGroup & group )
@ -673,7 +796,24 @@ bool Shell::queryClose()
void Shell : : setActiveTab ( int tab )
{
m_tabWidget - > setCurrentIndex ( tab ) ;
// NOTE : createGUI(...) breaks the visibility of the sidebar, so we need
// to save and restore it
const bool isSidebarVisible = m_sidebar - > isVisible ( ) ;
createGUI ( m_tabs [ tab ] . part ) ;
m_sidebar - > setVisible ( isSidebarVisible ) ;
// dock KPart's sidebar if new and make it current
Okular : : ViewerInterface * iPart = qobject_cast < Okular : : ViewerInterface * > ( m_tabs [ tab ] . part ) ;
Q_ASSERT ( iPart ) ;
QWidget * sideContainer = iPart - > getSideContainer ( ) ;
if ( m_sidebar - > indexOf ( sideContainer ) = = - 1 ) {
m_sidebar - > addWidget ( sideContainer ) ;
if ( m_sidebar - > maximumWidth ( ) > sideContainer - > maximumWidth ( ) ) {
m_sidebar - > setMaximumWidth ( sideContainer - > maximumWidth ( ) ) ;
}
}
m_sidebar - > setCurrentWidget ( sideContainer ) ;
m_printAction - > setEnabled ( m_tabs [ tab ] . printEnabled ) ;
m_closeAction - > setEnabled ( m_tabs [ tab ] . closeEnabled ) ;
@ -689,6 +829,13 @@ void Shell::closeTab(int tab)
part - > factory ( ) - > removeClient ( part ) ;
}
part - > disconnect ( ) ;
Okular : : ViewerInterface * iPart = qobject_cast < Okular : : ViewerInterface * > ( m_tabs [ tab ] . part ) ;
Q_ASSERT ( iPart ) ;
QWidget * sideContainer = iPart - > getSideContainer ( ) ;
m_sidebar - > removeWidget ( sideContainer ) ;
connect ( part , & QObject : : destroyed , sideContainer , & QObject : : deleteLater ) ;
part - > deleteLater ( ) ;
m_tabs . removeAt ( tab ) ;
m_tabWidget - > removeTab ( tab ) ;
@ -776,7 +923,7 @@ void Shell::applyOptionsToPart(QObject *part, const QString &serializedOptions)
}
}
void Shell : : connectPart ( QObjec t * part )
void Shell : : connectPart ( const KParts : : ReadWritePar t * part )
{
// We're abusing the fact we know the part is our part here
connect ( this , SIGNAL ( moveSplitter ( int ) ) , part , SLOT ( moveSplitter ( int ) ) ) ; // clazy:exclude=old-style-connect
@ -788,6 +935,12 @@ void Shell::connectPart(QObject *part)
// Otherwise the QSize,QSize gets turned into QSize, QSize that is not normalized signals and is slightly slower
connect ( part , SIGNAL ( fitWindowToPage ( QSize , QSize ) ) , this , SLOT ( slotFitWindowToPage ( QSize , QSize ) ) ) ; // clazy:exclude=old-style-connect
// clang-format on
// since sidebar is now docked to main window, we use another action
// to show/hide it, so we should hide a similar KPart's action
if ( QAction * action = part - > actionCollection ( ) - > action ( QStringLiteral ( " show_leftpanel " ) ) ) {
action - > setVisible ( false ) ;
}
}
void Shell : : print ( )
@ -903,12 +1056,17 @@ void Shell::slotFitWindowToPage(const QSize pageViewSize, const QSize pageSize)
void Shell : : hideWelcomeScreen ( )
{
m_sidebar - > setVisible ( m_showSidebarAction - > isChecked ( ) ) ;
m_centralStackedWidget - > setCurrentWidget ( m_tabWidget ) ;
m_showSidebarAction - > setEnabled ( true ) ;
}
void Shell : : showWelcomeScreen ( )
{
m_showSidebarAction - > setEnabled ( false ) ;
m_centralStackedWidget - > setCurrentWidget ( m_welcomeScreen ) ;
m_sidebar - > setVisible ( false ) ;
refreshRecentsOnWelcomeScreen ( ) ;
}
@ -927,4 +1085,6 @@ void Shell::forgetRecentItem(QUrl const &url)
}
}
# include "shell.moc"
/* kate: replace-tabs on; indent-width 4; */