Merge branch 'master' into frameworks

Conflicts:
	dolphin/src/dolphinmainwindow.cpp
	dolphin/src/dolphinmainwindow.h
	dolphin/src/dolphinrecenttabsmenu.cpp
	dolphin/src/dolphinviewcontainer.cpp
	kfind/CMakeLists.txt
This commit is contained in:
Emmanuel Pescosta 2014-08-22 23:17:02 +02:00
commit d4fb129710
14 changed files with 822 additions and 516 deletions

View file

@ -153,6 +153,7 @@ set(dolphin_SRCS
dolphintabbar.cpp
dolphinrecenttabsmenu.cpp
dolphintabpage.cpp
dolphintabwidget.cpp
filterbar/filterbar.cpp
main.cpp
panels/information/filemetadataconfigurationdialog.cpp

View file

@ -17,6 +17,7 @@
<name xml:lang="ia">Dolphin</name>
<name xml:lang="it">Dolphin</name>
<name xml:lang="lt">Dolphin</name>
<name xml:lang="nb">Dolphin</name>
<name xml:lang="nds">Dolphin</name>
<name xml:lang="nl">Dolphin</name>
<name xml:lang="pl">Dolphin</name>
@ -32,6 +33,7 @@
<name xml:lang="sv">Dolphin</name>
<name xml:lang="uk">Dolphin</name>
<name xml:lang="x-test">xxDolphinxx</name>
<name xml:lang="zh-TW">Dolphin</name>
<summary>File Manager</summary>
<summary xml:lang="ar">مدير ملفات</summary>
<summary xml:lang="ca">Gestor de fitxers</summary>
@ -46,6 +48,7 @@
<summary xml:lang="ia">Gerente de File</summary>
<summary xml:lang="it">Gestore file</summary>
<summary xml:lang="lt">Failų tvarkyklė</summary>
<summary xml:lang="nb">Filbehandler</summary>
<summary xml:lang="nds">Dateipleger</summary>
<summary xml:lang="nl">Bestandsbeheerder</summary>
<summary xml:lang="pl">Zarządzanie plikami</summary>
@ -61,6 +64,7 @@
<summary xml:lang="sv">Filhanterare</summary>
<summary xml:lang="uk">Програма для керування файлами</summary>
<summary xml:lang="x-test">xxFile Managerxx</summary>
<summary xml:lang="zh-TW">檔案管理員</summary>
<description>
<p>Dolphin is a lightweight file manager. It has been designed with ease of use and simplicity in mind, while still allowing flexibility and customisation. This means that you can do your file management exactly the way you want to do it.</p>
<p xml:lang="ar">دولفين هو مدير ملفات خفيف. صُمِّم دولفين مع أخذ سهولة الاستخدام والبساطة بعين الاعتبار، مع السماح بالمرونة والتخصيص. يعني هذا أنه يمكنك إدارة ملفاتك كما تريد تماماً.</p>
@ -73,6 +77,7 @@
<p xml:lang="fr">Dolphin est un gestionnaire de fichier léger. Il a été conçu en gardant à l'esprit la simplicité et l'aisance à l'usage, tout en permettant flexibilité et personnalisation. Cela signifie que vous pouvez gérer vos fichiers de la manière exacte que vous voulez.</p>
<p xml:lang="ia">Dolphin es un gerente de file legier. Il ha essite designate con facilitate de uso e simplicitate in le mente, mentre il permitte ancora flexibilitate e personalisation. Isto significa que tu pote facer le gerente de file exactemente como tu lo vole.</p>
<p xml:lang="it">Dolphin è un gestore file leggero. È stato progettato per essere facile da utilizzare e pensando alla semplicità, garantendo al contempo flessibilità e personalizzazione. Ciò significa che puoi gestire i tuoi file come meglio desideri.</p>
<p xml:lang="nb">Dolphin er en lettvekts filbehandler. Den er laget for å være enkel og lett å bruke, samtidig som den er fleksibel og kan tilpasses. Det betyr at du kan utføre dine filbehandlingsoppgaver akkurat slik du vil gjøre det.</p>
<p xml:lang="nds">Dolphin is en slank Dateipleger. Dat wöör buut mit de Idee vun't eenfache Bedenen vör Ogen, bides dat liekers flexibel un topassbor wesen schull. Du kannst Dien Dateien also jüst so plegen, as Du dat wullt.</p>
<p xml:lang="nl">Dolphin is een lichtgewicht bestandsbeheerder. Het is ontworpen met gebruiksgemak en eenvoud in gedachte en staat toch flexibiliteit en aan te passen toe. Dit betekent dat u uw bestandsbeheer kunt doen precies op de manier zoals u dat wilt.</p>
<p xml:lang="pl">Dolphin jest lekkim programem do zarządzania plikami. Został on opracowany mając na uwadze łatwość i prostotę obsługi, zapewniając jednocześnie elastyczność i możliwość dostosowania. Oznacza to, że można urządzić zarządzanie plikami w dokładnie taki sposób w jaki jest to pożądane.</p>
@ -87,6 +92,7 @@
<p xml:lang="sv">Dolphin är en lättviktig filhanterare. Den har konstruerats med användbarhet och enkelhet i åtanke, men ändå tillåta flexibilitet och anpassning. Det betyder att du kan hantera filer exakt på det sätt som du vill göra det.</p>
<p xml:lang="uk">Dolphin — невибаглива до ресурсів програма для керування файлами. Її створено простою у користуванні і гнучкою у налаштовуванні. Це означає, що ви можете зробити керування файлами саме таким, як вам потрібно.</p>
<p xml:lang="x-test">xxDolphin is a lightweight file manager. It has been designed with ease of use and simplicity in mind, while still allowing flexibility and customisation. This means that you can do your file management exactly the way you want to do it.xx</p>
<p xml:lang="zh-TW">Dolphin 是一套輕量級的檔案管理員。它設計的理念是易用與簡單,但仍然保持足夠的彈性。這表示您可以用您想要使用的方式來管理您的檔案。</p>
<p>Features:</p>
<p xml:lang="ar">المزايا:</p>
<p xml:lang="ca">Característiques:</p>
@ -101,6 +107,7 @@
<p xml:lang="ia">Characteristicas:</p>
<p xml:lang="it">Funzionalità:</p>
<p xml:lang="lt">Galimybės</p>
<p xml:lang="nb">Egenskaper:</p>
<p xml:lang="nds">Markmalen:</p>
<p xml:lang="nl">Mogelijkheden:</p>
<p xml:lang="pl">Możliwości:</p>
@ -116,6 +123,7 @@
<p xml:lang="sv">Funktioner:</p>
<p xml:lang="uk">Можливості:</p>
<p xml:lang="x-test">xxFeatures:xx</p>
<p xml:lang="zh-TW">功能:</p>
<ul>
<li>Navigation (or breadcrumb) bar for URLs, allowing you to quickly navigate through the hierarchy of files and folders.</li>
<li xml:lang="ca">Barra de navegació (o fil d'Ariadna) per els URL, permetent una navegació ràpida per la jerarquia de fitxers i carpetes.</li>
@ -127,6 +135,7 @@
<li xml:lang="fr">Barre de navigation (ou fil d'Ariane) permettant de naviguer rapidement dans la hiérarchie de fichiers et de dossiers.</li>
<li xml:lang="ia">Barra de navigation (o "breadcrumb") pro URLs, que il permitte te navigar rapidemente a transverso del hierarchia de files e dossieres.</li>
<li xml:lang="it">La barra di navigazione per gli URL, che ti consente di navigare rapidamente attraverso la struttura di file e cartelle.</li>
<li xml:lang="nb">Navigasjonslinje (brødsmulelinje) for URL-er slik at du raskt kan navigere gjennom hierarkiet av filer og mapper.</li>
<li xml:lang="nds">Steed- (oder Krömelspoor-)Balken för URLs, mit de Du Di fix dör de Hierarchie ut Dateien un Ornern bewegen kannst</li>
<li xml:lang="nl">Navigatie- (of broodkruimel)balk voor URL's, waarmee u snel kunt navigeren door de hiërarchie van bestanden en mappen.</li>
<li xml:lang="pl">Pasek nawigacji (lub okruchy chleba) dla adresów URL, umożliwiające szybkie przechodzenie w hierarchii plików i katalogów.</li>
@ -141,6 +150,7 @@
<li xml:lang="sv">Navigeringsrad (eller länkstig) för webbadresser, som låter dig snabbt navigera igenom hierarkin av filer och kataloger.</li>
<li xml:lang="uk">Панель навігації (звичайний режим і режим послідовної навігації) для адрес надає вам змогу швидко пересуватися ієрархією файлів та каталогів.</li>
<li xml:lang="x-test">xxNavigation (or breadcrumb) bar for URLs, allowing you to quickly navigate through the hierarchy of files and folders.xx</li>
<li xml:lang="zh-TW">網址導覽列讓您可以快速瀏覽檔案與資料夾。</li>
<li>Supports several different kinds of view styles and properties and allows you to configure the view exactly how you want it.</li>
<li xml:lang="ar">يدعم العديد من الأنواع المختلفة من الخصائص وأنماط العرض ويسمك لك بضبط العرض كما تريد تماماً.</li>
<li xml:lang="ca">Accepta diferents classes diverses d'estils de visualització i propietats i us permet configurar la visualització exactament com la vulgueu.</li>
@ -152,6 +162,7 @@
<li xml:lang="fr">Prend en charge plusieurs types de styles d'affichage et de propriété et vous permet de configurer l'affichage de la manière exacte que vous voulez.</li>
<li xml:lang="ia">Il supporta multe differente typos de stilos de vista e proprietates e il permitte te configurar le vista exactemente como tu vole.</li>
<li xml:lang="it">Supporta diversi stili di visualizzazione e proprietà e ti consente di configurare la vista come desideri.</li>
<li xml:lang="nb">Støtter flere forskjellige visningsstiler og kan sette opp visningen akkurat slik du vil ha den.</li>
<li xml:lang="nds">Ünnerstütt en Reeg verscheden Ansichtstilen un -egenschappen un lett Di de Ansicht jüst so topassen, as Du dat bruukst.</li>
<li xml:lang="nl">Ondersteunt een aantal verschillende soorten stijlen van weergave en eigenschappen en biedt u de mogelijkheid de weergave in te stellen precies zoals u dat wilt.</li>
<li xml:lang="pl">Obsługa wielu różnych rodzajów stylów widoków i właściwości oraz możliwość ustawienia widoku dopasowanego do potrzeb.</li>
@ -166,6 +177,7 @@
<li xml:lang="sv">Stöder flera olika sorters visningsstilar och egenskaper och låter dig anpassa visningen exakt som du vill ha den.</li>
<li xml:lang="uk">Підтримка декількох різних типів та параметрів перегляду надає вам змогу налаштувати перегляд каталогів саме так, як вам це потрібно.</li>
<li xml:lang="x-test">xxSupports several different kinds of view styles and properties and allows you to configure the view exactly how you want it.xx</li>
<li xml:lang="zh-TW">網址導覽列讓您可以快速瀏覽檔案與資料夾。</li>
<li>Split view, allowing you to easily copy or move files between locations.</li>
<li xml:lang="ar">العرض المقسوم، يسمح لك بنسخ ونقل الملفات بين مكانين بسهولة.</li>
<li xml:lang="ca">Divisió de visualització, permetent copiar o moure fitxers fàcilment entre les ubicacions.</li>
@ -177,6 +189,7 @@
<li xml:lang="fr">Affichage divisé, permettant de facilement copier ou déplacer des fichiers dans les différents emplacements.</li>
<li xml:lang="ia">Scinde vista, il permitte te copiar o mover facilemente files inter locationes.</li>
<li xml:lang="it">La vista divisa, che ti consente di copiare o spostare i file tra le diverse posizioni in maniera semplice.</li>
<li xml:lang="nb">Delt visning, så du lett kan kopiere eller flytte filer mellom steder.</li>
<li xml:lang="nds">Deelt Ansicht, mit De Du Dateien eenfach twischen Steden koperen oder bewegen kannst.</li>
<li xml:lang="nl">Gesplitst beeld, waarmee u gemakkelijk bestanden kunt kopiëren of verplaatsen tussen locaties.</li>
<li xml:lang="pl">Widok podzielony, umożliwiający łatwe kopiowane lub przenoszenie plików pomiędzy położeniami.</li>
@ -191,6 +204,7 @@
<li xml:lang="sv">Delad visning, som låter dig enkelt kopiera eller flytta filer mellan platser.</li>
<li xml:lang="uk">За допомогою режиму двопанельного розділеного перегляду ви зможе без проблем копіювати або пересувати файли між каталогами.</li>
<li xml:lang="x-test">xxSplit view, allowing you to easily copy or move files between locations.xx</li>
<li xml:lang="zh-TW">支援數個檢視模式,您也可以調整檢視模式的屬性。</li>
<li>Additional information and shortcuts are available as dock-able panels, allowing you to move them around freely and display exactly what you want.</li>
<li xml:lang="ar">تتوفر معلومات واختصارات إضافية كألواح قابلة للتركيب، مما يسمح لك بنقلها بحريّة وعرضها بالضبط كما تريد.</li>
<li xml:lang="ca">Hi ha informació addicional i dreceres disponibles com a plafons acoblables, permetent moure'ls lliurement i mostrar exactament el què vulgueu.</li>
@ -202,6 +216,7 @@
<li xml:lang="fr">Des informations supplémentaires et des raccourcis sont disponible comme panneaux ancrable librement déplaçable et affichant exactement ce que vous voulez.</li>
<li xml:lang="ia">Information additional e vias breve es disponibile como pannellos de basin (dock-panels), il permitte mover los liberemente e monstrar los exactemente como tu vole.</li>
<li xml:lang="it">Informazioni aggiuntive e scorciatoie sono disponibili come pannelli agganciabili, che possono essere spostati liberamente e visualizzare esattamente ciò che desideri.</li>
<li xml:lang="nb">Mer informasjon og snarveier er tilgjengelige som dokkbare ruter, som du kan flytte fritt rundt og bruke til å vise akkurat hva du vil.</li>
<li xml:lang="nds">Bito-Infos un Leestekens laat sik as Paneels andocken, Du kannst ehr verschuven un se jüst dat wiesen laten, wat Du weten wullt.</li>
<li xml:lang="nl">Extra informatie en sneltoetsen zijn beschikbaar als vast te zetten panelen, die u vrij kunt verplaatsen en precies kunt tonen wat u wilt.</li>
<li xml:lang="pl">Dodatkowe szczegóły i skróty dostępne jako dokowalne panele, umożliwiające ich dowolne przenoszenie i wyświetlanie dopasowane do potrzeb.</li>
@ -216,6 +231,7 @@
<li xml:lang="sv">Ytterligare information och genvägar är tillgängliga som dockningsbara paneler, vilket låter dig flytta omkring dem fritt och visa exakt vad du vill.</li>
<li xml:lang="uk">За допомогою бічних пересувних панелей ви зможете отримувати додаткову інформацію та пересуватися каталогами. Ви можете розташувати ці панелі так, як вам це зручно, і наказати програмі показувати на них саме те, що вам потрібно.</li>
<li xml:lang="x-test">xxAdditional information and shortcuts are available as dock-able panels, allowing you to move them around freely and display exactly what you want.xx</li>
<li xml:lang="zh-TW">分割檢視讓您可以輕鬆複製或移動檔案。</li>
<li>Multiple tab support</li>
<li xml:lang="ar">دعم تعدّد الألسنة</li>
<li xml:lang="ca">Implementació de pestanyes múltiples</li>
@ -229,6 +245,7 @@
<li xml:lang="ia">Supporto de scheda multiple</li>
<li xml:lang="it">Supporto di schede multiple</li>
<li xml:lang="lt">Daugelio kortelių palaikymas</li>
<li xml:lang="nb">Støtte for flere faner</li>
<li xml:lang="nds">Ünnerstütten för Paneels</li>
<li xml:lang="nl">Ondersteuning voor meerdere tabbladen</li>
<li xml:lang="pl">Obsługa wielu kart</li>
@ -244,6 +261,7 @@
<li xml:lang="sv">Stöd för flera flikar</li>
<li xml:lang="uk">Підтримка роботи з вкладками.</li>
<li xml:lang="x-test">xxMultiple tab supportxx</li>
<li xml:lang="zh-TW">額外資訊與嵌入式面板捷徑讓您可以輕易顯示您常用的項目。</li>
<li>Informational dialogues are displayed in an unobtrusive way.</li>
<li xml:lang="ca">El diàlegs informatius es mostren de manera no molesta.</li>
<li xml:lang="da">Informationsdialoger vises på en ikke-forstyrrende måde.</li>
@ -255,6 +273,7 @@
<li xml:lang="fr">Les dialogues d'information sont affiché de manière discrète.</li>
<li xml:lang="ia">Dialogos de information es monstrate de modo non importun.</li>
<li xml:lang="it">Le finestre informative sono visualizzate in modo molto discreto.</li>
<li xml:lang="nb">Informasjonsdialoger vises på en lite påtrengende måte.</li>
<li xml:lang="nds">Informatschoondialogen kaamt Di nich in'n Weg.</li>
<li xml:lang="nl">Informatiedialogen worden op een prettige manier getoond.</li>
<li xml:lang="pl">Pokazywanie informacyjnych okien dialogowych w nienatrętny sposób.</li>
@ -269,6 +288,7 @@
<li xml:lang="sv">Dialogrutor med information visas på ett diskret sätt.</li>
<li xml:lang="uk">Показ інформаційних панелей у зручний спосіб, що не заважає роботі.</li>
<li xml:lang="x-test">xxInformational dialogues are displayed in an unobtrusive way.xx</li>
<li xml:lang="zh-TW">支援多分頁</li>
<li>Undo/redo support</li>
<li xml:lang="ca">Implementació de desfer/refer</li>
<li xml:lang="da">Understøttelse af fortryd/gendan</li>
@ -280,6 +300,7 @@
<li xml:lang="fr">Prise en charge d'annulation et recommencement</li>
<li xml:lang="ia">Supporto de annulla/reface</li>
<li xml:lang="it">Supporto di annulla/rifai</li>
<li xml:lang="nb">Støtte for angring/omgjøring</li>
<li xml:lang="nds">Ünnerstütten för Torüchnehmen un Wedderherstellen</li>
<li xml:lang="nl">Ondersteuning ongedaan maken/opnieuw</li>
<li xml:lang="pl">Obsługa cofnij/ponów</li>
@ -295,6 +316,7 @@
<li xml:lang="sv">Stöd för ångra och gör om</li>
<li xml:lang="uk">Підтримка скасовування та повторення дій.</li>
<li xml:lang="x-test">xxUndo/redo supportxx</li>
<li xml:lang="zh-TW">以不唐突的方式顯示資訊對話框。</li>
<li>Transparent network access through the KIO system.</li>
<li xml:lang="ar">اتصال شبكيّ مباشر باستخدام نظام KIO.</li>
<li xml:lang="ca">Accés transparent a la xarxa a través del sistema KIO.</li>
@ -307,6 +329,7 @@
<li xml:lang="fr">Accès au réseau transparent grâce au système des KIO.</li>
<li xml:lang="ia">Accesso de rete transparente a transverso del systema KIO.</li>
<li xml:lang="it">Accesso trasparente alla rete tramite il sistema KIO.</li>
<li xml:lang="nb">Gjennomsiktig nettverkstilgang via KIO-systemet.</li>
<li xml:lang="nds">Direkt Nettwarktogriep över dat KDE-In-/Utgaav-(KIO-)Moduulsysteem</li>
<li xml:lang="nl">Transparante toegang tot het netwerk via het KIO systeem.</li>
<li xml:lang="pl">Przezroczysty dostęp do sieci przez system KIO.</li>
@ -322,6 +345,7 @@
<li xml:lang="sv">Transparent nätverksåtkomst via I/O-slavsystemet.</li>
<li xml:lang="uk">Прозорий доступ до ресурсів у мережі за допомогою системи KIO.</li>
<li xml:lang="x-test">xxTransparent network access through the KIO system.xx</li>
<li xml:lang="zh-TW">復原支援</li>
</ul>
</description>
<url type="homepage">http://dolphin.kde.org/</url>

View file

@ -26,7 +26,7 @@
#include "dolphincontextmenu.h"
#include "dolphinnewfilemenu.h"
#include "dolphinrecenttabsmenu.h"
#include "dolphintabbar.h"
#include "dolphintabwidget.h"
#include "dolphinviewcontainer.h"
#include "dolphintabpage.h"
#include "panels/folders/folderspanel.h"
@ -98,11 +98,8 @@ namespace {
DolphinMainWindow::DolphinMainWindow() :
KXmlGuiWindow(0),
m_newFileMenu(0),
m_tabBar(0),
m_tabWidget(0),
m_activeViewContainer(0),
m_centralWidgetLayout(0),
m_tabIndex(-1),
m_viewTab(),
m_actionHandler(0),
m_remoteEncoding(0),
m_settingsDialog(),
@ -135,6 +132,15 @@ DolphinMainWindow::DolphinMainWindow() :
setAcceptDrops(true);
m_tabWidget = new DolphinTabWidget(this);
connect(m_tabWidget, SIGNAL(activeViewChanged(DolphinViewContainer*)),
this, SLOT(activeViewChanged(DolphinViewContainer*)));
connect(m_tabWidget, SIGNAL(tabCountChanged(int)),
this, SLOT(tabCountChanged(int)));
connect(m_tabWidget, SIGNAL(currentUrlChanged(KUrl)),
this, SLOT(setUrlAsCaption(KUrl)));
setCentralWidget(m_tabWidget);
setupActions();
m_actionHandler = new DolphinViewActionHandler(actionCollection(), this);
@ -145,30 +151,6 @@ DolphinMainWindow::DolphinMainWindow() :
connect(this, &DolphinMainWindow::urlChanged,
m_remoteEncoding, &DolphinRemoteEncoding::slotAboutToOpenUrl);
m_tabBar = new DolphinTabBar(this);
connect(m_tabBar, SIGNAL(currentChanged(int)),
this, SLOT(setActiveTab(int)));
connect(m_tabBar, SIGNAL(tabCloseRequested(int)),
this, SLOT(closeTab(int)));
connect(m_tabBar, SIGNAL(openNewActivatedTab(int)),
this, SLOT(openNewActivatedTab(int)));
connect(m_tabBar, SIGNAL(tabMoved(int,int)),
this, SLOT(slotTabMoved(int,int)));
connect(m_tabBar, SIGNAL(tabDropEvent(int,QDropEvent*)),
this, SLOT(tabDropEvent(int,QDropEvent*)));
connect(m_tabBar, SIGNAL(tabDetachRequested(int)),
this, SLOT(detachTab(int)));
m_tabBar->blockSignals(true); // signals get unblocked after at least 2 tabs are open
m_tabBar->hide();
QWidget* centralWidget = new QWidget(this);
m_centralWidgetLayout = new QVBoxLayout(centralWidget);
m_centralWidgetLayout->setSpacing(0);
m_centralWidgetLayout->setMargin(0);
m_centralWidgetLayout->addWidget(m_tabBar);
setCentralWidget(centralWidget);
setupDockWidgets();
setupGUI(Keys | Save | Create | ToolBar);
@ -201,48 +183,12 @@ DolphinMainWindow::~DolphinMainWindow()
void DolphinMainWindow::openDirectories(const QList<KUrl>& dirs)
{
const bool hasSplitView = GeneralSettings::splitView();
// Open each directory inside a new tab. If the "split view" option has been enabled,
// always show two directories within one tab.
QList<KUrl>::const_iterator it = dirs.constBegin();
while (it != dirs.constEnd()) {
const KUrl& primaryUrl = *(it++);
if (hasSplitView && (it != dirs.constEnd())) {
const KUrl& secondaryUrl = *(it++);
openNewTab(primaryUrl, secondaryUrl);
} else {
openNewTab(primaryUrl);
}
}
m_tabWidget->openDirectories(dirs);
}
void DolphinMainWindow::openFiles(const QList<KUrl>& files)
{
if (files.isEmpty()) {
return;
}
// Get all distinct directories from 'files' and open a tab
// for each directory. If the "split view" option is enabled, two
// directories are shown inside one tab (see openDirectories()).
QList<KUrl> dirs;
foreach (const KUrl& url, files) {
const KUrl dir(url.directory());
if (!dirs.contains(dir)) {
dirs.append(dir);
}
}
openDirectories(dirs);
// Select the files. Although the files can be split between several
// tabs, there is no need to split 'files' accordingly, as
// the DolphinView will just ignore invalid selections.
foreach (DolphinTabPage* tabPage, m_viewTab) {
tabPage->markUrlsAsSelected(files);
tabPage->markUrlAsCurrent(files.first());
}
m_tabWidget->openFiles(files);
}
void DolphinMainWindow::showCommand(CommandType command)
@ -288,21 +234,13 @@ void DolphinMainWindow::changeUrl(const KUrl& url)
return;
}
DolphinViewContainer* view = activeViewContainer();
if (view) {
view->setUrl(url);
updateEditActions();
updatePasteAction();
updateViewActions();
updateGoActions();
setUrlAsCaption(url);
m_activeViewContainer->setUrl(url);
updateEditActions();
updatePasteAction();
updateViewActions();
updateGoActions();
const QString iconName = KIO::iconNameForUrl(url);
m_tabBar->setTabIcon(m_tabIndex, QIcon::fromTheme(iconName));
m_tabBar->setTabText(m_tabIndex, squeezedText(tabName(view->url())));
emit urlChanged(url);
}
emit urlChanged(url);
}
void DolphinMainWindow::slotTerminalDirectoryChanged(const KUrl& url)
@ -323,7 +261,7 @@ void DolphinMainWindow::slotSelectionChanged(const KFileItemList& selection)
{
updateEditActions();
const int selectedUrlsCount = m_viewTab.at(m_tabIndex)->selectedItemsCount();
const int selectedUrlsCount = m_tabWidget->currentTabPage()->selectedItemsCount();
QAction* compareFilesAction = actionCollection()->action("compare_files");
if (selectedUrlsCount == 2) {
@ -369,99 +307,19 @@ void DolphinMainWindow::openNewMainWindow()
KRun::run("dolphin %u", KUrl::List(), this);
}
void DolphinMainWindow::openNewTab()
void DolphinMainWindow::openNewActivatedTab()
{
const bool isUrlEditable = m_activeViewContainer->urlNavigator()->isUrlEditable();
openNewTab(m_activeViewContainer->url());
m_tabBar->setCurrentIndex(m_viewTab.count() - 1);
// The URL navigator of the new tab should have the same editable state
// as the current tab
KUrlNavigator* navigator = m_activeViewContainer->urlNavigator();
navigator->setUrlEditable(isUrlEditable);
if (isUrlEditable) {
// If a new tab is opened and the URL is editable, assure that
// the user can edit the URL without manually setting the focus
navigator->setFocus();
}
m_tabWidget->openNewActivatedTab();
}
void DolphinMainWindow::openNewTab(const KUrl& primaryUrl, const KUrl& secondaryUrl)
{
QWidget* focusWidget = QApplication::focusWidget();
DolphinTabPage* tabPage = new DolphinTabPage(primaryUrl, secondaryUrl, this);
m_viewTab.append(tabPage);
connect(tabPage, SIGNAL(activeViewChanged()),
this, SLOT(activeViewChanged()));
// The places-selector from the URL navigator should only be shown
// if the places dock is invisible
QDockWidget* placesDock = findChild<QDockWidget*>("placesDock");
const bool placesSelectorVisible = !placesDock || !placesDock->isVisible();
tabPage->setPlacesSelectorVisible(placesSelectorVisible);
DolphinViewContainer* primaryContainer = tabPage->primaryViewContainer();
connectViewSignals(primaryContainer);
if (tabPage->splitViewEnabled()) {
DolphinViewContainer* secondaryContainer = tabPage->secondaryViewContainer();
connectViewSignals(secondaryContainer);
}
tabPage->hide();
m_tabBar->addTab(QIcon::fromTheme(KIO::iconNameForUrl(primaryUrl)),
squeezedText(tabName(primaryUrl)));
if (m_viewTab.count() > 1) {
actionCollection()->action("close_tab")->setEnabled(true);
actionCollection()->action("activate_prev_tab")->setEnabled(true);
actionCollection()->action("activate_next_tab")->setEnabled(true);
m_tabBar->show();
m_tabBar->blockSignals(false);
}
if (focusWidget) {
// The DolphinViewContainer grabbed the keyboard focus. As the tab is opened
// in background, assure that the previous focused widget gets the focus back.
focusWidget->setFocus();
}
m_tabWidget->openNewTab(primaryUrl, secondaryUrl);
}
void DolphinMainWindow::openNewActivatedTab(const KUrl& primaryUrl, const KUrl& secondaryUrl)
{
openNewTab(primaryUrl, secondaryUrl);
setActiveTab(m_viewTab.count() - 1);
}
void DolphinMainWindow::openNewActivatedTab(int index)
{
Q_ASSERT(index >= 0);
const DolphinTabPage* tabPage = m_viewTab.at(index);
openNewActivatedTab(tabPage->activeViewContainer()->url());
}
void DolphinMainWindow::activateNextTab()
{
if (m_viewTab.count() >= 2) {
const int tabIndex = (m_tabBar->currentIndex() + 1) % m_tabBar->count();
setActiveTab(tabIndex);
}
}
void DolphinMainWindow::activatePrevTab()
{
if (m_viewTab.count() >= 2) {
int tabIndex = m_tabBar->currentIndex() - 1;
if (tabIndex == -1) {
tabIndex = m_tabBar->count() - 1;
}
setActiveTab(tabIndex);
}
m_tabWidget->openNewActivatedTab(primaryUrl, secondaryUrl);
}
void DolphinMainWindow::openInNewTab()
@ -500,12 +358,6 @@ void DolphinMainWindow::showEvent(QShowEvent* event)
{
KXmlGuiWindow::showEvent(event);
if (!m_activeViewContainer && m_viewTab.count() > 0) {
// If we have no active view container yet, we set the primary view container
// of the first tab as active view container.
setActiveTab(0);
}
if (!event->spontaneous()) {
m_activeViewContainer->view()->setFocus();
}
@ -521,7 +373,7 @@ void DolphinMainWindow::closeEvent(QCloseEvent* event)
closedByUser = false;
}
if (m_viewTab.count() > 1 && GeneralSettings::confirmClosingMultipleTabs() && closedByUser) {
if (m_tabWidget->count() > 1 && GeneralSettings::confirmClosingMultipleTabs() && closedByUser) {
// Ask the user if he really wants to quit and close all tabs.
// Open a confirmation dialog with 3 buttons:
// KDialog::Yes -> Quit
@ -557,7 +409,7 @@ void DolphinMainWindow::closeEvent(QCloseEvent* event)
break;
case QDialogButtonBox::No:
// Close only the current tab
closeTab();
m_tabWidget->closeTab();
default:
event->ignore();
return;
@ -572,32 +424,12 @@ void DolphinMainWindow::closeEvent(QCloseEvent* event)
void DolphinMainWindow::saveProperties(KConfigGroup& group)
{
const int tabCount = m_viewTab.count();
group.writeEntry("Tab Count", tabCount);
group.writeEntry("Active Tab Index", m_tabBar->currentIndex());
for (int i = 0; i < tabCount; ++i) {
const DolphinTabPage* tabPage = m_viewTab.at(i);
group.writeEntry("Tab " % QString::number(i), tabPage->saveState());
}
m_tabWidget->saveProperties(group);
}
void DolphinMainWindow::readProperties(const KConfigGroup& group)
{
const int tabCount = group.readEntry("Tab Count", 1);
for (int i = 0; i < tabCount; ++i) {
const QByteArray state = group.readEntry("Tab " % QString::number(i), QByteArray());
DolphinTabPage* tabPage = m_viewTab.at(i);
tabPage->restoreState(state);
// openNewTab() needs to be called only tabCount - 1 times
if (i != tabCount - 1) {
openNewTab();
}
}
const int index = group.readEntry("Active Tab Index", 0);
m_tabBar->setCurrentIndex(index);
m_tabWidget->readProperties(group);
}
void DolphinMainWindow::updateNewMenu()
@ -701,13 +533,9 @@ void DolphinMainWindow::invertSelection()
void DolphinMainWindow::toggleSplitView()
{
DolphinTabPage* tabPage = m_viewTab.at(m_tabIndex);
DolphinTabPage* tabPage = m_tabWidget->currentTabPage();
tabPage->setSplitViewEnabled(!tabPage->splitViewEnabled());
if (tabPage->splitViewEnabled()) {
connectViewSignals(tabPage->secondaryViewContainer());
}
updateViewActions();
}
@ -770,14 +598,6 @@ void DolphinMainWindow::togglePanelLockState()
GeneralSettings::setLockPanels(newLockState);
}
void DolphinMainWindow::slotPlacesPanelVisibilityChanged(bool visible)
{
foreach (DolphinTabPage* tabPage, m_viewTab) {
// The Places selector in the location bar should be shown if and only if the Places panel is hidden.
tabPage->setPlacesSelectorVisible(!visible);
}
}
void DolphinMainWindow::goBack()
{
KUrlNavigator* urlNavigator = m_activeViewContainer->urlNavigator();
@ -843,7 +663,7 @@ void DolphinMainWindow::goHome(Qt::MouseButtons buttons)
void DolphinMainWindow::compareFiles()
{
const KFileItemList items = m_viewTab.at(m_tabIndex)->selectedItems();
const KFileItemList items = m_tabWidget->currentTabPage()->selectedItems();
if (items.count() != 2) {
// The action is disabled in this case, but it could have been triggered
// via D-Bus, see https://bugs.kde.org/show_bug.cgi?id=325517
@ -905,111 +725,6 @@ void DolphinMainWindow::editSettings()
}
}
void DolphinMainWindow::setActiveTab(int index)
{
Q_ASSERT(index >= 0);
Q_ASSERT(index < m_viewTab.count());
if (index == m_tabIndex) {
return;
}
m_tabBar->setCurrentIndex(index);
// hide current tab content
if (m_tabIndex >= 0) {
DolphinTabPage* hiddenTabPage = m_viewTab.at(m_tabIndex);
hiddenTabPage->hide();
m_centralWidgetLayout->removeWidget(hiddenTabPage);
}
// show active tab content
m_tabIndex = index;
DolphinTabPage* tabPage = m_viewTab.at(index);
m_centralWidgetLayout->addWidget(tabPage, 1);
tabPage->show();
setActiveViewContainer(tabPage->activeViewContainer());
}
void DolphinMainWindow::closeTab()
{
closeTab(m_tabBar->currentIndex());
}
void DolphinMainWindow::closeTab(int index)
{
Q_ASSERT(index >= 0);
Q_ASSERT(index < m_viewTab.count());
if (m_viewTab.count() == 1) {
// the last tab may never get closed
return;
}
if (index == m_tabIndex) {
// The tab that should be closed is the active tab. Activate the
// previous tab before closing the tab.
m_tabBar->setCurrentIndex((index > 0) ? index - 1 : 1);
}
DolphinTabPage* tabPage = m_viewTab.at(index);
if (tabPage->splitViewEnabled()) {
emit rememberClosedTab(tabPage->primaryViewContainer()->url(),
tabPage->secondaryViewContainer()->url());
} else {
emit rememberClosedTab(tabPage->primaryViewContainer()->url(), KUrl());
}
// delete tab
m_viewTab.removeAt(index);
tabPage->deleteLater();
m_tabBar->blockSignals(true);
m_tabBar->removeTab(index);
if (m_tabIndex > index) {
m_tabIndex--;
Q_ASSERT(m_tabIndex >= 0);
}
// if only one tab is left, also remove the tab entry so that
// closing the last tab is not possible
if (m_viewTab.count() < 2) {
actionCollection()->action("close_tab")->setEnabled(false);
actionCollection()->action("activate_prev_tab")->setEnabled(false);
actionCollection()->action("activate_next_tab")->setEnabled(false);
m_tabBar->hide();
} else {
m_tabBar->blockSignals(false);
}
}
void DolphinMainWindow::detachTab(int index)
{
Q_ASSERT(index >= 0);
const QString separator(QLatin1Char(' '));
QString command = QLatin1String("dolphin");
const DolphinTabPage* tabPage = m_viewTab.at(index);
command += separator + tabPage->primaryViewContainer()->url().url();
if (tabPage->splitViewEnabled()) {
command += separator + tabPage->secondaryViewContainer()->url().url();
command += separator + QLatin1String("-split");
}
KRun::runCommand(command, this);
closeTab(index);
}
void DolphinMainWindow::slotTabMoved(int from, int to)
{
m_viewTab.move(from, to);
m_tabIndex = m_tabBar->currentIndex();
}
void DolphinMainWindow::handleUrl(const KUrl& url)
{
delete m_lastHandleUrlStatJob;
@ -1043,20 +758,6 @@ void DolphinMainWindow::slotHandleUrlStatFinished(KJob* job)
}
}
void DolphinMainWindow::tabDropEvent(int tab, QDropEvent* event)
{
const KUrl::List urls = KUrl::List::fromMimeData(event->mimeData());
if (!urls.isEmpty() && tab != -1) {
const DolphinView* view = m_viewTab.at(tab)->activeViewContainer()->view();
QString error;
DragAndDropHelper::dropUrls(view->rootItem(), view->url(), event, error);
if (!error.isEmpty()) {
activeViewContainer()->showMessage(error, DolphinViewContainer::Error);
}
}
}
void DolphinMainWindow::slotWriteStateChanged(bool isFolderWritable)
{
newFileMenu()->setEnabled(isFolderWritable);
@ -1217,27 +918,28 @@ void DolphinMainWindow::slotPlaceActivated(const KUrl& url)
}
}
void DolphinMainWindow::activeViewChanged()
{
const DolphinTabPage* tabPage = m_viewTab.at(m_tabIndex);
setActiveViewContainer(tabPage->activeViewContainer());
}
void DolphinMainWindow::closedTabsCountChanged(unsigned int count)
{
actionCollection()->action("undo_close_tab")->setEnabled(count > 0);
}
void DolphinMainWindow::setActiveViewContainer(DolphinViewContainer* viewContainer)
void DolphinMainWindow::activeViewChanged(DolphinViewContainer* viewContainer)
{
DolphinViewContainer* oldViewContainer = m_activeViewContainer;
Q_ASSERT(viewContainer);
Q_ASSERT((viewContainer == m_viewTab.at(m_tabIndex)->primaryViewContainer()) ||
(viewContainer == m_viewTab.at(m_tabIndex)->secondaryViewContainer()));
if (m_activeViewContainer == viewContainer) {
return;
}
m_activeViewContainer = viewContainer;
if (oldViewContainer) {
// Disconnect all signals between the old view container (container,
// view and url navigator) and main window.
oldViewContainer->disconnect(this);
oldViewContainer->view()->disconnect(this);
oldViewContainer->urlNavigator()->disconnect(this);
}
connectViewSignals(viewContainer);
m_actionHandler->setCurrentView(viewContainer->view());
updateHistory();
@ -1246,14 +948,34 @@ void DolphinMainWindow::setActiveViewContainer(DolphinViewContainer* viewContain
updateViewActions();
updateGoActions();
const KUrl url = m_activeViewContainer->url();
setUrlAsCaption(url);
m_tabBar->setTabText(m_tabIndex, squeezedText(tabName(url)));
m_tabBar->setTabIcon(m_tabIndex, QIcon::fromTheme(KIO::iconNameForUrl(url)));
const KUrl url = viewContainer->url();
emit urlChanged(url);
}
void DolphinMainWindow::tabCountChanged(int count)
{
const bool enableTabActions = (count > 1);
actionCollection()->action("close_tab")->setEnabled(enableTabActions);
actionCollection()->action("activate_next_tab")->setEnabled(enableTabActions);
actionCollection()->action("activate_prev_tab")->setEnabled(enableTabActions);
}
void DolphinMainWindow::setUrlAsCaption(const KUrl& url)
{
QString caption;
if (!url.isLocalFile()) {
caption.append(url.protocol() + " - ");
if (url.hasHost()) {
caption.append(url.host() + " - ");
}
}
const QString fileName = url.fileName().isEmpty() ? "/" : url.fileName();
caption.append(fileName);
setCaption(caption);
}
void DolphinMainWindow::setupActions()
{
// setup 'File' menu
@ -1275,14 +997,14 @@ void DolphinMainWindow::setupActions()
newTab->setIcon(QIcon::fromTheme("tab-new"));
newTab->setText(i18nc("@action:inmenu File", "New Tab"));
newTab->setShortcuts(QList<QKeySequence>() << QKeySequence(Qt::CTRL | Qt::Key_T) << QKeySequence(Qt::CTRL | Qt::SHIFT | Qt::Key_N));
connect(newTab, &QAction::triggered, this, static_cast<void(DolphinMainWindow::*)()>(&DolphinMainWindow::openNewTab));
connect(newTab, &QAction::triggered, this, static_cast<void(DolphinMainWindow::*)()>(&DolphinMainWindow::openNewActivatedTab));
QAction* closeTab = actionCollection()->addAction("close_tab");
closeTab->setIcon(QIcon::fromTheme("tab-close"));
closeTab->setText(i18nc("@action:inmenu File", "Close Tab"));
closeTab->setShortcut(Qt::CTRL | Qt::Key_W);
closeTab->setEnabled(false);
connect(closeTab, &QAction::triggered, this, static_cast<void(DolphinMainWindow::*)()>(&DolphinMainWindow::closeTab));
connect(closeTab, &QAction::triggered, m_tabWidget, static_cast<void(DolphinTabWidget::*)()>(&DolphinTabWidget::closeTab));
KStandardAction::quit(this, SLOT(quit()), actionCollection());
@ -1353,10 +1075,10 @@ void DolphinMainWindow::setupActions()
DolphinRecentTabsMenu* recentTabsMenu = new DolphinRecentTabsMenu(this);
actionCollection()->addAction("closed_tabs", recentTabsMenu);
connect(this, SIGNAL(rememberClosedTab(KUrl,KUrl)),
recentTabsMenu, SLOT(rememberClosedTab(KUrl,KUrl)));
connect(recentTabsMenu, SIGNAL(restoreClosedTab(KUrl,KUrl)),
this, SLOT(openNewActivatedTab(KUrl,KUrl)));
connect(m_tabWidget, SIGNAL(rememberClosedTab(KUrl,QByteArray)),
recentTabsMenu, SLOT(rememberClosedTab(KUrl,QByteArray)));
connect(recentTabsMenu, SIGNAL(restoreClosedTab(QByteArray)),
m_tabWidget, SLOT(restoreClosedTab(QByteArray)));
connect(recentTabsMenu, SIGNAL(closedTabsCountChanged(uint)),
this, SLOT(closedTabsCountChanged(uint)));
@ -1409,14 +1131,14 @@ void DolphinMainWindow::setupActions()
activateNextTab->setIconText(i18nc("@action:inmenu", "Next Tab"));
activateNextTab->setText(i18nc("@action:inmenu", "Activate Next Tab"));
activateNextTab->setEnabled(false);
connect(activateNextTab, &QAction::triggered, this, &DolphinMainWindow::activateNextTab);
connect(activateNextTab, &QAction::triggered, m_tabWidget, &DolphinTabWidget::activateNextTab);
activateNextTab->setShortcuts(QApplication::isRightToLeft() ? prevTabKeys : nextTabKeys);
QAction* activatePrevTab = actionCollection()->addAction("activate_prev_tab");
activatePrevTab->setIconText(i18nc("@action:inmenu", "Previous Tab"));
activatePrevTab->setText(i18nc("@action:inmenu", "Activate Previous Tab"));
activatePrevTab->setEnabled(false);
connect(activatePrevTab, &QAction::triggered, this, &DolphinMainWindow::activatePrevTab);
connect(activatePrevTab, &QAction::triggered, m_tabWidget, &DolphinTabWidget::activatePrevTab);
activatePrevTab->setShortcuts(QApplication::isRightToLeft() ? nextTabKeys : prevTabKeys);
// for context menu
@ -1545,10 +1267,12 @@ void DolphinMainWindow::setupDockWidgets()
connect(this, &DolphinMainWindow::urlChanged,
placesPanel, &PlacesPanel::setUrl);
connect(placesDock, &DolphinDockWidget::visibilityChanged,
this, &DolphinMainWindow::slotPlacesPanelVisibilityChanged);
m_tabWidget, &DolphinTabWidget::slotPlacesPanelVisibilityChanged);
connect(this, &DolphinMainWindow::settingsChanged,
placesPanel, &PlacesPanel::readSettings);
m_tabWidget->slotPlacesPanelVisibilityChanged(placesPanel->isVisible());
// Add actions into the "Panels" menu
KActionMenu* panelsMenu = new KActionMenu(i18nc("@action:inmenu View", "Panels"), this);
actionCollection()->addAction("panels", panelsMenu);
@ -1671,15 +1395,13 @@ bool DolphinMainWindow::addActionToMenu(QAction* action, KMenu* menu)
void DolphinMainWindow::refreshViews()
{
foreach (DolphinTabPage* tabPage, m_viewTab) {
tabPage->refreshViews();
}
m_tabWidget->refreshViews();
if (GeneralSettings::modifiedStartupSettings()) {
// The startup settings have been changed by the user (see bug #254947).
// Synchronize the split-view setting with the active view:
const bool splitView = GeneralSettings::splitView();
m_viewTab.at(m_tabIndex)->setSplitViewEnabled(splitView);
m_tabWidget->currentTabPage()->setSplitViewEnabled(splitView);
updateSplitAction();
}
@ -1730,7 +1452,7 @@ void DolphinMainWindow::connectViewSignals(DolphinViewContainer* container)
void DolphinMainWindow::updateSplitAction()
{
QAction* splitAction = actionCollection()->action("split_view");
const DolphinTabPage* tabPage = m_viewTab.at(m_tabIndex);
const DolphinTabPage* tabPage = m_tabWidget->currentTabPage();
if (tabPage->splitViewEnabled()) {
if (tabPage->primaryViewActive()) {
splitAction->setText(i18nc("@action:intoolbar Close left view", "Close"));
@ -1748,24 +1470,6 @@ void DolphinMainWindow::updateSplitAction()
}
}
QString DolphinMainWindow::tabName(const KUrl& url) const
{
QString name;
if (url.equals(KUrl("file:///"))) {
name = '/';
} else {
name = url.fileName();
if (name.isEmpty()) {
name = url.protocol();
} else {
// Make sure that a '&' inside the directory name is displayed correctly
// and not misinterpreted as a keyboard shortcut in QTabBar::setTabText()
name.replace('&', "&&");
}
}
return name;
}
bool DolphinMainWindow::isKompareInstalled() const
{
static bool initialized = false;
@ -1779,28 +1483,6 @@ bool DolphinMainWindow::isKompareInstalled() const
return installed;
}
void DolphinMainWindow::setUrlAsCaption(const KUrl& url)
{
QString caption;
if (!url.isLocalFile()) {
caption.append(url.protocol() + " - ");
if (url.hasHost()) {
caption.append(url.host() + " - ");
}
}
const QString fileName = url.fileName().isEmpty() ? "/" : url.fileName();
caption.append(fileName);
setCaption(caption);
}
QString DolphinMainWindow::squeezedText(const QString& text) const
{
const QFontMetrics fm = fontMetrics();
return fm.elidedText(text, Qt::ElideMiddle, fm.maxWidth() * 10);
}
void DolphinMainWindow::createPanelAction(const QIcon& icon,
const QKeySequence& shortcut,
QAction* dockAction,

View file

@ -39,17 +39,14 @@ typedef KIO::FileUndoManager::CommandType CommandType;
class DolphinViewActionHandler;
class DolphinApplication;
class DolphinSettingsDialog;
class DolphinTabBar;
class DolphinViewContainer;
class DolphinRemoteEncoding;
class DolphinTabPage;
class DolphinTabWidget;
class KFileItem;
class KFileItemList;
class KJob;
class KNewFileMenu;
class QSplitter;
class QToolButton;
class QVBoxLayout;
class QIcon;
/**
@ -149,11 +146,6 @@ signals:
*/
void settingsChanged();
/**
* Is emitted when a tab has been closed.
*/
void rememberClosedTab(const KUrl& primaryUrl, const KUrl& secondaryUrl);
protected:
/** @see QWidget::showEvent() */
virtual void showEvent(QShowEvent* event);
@ -262,13 +254,6 @@ private slots:
*/
void togglePanelLockState();
/**
* Is invoked if the Places panel got visible/invisible and takes care
* that the places-selector of all views is only shown if the Places panel
* is invisible.
*/
void slotPlacesPanelVisibilityChanged(bool visible);
/** Goes back one step of the URL history. */
void goBack();
@ -343,8 +328,11 @@ private slots:
/** Open a new main window. */
void openNewMainWindow();
/** Opens a new view with the current URL that is part of a tab. */
void openNewTab();
/**
* Opens a new view with the current URL that is part of a tab and
* activates it.
*/
void openNewActivatedTab();
/**
* Opens a new tab in the background showing the URL \a primaryUrl and the
@ -358,16 +346,6 @@ private slots:
*/
void openNewActivatedTab(const KUrl& primaryUrl, const KUrl& secondaryUrl = KUrl());
/**
* Opens a new tab showing the url from tab at the given \a index and
* activates the tab.
*/
void openNewActivatedTab(int index);
void activateNextTab();
void activatePrevTab();
/**
* Opens the selected folder in a new tab.
*/
@ -384,33 +362,6 @@ private slots:
*/
void showCommand(CommandType command);
/**
* Activates the tab with the index \a index, which means that the current view
* is replaced by the view of the given tab.
*/
void setActiveTab(int index);
/** Closes the currently active tab. */
void closeTab();
/**
* Closes the tab with the index \a index and activates the tab with index - 1.
*/
void closeTab(int index);
/**
* Opens the tab with the index \a index in a new Dolphin instance and closes
* this tab.
*/
void detachTab(int index);
/**
* Is connected to the QTabBar signal tabMoved(int from, int to).
* Reorders the list of tabs after a tab was moved in the tab bar
* and sets m_tabIndex to the new index of the current tab.
*/
void slotTabMoved(int from, int to);
/**
* If the URL can be listed, open it in the current view, otherwise
* run it through KRun.
@ -423,12 +374,6 @@ private slots:
*/
void slotHandleUrlStatFinished(KJob* job);
/**
* Is connected to the KTabBar signal receivedDropEvent.
* Allows dragging and dropping files onto tabs.
*/
void tabDropEvent(int tab, QDropEvent* event);
/**
* Is invoked when the write state of a folder has been changed and
* enables/disables the "Create New..." menu entry.
@ -466,19 +411,31 @@ private slots:
*/
void slotPlaceActivated(const KUrl& url);
void activeViewChanged();
/**
* Is called if the another view has been activated by changing the current
* tab or activating another view in split-view mode.
*
* Activates the given view, which means that all menu actions are applied
* to this view. When having a split view setup, the nonactive view is
* usually shown in darker colors.
*/
void activeViewChanged(DolphinViewContainer* viewContainer);
void closedTabsCountChanged(unsigned int count);
private:
/**
* Activates the given view, which means that
* all menu actions are applied to this view. When
* having a split view setup, the nonactive view
* is usually shown in darker colors.
* Is called if a new tab has been opened or a tab has been closed to
* enable/disable the tab actions.
*/
void setActiveViewContainer(DolphinViewContainer* view);
void tabCountChanged(int count);
/**
* Sets the window caption to url.fileName() if this is non-empty,
* "/" if the URL is "file:///", and url.protocol() otherwise.
*/
void setUrlAsCaption(const KUrl& url);
private:
void setupActions();
void setupDockWidgets();
void updateEditActions();
@ -511,20 +468,8 @@ private:
*/
void updateSplitAction();
/** Returns the name of the tab for the URL \a url. */
QString tabName(const KUrl& url) const;
bool isKompareInstalled() const;
/**
* Sets the window caption to url.fileName() if this is non-empty,
* "/" if the URL is "file:///", and url.protocol() otherwise.
*/
void setUrlAsCaption(const KUrl& url);
QString squeezedText(const QString& text) const;
/**
* Creates an action for showing/hiding a panel, that is accessible
* in "Configure toolbars..." and "Configure shortcuts...". This is necessary
@ -551,14 +496,10 @@ private:
};
KNewFileMenu* m_newFileMenu;
DolphinTabBar* m_tabBar;
DolphinTabWidget* m_tabWidget;
DolphinViewContainer* m_activeViewContainer;
QVBoxLayout* m_centralWidgetLayout;
int m_id;
int m_tabIndex;
QList<DolphinTabPage*> m_viewTab;
DolphinViewActionHandler* m_actionHandler;
DolphinRemoteEncoding* m_remoteEncoding;
QWeakPointer<DolphinSettingsDialog> m_settingsDialog;

View file

@ -21,7 +21,7 @@
#include <KLocalizedString>
#include <KAcceleratorManager>
#include <KMimeType>
#include <kio/global.h>
#include <KMenu>
DolphinRecentTabsMenu::DolphinRecentTabsMenu(QObject* parent) :
@ -40,19 +40,14 @@ DolphinRecentTabsMenu::DolphinRecentTabsMenu(QObject* parent) :
this, SLOT(handleAction(QAction*)));
}
void DolphinRecentTabsMenu::rememberClosedTab(const KUrl& primaryUrl, const KUrl& secondaryUrl)
void DolphinRecentTabsMenu::rememberClosedTab(const KUrl& url, const QByteArray& state)
{
QAction* action = new QAction(menu());
action->setText(primaryUrl.path());
const QString iconName = KMimeType::iconNameForUrl(primaryUrl);
action->setText(url.path());
action->setData(state);
const QString iconName = KIO::iconNameForUrl(url);
action->setIcon(QIcon::fromTheme(iconName));
KUrl::List urls;
urls << primaryUrl;
urls << secondaryUrl;
action->setData(QVariant::fromValue(urls));
// Add the closed tab menu entry after the separator and
// "Empty Recently Closed Tabs" entry
if (menu()->actions().size() == 2) {
@ -88,13 +83,11 @@ void DolphinRecentTabsMenu::handleAction(QAction* action)
}
emit closedTabsCountChanged(0);
} else {
const KUrl::List urls = action->data().value<KUrl::List>();
const QByteArray state = action->data().value<QByteArray>();
removeAction(action);
delete action;
action = 0;
if (urls.count() == 2) {
emit restoreClosedTab(urls.first(), urls.last());
}
emit restoreClosedTab(state);
emit closedTabsCountChanged(menu()->actions().size() - 2);
}

View file

@ -34,11 +34,11 @@ public:
explicit DolphinRecentTabsMenu(QObject* parent);
public slots:
void rememberClosedTab(const KUrl& primaryUrl, const KUrl& secondaryUrl);
void rememberClosedTab(const KUrl& url, const QByteArray& state);
void undoCloseTab();
signals:
void restoreClosedTab(const KUrl& primaryUrl, const KUrl& secondaryUrl);
void restoreClosedTab(const QByteArray& state);
void closedTabsCountChanged(unsigned int count);
private slots:

View file

@ -41,6 +41,8 @@ DolphinTabPage::DolphinTabPage(const KUrl& primaryUrl, const KUrl& secondaryUrl,
m_primaryViewContainer = createViewContainer(primaryUrl);
connect(m_primaryViewContainer->view(), SIGNAL(urlChanged(KUrl)),
this, SIGNAL(activeViewUrlChanged(KUrl)));
connect(m_primaryViewContainer->view(), SIGNAL(redirection(KUrl,KUrl)),
this, SLOT(slotViewUrlRedirection(KUrl,KUrl)));
m_splitter->addWidget(m_primaryViewContainer);
m_primaryViewContainer->show();
@ -169,14 +171,18 @@ QByteArray DolphinTabPage::saveState() const
QByteArray state;
QDataStream stream(&state, QIODevice::WriteOnly);
stream << quint32(2); // Tab state version
stream << m_splitViewEnabled;
stream << m_primaryViewContainer->url();
stream << m_primaryViewContainer->urlNavigator()->isUrlEditable();
m_primaryViewContainer->view()->saveState(stream);
if (m_splitViewEnabled) {
stream << m_secondaryViewContainer->url();
stream << m_secondaryViewContainer->urlNavigator()->isUrlEditable();
m_secondaryViewContainer->view()->saveState(stream);
}
stream << m_primaryViewActive;
@ -187,6 +193,62 @@ QByteArray DolphinTabPage::saveState() const
void DolphinTabPage::restoreState(const QByteArray& state)
{
if (state.isEmpty()) {
return;
}
QByteArray sd = state;
QDataStream stream(&sd, QIODevice::ReadOnly);
// Read the version number of the tab state and check if the version is supported.
quint32 version = 0;
stream >> version;
if (version != 2) {
// The version of the tab state isn't supported, we can't restore it.
return;
}
bool isSplitViewEnabled = false;
stream >> isSplitViewEnabled;
setSplitViewEnabled(isSplitViewEnabled);
KUrl primaryUrl;
stream >> primaryUrl;
m_primaryViewContainer->setUrl(primaryUrl);
bool primaryUrlEditable;
stream >> primaryUrlEditable;
m_primaryViewContainer->urlNavigator()->setUrlEditable(primaryUrlEditable);
m_primaryViewContainer->view()->restoreState(stream);
if (isSplitViewEnabled) {
KUrl secondaryUrl;
stream >> secondaryUrl;
m_secondaryViewContainer->setUrl(secondaryUrl);
bool secondaryUrlEditable;
stream >> secondaryUrlEditable;
m_secondaryViewContainer->urlNavigator()->setUrlEditable(secondaryUrlEditable);
m_secondaryViewContainer->view()->restoreState(stream);
}
stream >> m_primaryViewActive;
if (m_primaryViewActive) {
m_primaryViewContainer->setActive(true);
} else {
Q_ASSERT(m_splitViewEnabled);
m_secondaryViewContainer->setActive(true);
}
QByteArray splitterState;
stream >> splitterState;
m_splitter->restoreState(splitterState);
}
void DolphinTabPage::restoreStateV1(const QByteArray& state)
{
if (state.isEmpty()) {
return;
}
QByteArray sd = state;
QDataStream stream(&sd, QIODevice::ReadOnly);
@ -241,12 +303,23 @@ void DolphinTabPage::slotViewActivated()
if (newActiveView != oldActiveView) {
disconnect(oldActiveView, SIGNAL(urlChanged(KUrl)),
this, SIGNAL(activeViewUrlChanged(KUrl)));
disconnect(oldActiveView, SIGNAL(redirection(KUrl,KUrl)),
this, SLOT(slotViewUrlRedirection(KUrl,KUrl)));
connect(newActiveView, SIGNAL(urlChanged(KUrl)),
this, SIGNAL(activeViewUrlChanged(KUrl)));
connect(newActiveView, SIGNAL(redirection(KUrl,KUrl)),
this, SLOT(slotViewUrlRedirection(KUrl,KUrl)));
}
emit activeViewUrlChanged(activeViewContainer()->url());
emit activeViewChanged();
emit activeViewChanged(activeViewContainer());
}
void DolphinTabPage::slotViewUrlRedirection(const KUrl& oldUrl, const KUrl& newUrl)
{
Q_UNUSED(oldUrl);
emit activeViewUrlChanged(newUrl);
}
DolphinViewContainer* DolphinTabPage::createViewContainer(const KUrl& url) const

View file

@ -120,8 +120,17 @@ public:
*/
void restoreState(const QByteArray& state);
/**
* Restores all tab related properties (urls, splitter layout, ...) from
* the given \a state.
*
* @deprecated The first tab state version has no version number, we keep
* this method to restore old states (<= Dolphin 4.14.x).
*/
void restoreStateV1(const QByteArray& state);
signals:
void activeViewChanged();
void activeViewChanged(DolphinViewContainer* viewContainer);
void activeViewUrlChanged(const KUrl& url);
private slots:
@ -133,6 +142,13 @@ private slots:
*/
void slotViewActivated();
/**
* Handles the view url redirection event.
*
* It emits the activeViewUrlChanged signal with the url \a newUrl.
*/
void slotViewUrlRedirection(const KUrl& oldUrl, const KUrl& newUrl);
private:
/**
* Creates a new view container and does the default initialization.

360
src/dolphintabwidget.cpp Normal file
View file

@ -0,0 +1,360 @@
/***************************************************************************
* Copyright (C) 2014 by Emmanuel Pescosta <emmanuelpescosta099@gmail.com> *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA *
***************************************************************************/
#include "dolphintabwidget.h"
#include "dolphintabbar.h"
#include "dolphintabpage.h"
#include "dolphinviewcontainer.h"
#include "dolphin_generalsettings.h"
#include "views/draganddrophelper.h"
#include <QApplication>
#include <KConfigGroup>
#include <kio/global.h>
#include <KRun>
DolphinTabWidget::DolphinTabWidget(QWidget* parent) :
QTabWidget(parent),
m_placesSelectorVisible(true)
{
connect(this, SIGNAL(tabCloseRequested(int)),
this, SLOT(closeTab(int)));
connect(this, SIGNAL(currentChanged(int)),
this, SLOT(currentTabChanged(int)));
DolphinTabBar* tabBar = new DolphinTabBar(this);
connect(tabBar, SIGNAL(openNewActivatedTab(int)),
this, SLOT(openNewActivatedTab(int)));
connect(tabBar, SIGNAL(tabDropEvent(int,QDropEvent*)),
this, SLOT(tabDropEvent(int,QDropEvent*)));
connect(tabBar, SIGNAL(tabDetachRequested(int)),
this, SLOT(detachTab(int)));
tabBar->hide();
setTabBar(tabBar);
setDocumentMode(true);
setElideMode(Qt::ElideRight);
setUsesScrollButtons(true);
}
DolphinTabPage* DolphinTabWidget::currentTabPage() const
{
return tabPageAt(currentIndex());
}
DolphinTabPage* DolphinTabWidget::tabPageAt(const int index) const
{
return static_cast<DolphinTabPage*>(widget(index));
}
void DolphinTabWidget::saveProperties(KConfigGroup& group) const
{
const int tabCount = count();
group.writeEntry("Tab Count", tabCount);
group.writeEntry("Active Tab Index", currentIndex());
for (int i = 0; i < tabCount; ++i) {
const DolphinTabPage* tabPage = tabPageAt(i);
group.writeEntry("Tab Data " % QString::number(i), tabPage->saveState());
}
}
void DolphinTabWidget::readProperties(const KConfigGroup& group)
{
const int tabCount = group.readEntry("Tab Count", 0);
for (int i = 0; i < tabCount; ++i) {
if (i >= count()) {
openNewActivatedTab();
}
if (group.hasKey("Tab Data " % QString::number(i))) {
// Tab state created with Dolphin > 4.14.x
const QByteArray state = group.readEntry("Tab Data " % QString::number(i), QByteArray());
tabPageAt(i)->restoreState(state);
} else {
// Tab state created with Dolphin <= 4.14.x
const QByteArray state = group.readEntry("Tab " % QString::number(i), QByteArray());
tabPageAt(i)->restoreStateV1(state);
}
}
const int index = group.readEntry("Active Tab Index", 0);
setCurrentIndex(index);
}
void DolphinTabWidget::refreshViews()
{
const int tabCount = count();
for (int i = 0; i < tabCount; ++i) {
tabPageAt(i)->refreshViews();
}
}
void DolphinTabWidget::openNewActivatedTab()
{
const DolphinViewContainer* oldActiveViewContainer = currentTabPage()->activeViewContainer();
Q_ASSERT(oldActiveViewContainer);
const bool isUrlEditable = oldActiveViewContainer->urlNavigator()->isUrlEditable();
openNewActivatedTab(oldActiveViewContainer->url());
DolphinViewContainer* newActiveViewContainer = currentTabPage()->activeViewContainer();
Q_ASSERT(newActiveViewContainer);
// The URL navigator of the new tab should have the same editable state
// as the current tab
KUrlNavigator* navigator = newActiveViewContainer->urlNavigator();
navigator->setUrlEditable(isUrlEditable);
if (isUrlEditable) {
// If a new tab is opened and the URL is editable, assure that
// the user can edit the URL without manually setting the focus
navigator->setFocus();
}
}
void DolphinTabWidget::openNewActivatedTab(const KUrl& primaryUrl, const KUrl& secondaryUrl)
{
openNewTab(primaryUrl, secondaryUrl);
setCurrentIndex(count() - 1);
}
void DolphinTabWidget::openNewTab(const KUrl& primaryUrl, const KUrl& secondaryUrl)
{
QWidget* focusWidget = QApplication::focusWidget();
DolphinTabPage* tabPage = new DolphinTabPage(primaryUrl, secondaryUrl, this);
tabPage->setPlacesSelectorVisible(m_placesSelectorVisible);
connect(tabPage, SIGNAL(activeViewChanged(DolphinViewContainer*)),
this, SIGNAL(activeViewChanged(DolphinViewContainer*)));
connect(tabPage, SIGNAL(activeViewUrlChanged(KUrl)),
this, SLOT(tabUrlChanged(KUrl)));
addTab(tabPage, QIcon::fromTheme(KIO::iconNameForUrl(primaryUrl)), tabName(primaryUrl));
if (focusWidget) {
// The DolphinViewContainer grabbed the keyboard focus. As the tab is opened
// in background, assure that the previous focused widget gets the focus back.
focusWidget->setFocus();
}
}
void DolphinTabWidget::openDirectories(const QList<KUrl>& dirs)
{
const bool hasSplitView = GeneralSettings::splitView();
// Open each directory inside a new tab. If the "split view" option has been enabled,
// always show two directories within one tab.
QList<KUrl>::const_iterator it = dirs.constBegin();
while (it != dirs.constEnd()) {
const KUrl& primaryUrl = *(it++);
if (hasSplitView && (it != dirs.constEnd())) {
const KUrl& secondaryUrl = *(it++);
openNewTab(primaryUrl, secondaryUrl);
} else {
openNewTab(primaryUrl);
}
}
}
void DolphinTabWidget::openFiles(const QList<KUrl>& files)
{
if (files.isEmpty()) {
return;
}
// Get all distinct directories from 'files' and open a tab
// for each directory. If the "split view" option is enabled, two
// directories are shown inside one tab (see openDirectories()).
QList<KUrl> dirs;
foreach (const KUrl& url, files) {
const KUrl dir(url.directory());
if (!dirs.contains(dir)) {
dirs.append(dir);
}
}
const int oldTabCount = count();
openDirectories(dirs);
const int tabCount = count();
// Select the files. Although the files can be split between several
// tabs, there is no need to split 'files' accordingly, as
// the DolphinView will just ignore invalid selections.
for (int i = oldTabCount; i < tabCount; ++i) {
DolphinTabPage* tabPage = tabPageAt(i);
tabPage->markUrlsAsSelected(files);
tabPage->markUrlAsCurrent(files.first());
}
}
void DolphinTabWidget::closeTab()
{
closeTab(currentIndex());
}
void DolphinTabWidget::closeTab(const int index)
{
Q_ASSERT(index >= 0);
Q_ASSERT(index < count());
if (count() < 2) {
// Never close the last tab.
return;
}
DolphinTabPage* tabPage = tabPageAt(index);
emit rememberClosedTab(tabPage->activeViewContainer()->url(), tabPage->saveState());
removeTab(index);
tabPage->deleteLater();
}
void DolphinTabWidget::activateNextTab()
{
const int index = currentIndex() + 1;
setCurrentIndex(index < count() ? index : 0);
}
void DolphinTabWidget::activatePrevTab()
{
const int index = currentIndex() - 1;
setCurrentIndex(index >= 0 ? index : (count() - 1));
}
void DolphinTabWidget::slotPlacesPanelVisibilityChanged(bool visible)
{
// The places-selector from the URL navigator should only be shown
// if the places dock is invisible
m_placesSelectorVisible = !visible;
const int tabCount = count();
for (int i = 0; i < tabCount; ++i) {
DolphinTabPage* tabPage = tabPageAt(i);
tabPage->setPlacesSelectorVisible(m_placesSelectorVisible);
}
}
void DolphinTabWidget::restoreClosedTab(const QByteArray& state)
{
openNewActivatedTab();
currentTabPage()->restoreState(state);
}
void DolphinTabWidget::detachTab(int index)
{
Q_ASSERT(index >= 0);
const QString separator(QLatin1Char(' '));
QString command = QLatin1String("dolphin");
const DolphinTabPage* tabPage = tabPageAt(index);
command += separator + tabPage->primaryViewContainer()->url().url();
if (tabPage->splitViewEnabled()) {
command += separator + tabPage->secondaryViewContainer()->url().url();
command += separator + QLatin1String("-split");
}
KRun::runCommand(command, this);
closeTab(index);
}
void DolphinTabWidget::openNewActivatedTab(int index)
{
Q_ASSERT(index >= 0);
const DolphinTabPage* tabPage = tabPageAt(index);
openNewActivatedTab(tabPage->activeViewContainer()->url());
}
void DolphinTabWidget::tabDropEvent(int index, QDropEvent* event)
{
if (index >= 0) {
const DolphinView* view = tabPageAt(index)->activeViewContainer()->view();
QString error;
DragAndDropHelper::dropUrls(view->rootItem(), view->url(), event, error);
if (!error.isEmpty()) {
currentTabPage()->activeViewContainer()->showMessage(error, DolphinViewContainer::Error);
}
}
}
void DolphinTabWidget::tabUrlChanged(const KUrl& url)
{
const int index = indexOf(qobject_cast<QWidget*>(sender()));
if (index >= 0) {
tabBar()->setTabText(index, tabName(url));
tabBar()->setTabIcon(index, QIcon::fromTheme(KIO::iconNameForUrl(url)));
// Emit the currentUrlChanged signal if the url of the current tab has been changed.
if (index == currentIndex()) {
emit currentUrlChanged(url);
}
}
}
void DolphinTabWidget::currentTabChanged(int index)
{
DolphinViewContainer* viewContainer = tabPageAt(index)->activeViewContainer();
emit activeViewChanged(viewContainer);
emit currentUrlChanged(viewContainer->url());
}
void DolphinTabWidget::tabInserted(int index)
{
QTabWidget::tabInserted(index);
if (count() > 1) {
tabBar()->show();
}
emit tabCountChanged(count());
}
void DolphinTabWidget::tabRemoved(int index)
{
QTabWidget::tabRemoved(index);
// If only one tab is left, then remove the tab entry so that
// closing the last tab is not possible.
if (count() < 2) {
tabBar()->hide();
}
emit tabCountChanged(count());
}
QString DolphinTabWidget::tabName(const KUrl& url) const
{
QString name;
if (url.equals(KUrl("file:///"))) {
name = '/';
} else {
name = url.fileName();
if (name.isEmpty()) {
name = url.protocol();
} else {
// Make sure that a '&' inside the directory name is displayed correctly
// and not misinterpreted as a keyboard shortcut in QTabBar::setTabText()
name.replace('&', "&&");
}
}
return name;
}

190
src/dolphintabwidget.h Normal file
View file

@ -0,0 +1,190 @@
/***************************************************************************
* Copyright (C) 2014 by Emmanuel Pescosta <emmanuelpescosta099@gmail.com> *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA *
***************************************************************************/
#ifndef DOLPHIN_TAB_WIDGET_H
#define DOLPHIN_TAB_WIDGET_H
#include <QTabWidget>
#include <KUrl>
class DolphinViewContainer;
class DolphinTabPage;
class KConfigGroup;
class DolphinTabWidget : public QTabWidget
{
Q_OBJECT
public:
explicit DolphinTabWidget(QWidget* parent);
/**
* @return Tab page at the current index (can be 0 if tabs count is smaller than 1)
*/
DolphinTabPage* currentTabPage() const;
/**
* @return Tab page at the given \a index (can be 0 if the index is out-of-range)
*/
DolphinTabPage* tabPageAt(const int index) const;
void saveProperties(KConfigGroup& group) const;
void readProperties(const KConfigGroup& group);
/**
* Refreshes the views of the main window by recreating them according to
* the given Dolphin settings.
*/
void refreshViews();
signals:
/**
* Is emitted when the active view has been changed, by changing the current
* tab or by activating another view when split view is enabled in the current
* tab.
*/
void activeViewChanged(DolphinViewContainer* viewContainer);
/**
* Is emitted when the number of open tabs has changed (e.g. by opening or
* closing a tab)
*/
void tabCountChanged(int count);
/**
* Is emitted when a tab has been closed.
*/
void rememberClosedTab(const KUrl& url, const QByteArray& state);
/**
* Is emitted when the url of the current tab has been changed. This signal
* is also emitted when the active view has been changed.
*/
void currentUrlChanged(const KUrl& url);
public slots:
/**
* Opens a new view with the current URL that is part of a tab and activates
* the tab.
*/
void openNewActivatedTab();
/**
* Opens a new tab showing the URL \a primaryUrl and the optional URL
* \a secondaryUrl and activates the tab.
*/
void openNewActivatedTab(const KUrl& primaryUrl, const KUrl& secondaryUrl = KUrl());
/**
* Opens a new tab in the background showing the URL \a primaryUrl and the
* optional URL \a secondaryUrl.
*/
void openNewTab(const KUrl& primaryUrl, const KUrl& secondaryUrl = KUrl());
/**
* Opens each directory in \p dirs in a separate tab. If the "split view"
* option is enabled, 2 directories are collected within one tab.
*/
void openDirectories(const QList<KUrl>& dirs);
/**
* Opens the directory which contains the files \p files
* and selects all files (implements the --select option
* of Dolphin).
*/
void openFiles(const QList<KUrl>& files);
/**
* Closes the currently active tab.
*/
void closeTab();
/**
* Closes the tab with the index \a index and activates the tab with index - 1.
*/
void closeTab(const int index);
/**
* Activates the next tab in the tab bar.
* If the current active tab is the last tab, it activates the first tab.
*/
void activateNextTab();
/**
* Activates the previous tab in the tab bar.
* If the current active tab is the first tab, it activates the last tab.
*/
void activatePrevTab();
/**
* Is invoked if the Places panel got visible/invisible and takes care
* that the places-selector of all views is only shown if the Places panel
* is invisible.
*/
void slotPlacesPanelVisibilityChanged(bool visible);
/**
* Is called when the user wants to reopen a previously closed tab from
* the recent tabs menu.
*/
void restoreClosedTab(const QByteArray& state);
private slots:
/**
* Opens the tab with the index \a index in a new Dolphin instance and closes
* this tab.
*/
void detachTab(int index);
/**
* Opens a new tab showing the url from tab at the given \a index and
* activates the tab.
*/
void openNewActivatedTab(int index);
/**
* Is connected to the KTabBar signal receivedDropEvent.
* Allows dragging and dropping files onto tabs.
*/
void tabDropEvent(int tab, QDropEvent* event);
/**
* The active view url of a tab has been changed so update the text and the
* icon of the corresponding tab.
*/
void tabUrlChanged(const KUrl& url);
void currentTabChanged(int index);
protected:
virtual void tabInserted(int index);
virtual void tabRemoved(int index);
private:
/**
* Returns the name of the tab for the URL \a url.
*/
QString tabName(const KUrl& url) const;
private:
/** Caches the (negated) places panel visibility */
bool m_placesSelectorVisible;
};
#endif

View file

@ -112,6 +112,8 @@ DolphinViewContainer::DolphinViewContainer(const KUrl& url, QWidget* parent) :
m_urlNavigator, &KUrlNavigator::setUrl);
connect(m_view, &DolphinView::urlChanged,
m_messageWidget, &KMessageWidget::hide);
connect(m_view, &DolphinView::directoryLoadingCompleted,
m_messageWidget, &KMessageWidget::hide);
connect(m_view, &DolphinView::writeStateChanged,
this, &DolphinViewContainer::writeStateChanged);
connect(m_view, &DolphinView::requestItemInfo,
@ -301,6 +303,9 @@ void DolphinViewContainer::showMessage(const QString& msg, MessageType type)
const int unwrappedWidth = m_messageWidget->sizeHint().width();
m_messageWidget->setWordWrap(unwrappedWidth > size().width());
if (m_messageWidget->isVisible()) {
m_messageWidget->hide();
}
m_messageWidget->animatedShow();
}

View file

@ -1136,14 +1136,24 @@ void KStandardItemListWidget::updateIconsLayoutTextCache()
const int textLength = line.textStart() + line.textLength();
if (textLength < nameText.length()) {
// Elide the last line of the text
QString lastTextLine = nameText.mid(line.textStart());
lastTextLine = m_customizedFontMetrics.elidedText(lastTextLine,
Qt::ElideRight,
maxWidth);
const QString elidedText = nameText.left(line.textStart()) + lastTextLine;
nameTextInfo->staticText.setText(elidedText);
qreal elidingWidth = maxWidth;
qreal lastLineWidth;
do {
QString lastTextLine = nameText.mid(line.textStart());
lastTextLine = m_customizedFontMetrics.elidedText(lastTextLine,
Qt::ElideRight,
elidingWidth);
const QString elidedText = nameText.left(line.textStart()) + lastTextLine;
nameTextInfo->staticText.setText(elidedText);
lastLineWidth = m_customizedFontMetrics.boundingRect(lastTextLine).width();
// We do the text eliding in a loop with decreasing width (1 px / iteration)
// to avoid problems related to different width calculation code paths
// within Qt. (see bug 337104)
elidingWidth -= 1.0;
} while (lastLineWidth > maxWidth);
const qreal lastLineWidth = m_customizedFontMetrics.boundingRect(lastTextLine).width();
nameWidth = qMax(nameWidth, lastLineWidth);
}
break;

View file

@ -109,18 +109,19 @@ DolphinStatusBar::DolphinStatusBar(QWidget* parent) :
const int zoomSliderHeight = m_zoomSlider->minimumSizeHint().height();
const int contentHeight = qMax(fontHeight, zoomSliderHeight);
QFontMetrics fontMetrics(m_label->font());
m_label->setFixedHeight(contentHeight);
m_label->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
m_zoomSlider->setFixedHeight(contentHeight);
m_zoomSlider->setMaximumWidth(150);
m_zoomSlider->setMaximumWidth(fontMetrics.averageCharWidth() * 15);
m_spaceInfo->setFixedHeight(contentHeight);
m_spaceInfo->setMaximumWidth(150);
m_spaceInfo->setMaximumWidth(fontMetrics.averageCharWidth() * 15);
m_spaceInfo->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
m_progressBar->setFixedHeight(contentHeight);
m_progressBar->setMaximumWidth(150);
m_progressBar->setMaximumWidth(fontMetrics.averageCharWidth() * 15);
QHBoxLayout* topLayout = new QHBoxLayout(this);
topLayout->setMargin(0);

View file

@ -1176,6 +1176,14 @@ bool DolphinView::itemsExpandable() const
void DolphinView::restoreState(QDataStream& stream)
{
// Read the version number of the view state and check if the version is supported.
quint32 version = 0;
stream >> version;
if (version != 1) {
// The version of the view state isn't supported, we can't restore it.
return;
}
// Restore the current item that had the keyboard focus
stream >> m_currentItemUrl;
@ -1190,6 +1198,8 @@ void DolphinView::restoreState(QDataStream& stream)
void DolphinView::saveState(QDataStream& stream)
{
stream << quint32(1); // View state version
// Save the current item that has the keyboard focus
const int currentIndex = m_container->controller()->selectionManager()->currentItem();
if (currentIndex != -1) {
@ -1298,11 +1308,11 @@ void DolphinView::updateViewState()
m_view->scrollToItem(currentIndex);
m_scrollToCurrentItem = false;
}
m_currentItemUrl = KUrl();
} else {
selectionManager->setCurrentItem(0);
}
m_currentItemUrl = KUrl();
}
if (!m_restoredContentsPosition.isNull()) {