diff --git a/krusader/Panel/listpanel.h b/krusader/Panel/listpanel.h --- a/krusader/Panel/listpanel.h +++ b/krusader/Panel/listpanel.h @@ -67,6 +67,7 @@ #define PROP_SYNC_BUTTON_ON 1 #define PROP_LOCKED 2 +#define PROP_PINNED 4 class DirHistoryButton; class KrBookmarkButton; @@ -86,6 +87,14 @@ friend class ListPanelFunc; Q_OBJECT public: + + enum TabState { + DEFAULT, + LOCKED, + // locked tab with changeable address + PINNED + }; + // constructor create the panel, but DOESN'T fill it with data, use start() ListPanel(QWidget *parent, AbstractPanelManager *manager, KConfigGroup cfg = KConfigGroup()); ~ListPanel(); @@ -101,10 +110,13 @@ } void changeType(int); bool isLocked() { - return _locked; + return _tabState == TabState::LOCKED; } - void setLocked(bool lck) { - _locked = lck; + bool isPinned() { + return _tabState == TabState::PINNED; + } + void setTabState(TabState tabState) { + _tabState = tabState; } ListPanelActions *actions() { @@ -124,6 +136,9 @@ void saveSettings(KConfigGroup cfg, bool saveHistory); void restoreSettings(KConfigGroup cfg); + void setPinnedUrl(QUrl &pinnedUrl) { _pinnedUrl = pinnedUrl; }; + QUrl pinnedUrl() const { return _pinnedUrl; }; + public slots: void popRightClickMenu(const QPoint&); void popEmptyRightClickMenu(const QPoint &); @@ -244,7 +259,8 @@ private: QUrl _navigatorUrl; // distinguish between new user set URL and new custom set URL - bool _locked; + QUrl _pinnedUrl; // only for TabState::PINNED + TabState _tabState; QList sidebarSplitterSizes; }; diff --git a/krusader/Panel/listpanel.cpp b/krusader/Panel/listpanel.cpp --- a/krusader/Panel/listpanel.cpp +++ b/krusader/Panel/listpanel.cpp @@ -133,7 +133,7 @@ QWidget(parent), KrPanel(manager, this, new ListPanelFunc(this)), panelType(-1), colorMask(255), compareMode(false), previewJob(0), inlineRefreshJob(0), searchBar(0), cdRootButton(0), cdUpButton(0), - sidebarButton(0), sidebar(0), fileSystemError(0), _navigatorUrl(), _locked(false) + sidebarButton(0), sidebar(0), fileSystemError(0), _navigatorUrl(), _tabState(TabState::DEFAULT) { if(cfg.isValid()) panelType = cfg.readEntry("Type", -1); @@ -498,17 +498,27 @@ int ListPanel::getProperties() { int props = 0; - if (syncBrowseButton->isChecked()) + if (syncBrowseButton->isChecked()) { props |= PROP_SYNC_BUTTON_ON; - if (_locked) + } + if (isLocked()) { props |= PROP_LOCKED; + } else if (isPinned()) { + props |= PROP_PINNED; + } return props; } void ListPanel::setProperties(int prop) { syncBrowseButton->setChecked(prop & PROP_SYNC_BUTTON_ON); - _locked = (prop & PROP_LOCKED); + if (prop & PROP_LOCKED) { + _tabState = TabState::LOCKED; + } else if (prop & PROP_PINNED) { + _tabState = TabState::PINNED; + } else { + _tabState = TabState::DEFAULT; + } } bool ListPanel::eventFilter(QObject * watched, QEvent * e) @@ -1199,6 +1209,7 @@ cfg.writeEntry("Url", url.toString()); cfg.writeEntry("Type", getType()); cfg.writeEntry("Properties", getProperties()); + cfg.writeEntry("PinnedUrl", pinnedUrl().toString()); if(saveHistory) func->history->save(KConfigGroup(&cfg, "History")); view->saveSettings(KConfigGroup(&cfg, "View")); @@ -1240,6 +1251,15 @@ setProperties(cfg.readEntry("Properties", 0)); + if (isPinned()) { + QUrl pinnedUrl(cfg.readEntry("PinnedUrl", "invalid")); + if (!pinnedUrl.isValid()) { + pinnedUrl = func->history->currentUrl(); + } + func->openUrl(pinnedUrl); + setPinnedUrl(pinnedUrl); + } + if (cfg.hasKey("PopupPosition")) { // sidebar was visible, restore toggleSidebar(); // create and show sidebar->restoreSettings(KConfigGroup(&cfg, "PanelPopup")); diff --git a/krusader/Panel/panelfunc.cpp b/krusader/Panel/panelfunc.cpp --- a/krusader/Panel/panelfunc.cpp +++ b/krusader/Panel/panelfunc.cpp @@ -198,7 +198,7 @@ QString relative = QDir(panel->virtualPath().path() + '/').relativeFilePath(url.path()); syncURL.setPath(QDir::cleanPath(syncURL.path() + '/' + relative)); - panel->otherPanel()->gui->setLocked(false); + panel->otherPanel()->gui->setTabState(ListPanel::TabState::DEFAULT); otherFunc()->openUrlInternal(syncURL, nameToMakeCurrent, false, false); } openUrlInternal(url, nameToMakeCurrent, false, manuallyEntered); diff --git a/krusader/actionsbase.cpp b/krusader/actionsbase.cpp --- a/krusader/actionsbase.cpp +++ b/krusader/actionsbase.cpp @@ -42,20 +42,17 @@ QAction *ActionsBase::createAction(QString text, QString icon, bool isToggleAction) { - QAction *a; if(isToggleAction) { if (icon == 0) - a = (QAction *)(new KToggleAction(text, this)); + return (QAction *)(new KToggleAction(text, this)); else - a = (QAction *)new KToggleAction(QIcon::fromTheme(icon), text, this); + return (QAction *)(new KToggleAction(QIcon::fromTheme(icon), text, this)); } else { if (icon == 0) - a = new QAction(text, this); + return new QAction(text, this); else - a = new QAction(QIcon::fromTheme(icon), text, this); + return new QAction(QIcon::fromTheme(icon), text, this); } - - return a; } QAction *ActionsBase::action(QString text, QString icon, QKeySequence shortcut, diff --git a/krusader/panelmanager.h b/krusader/panelmanager.h --- a/krusader/panelmanager.h +++ b/krusader/panelmanager.h @@ -101,6 +101,7 @@ void slotNewTab(const QUrl &url, bool setCurrent = true, KrPanel *nextTo = 0); void slotNewTab(); void slotLockTab(); + void slotPinTab(); void slotNextTab(); void slotPreviousTab(); diff --git a/krusader/panelmanager.cpp b/krusader/panelmanager.cpp --- a/krusader/panelmanager.cpp +++ b/krusader/panelmanager.cpp @@ -114,7 +114,6 @@ } void PanelManager::slotCurrentTabChanged(int index) -// void PanelManager::slotChangePanel(ListPanel *p, bool makeActive) { ListPanel *panel = _tabbar->getPanel(index); @@ -136,6 +135,11 @@ if (otherManager()) { otherManager()->currentPanel()->otherPanelChanged(); } + + // go back to pinned url if tab is pinned and switched back to active + if (panel->isPinned()) { + panel->func->openUrl(panel->pinnedUrl()); + } } ListPanel* PanelManager::createPanel(KConfigGroup cfg) @@ -259,11 +263,10 @@ KConfigGroup cfg(krConfig, grpName); nextTo->gui->saveSettings(cfg, true); + // reset undesired duplicated settings + cfg.writeEntry("Properties", 0); p->restoreSettings(cfg); krConfig->deleteGroup(grpName); - - // reset undesired duplicated settings - p->setLocked(false); } else p->start(url); @@ -287,9 +290,6 @@ ListPanel *oldp; -// if (index == _tabbar->currentIndex()) -// slotChangePanel(_tabbar->removeCurrentPanel(oldp), false); -// else _tabbar->removePanel(index, oldp); //this automatically changes the current panel _stack->removeWidget(oldp); @@ -438,7 +438,19 @@ void PanelManager::slotLockTab() { ListPanel *panel = _currentPanel; - panel->gui->setLocked(!panel->gui->isLocked()); + panel->gui->setTabState(panel->gui->isLocked() ? ListPanel::TabState::DEFAULT : ListPanel::TabState::LOCKED); + _actions->refreshActions(); + _tabbar->updateTab(panel); +} + +void PanelManager::slotPinTab() +{ + ListPanel *panel = _currentPanel; + panel->gui->setTabState(panel->gui->isPinned() ? ListPanel::TabState::DEFAULT : ListPanel::TabState::PINNED); + if (panel->gui->isPinned()) { + QUrl virtualPath = panel->virtualPath(); + panel->setPinnedUrl(virtualPath); + } _actions->refreshActions(); _tabbar->updateTab(panel); } diff --git a/krusader/paneltabbar.h b/krusader/paneltabbar.h --- a/krusader/paneltabbar.h +++ b/krusader/paneltabbar.h @@ -101,6 +101,7 @@ private: void setIcon(int index, ListPanel *panel); void handleDragEvent(int tabIndex); + void setPanelTextToTab(int tabIndex, ListPanel *panel); KActionMenu *_panelActionMenu; bool _left; int _maxTabLength; diff --git a/krusader/paneltabbar.cpp b/krusader/paneltabbar.cpp --- a/krusader/paneltabbar.cpp +++ b/krusader/paneltabbar.cpp @@ -24,6 +24,7 @@ #include "tabactions.h" #include "../krglobal.h" #include "Panel/listpanel.h" +#include "Panel/panelfunc.h" // QtCore #include @@ -51,6 +52,7 @@ insertAction(actions->actNewTab); insertAction(actions->actLockTab); + insertAction(actions->actPinTab); insertAction(actions->actDupTab); insertAction(actions->actMoveTabToOtherSide); insertAction(actions->actCloseTab); @@ -89,12 +91,12 @@ } } - const QString text = squeeze(panel->virtualPath()); + QUrl virtualPath = panel->virtualPath(); + panel->setPinnedUrl(virtualPath); + const QString text = squeeze(virtualPath); const int index = insertIndex != -1 ? insertTab(insertIndex, text) : addTab(text); - QVariant v; - v.setValue((long long)panel); - setTabData(index, v); + setTabData(index, QVariant((long long) panel)); setIcon(index, panel); @@ -116,9 +118,7 @@ void PanelTabBar::changePanel(int tabIdx, ListPanel *panel) { - QVariant v; - v.setValue((long long)panel); - setTabData(tabIdx, v); + setTabData(tabIdx, QVariant((long long) panel)); } ListPanel* PanelTabBar::removePanel(int index, ListPanel* &panelToDelete) @@ -142,7 +142,7 @@ // find which is the correct tab for (int i = 0; i < count(); i++) { if ((ListPanel*)tabData(i).toLongLong() == panel) { - setTabText(i, squeeze(panel->virtualPath(), i)); + setPanelTextToTab(i, panel); setIcon(i, panel); break; } @@ -157,8 +157,13 @@ void PanelTabBar::setIcon(int index, ListPanel *panel) { - setTabIcon(index, - panel->isLocked() ? krLoader->loadIcon("lock", KIconLoader::Toolbar, 16) : QIcon()); + QIcon tabIcon; + if (panel->isLocked()) { + tabIcon = krLoader->loadIcon("lock", KIconLoader::Toolbar, 16); + } else if (panel->isPinned()) { + tabIcon = krLoader->loadIcon("pin", KIconLoader::Toolbar, 16); + } + setTabIcon(index, tabIcon); } QString PanelTabBar::squeeze(const QUrl &url, int tabIndex) @@ -314,8 +319,17 @@ void PanelTabBar::layoutTabs() { - for (int i = 0; i < count(); i++) { - setTabText(i, squeeze(((ListPanel*)tabData(i).toLongLong())->virtualPath(), i)); - } + for (int i = 0; i < count(); i++) { + setPanelTextToTab(i, (ListPanel*) tabData(i).toLongLong()); + } } +void PanelTabBar::setPanelTextToTab(int tabIndex, ListPanel *panel) +{ + // update tab text from pinnedUrl in case the tab is pinned + if (panel->isPinned()) { + setTabText(tabIndex, squeeze(panel->pinnedUrl(), tabIndex)); + } else { + setTabText(tabIndex, squeeze(panel->virtualPath(), tabIndex)); + } +} diff --git a/krusader/tabactions.h b/krusader/tabactions.h --- a/krusader/tabactions.h +++ b/krusader/tabactions.h @@ -42,6 +42,7 @@ void newTab(); void duplicateTab(); void lockTab(); + void pinTab(); void closeTab(); void nextTab(); void previousTab(); @@ -53,7 +54,7 @@ inline PanelManager *activeManager(); QAction *actNewTab, *actDupTab, *actCloseTab, *actPreviousTab, *actNextTab, *actMoveTabToOtherSide; - QAction *actCloseInactiveTabs, *actCloseDuplicatedTabs, *actLockTab; + QAction *actCloseInactiveTabs, *actCloseDuplicatedTabs, *actLockTab, *actPinTab; }; diff --git a/krusader/tabactions.cpp b/krusader/tabactions.cpp --- a/krusader/tabactions.cpp +++ b/krusader/tabactions.cpp @@ -39,7 +39,8 @@ actPreviousTab = action(i18n("Previous Tab"), QString(), KStandardShortcut::tabPrev(), this, SLOT(previousTab()), "previous tab"); actCloseInactiveTabs = action(i18n("Close Inactive Tabs"), 0, 0, SLOT(closeInactiveTabs()), "close inactive tabs"); actCloseDuplicatedTabs = action(i18n("Close Duplicated Tabs"), 0, 0, SLOT(closeDuplicatedTabs()), "close duplicated tabs"); - actLockTab = action(i18n("Lock Tab"), 0, 0, SLOT(lockTab()), "lock tab"); + actLockTab = action(i18n("Lock Tab"), "lock", 0, SLOT(lockTab()), "lock tab"); + actPinTab = action(i18n("Pin Tab"), "pin", 0, SLOT(pinTab()), "pin tab"); } inline PanelManager *TabActions::activeManager() @@ -61,6 +62,8 @@ actPreviousTab->setEnabled(tabCount > 1); bool locked = activeManager()->currentPanel()->gui->isLocked(); actLockTab->setText(locked ? i18n("Unlock Tab") : i18n("Lock Tab")); + bool pinned = activeManager()->currentPanel()->gui->isPinned(); + actPinTab->setText(pinned ? i18n("Unpin Tab") : i18n("Pin Tab")); } void TabActions::newTab() @@ -108,3 +111,8 @@ { activeManager()->slotLockTab(); } + +void TabActions::pinTab() +{ + activeManager()->slotPinTab(); +}