From 18a976c435e85fa2556b1a1abb6de41392003d7d Mon Sep 17 00:00:00 2001 From: Emmanuel Pescosta Date: Mon, 4 Aug 2014 19:43:07 +0200 Subject: [PATCH 01/13] Fix wrong text eliding in some corner cases. BUG: 337104 FIXED-IN: 4.14.0 REVIEW: 119546 --- src/kitemviews/kstandarditemlistwidget.cpp | 24 +++++++++++++++------- 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/src/kitemviews/kstandarditemlistwidget.cpp b/src/kitemviews/kstandarditemlistwidget.cpp index 998acc0665..6407efc225 100644 --- a/src/kitemviews/kstandarditemlistwidget.cpp +++ b/src/kitemviews/kstandarditemlistwidget.cpp @@ -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; From 1ffb64db1f6d3436db6e637f8669319e96a17797 Mon Sep 17 00:00:00 2001 From: l10n daemon script Date: Sun, 10 Aug 2014 01:35:56 +0000 Subject: [PATCH 02/13] SVN_SILENT made messages (after extraction) --- src/dolphin.appdata.xml | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/dolphin.appdata.xml b/src/dolphin.appdata.xml index 958464976c..de59e6a2fc 100644 --- a/src/dolphin.appdata.xml +++ b/src/dolphin.appdata.xml @@ -17,6 +17,7 @@ Dolphin Dolphin Dolphin + Dolphin Dolphin Dolphin Dolphin @@ -46,6 +47,7 @@ Gerente de File Gestore file Failų tvarkyklė + Filbehandler Dateipleger Bestandsbeheerder Zarządzanie plikami @@ -73,6 +75,7 @@

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.

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.

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.

+

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.

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.

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.

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.

@@ -101,6 +104,7 @@

Characteristicas:

Funzionalità:

Galimybės

+

Egenskaper:

Markmalen:

Mogelijkheden:

Możliwości:

@@ -127,6 +131,7 @@
  • Barre de navigation (ou fil d'Ariane) permettant de naviguer rapidement dans la hiérarchie de fichiers et de dossiers.
  • Barra de navigation (o "breadcrumb") pro URLs, que il permitte te navigar rapidemente a transverso del hierarchia de files e dossieres.
  • La barra di navigazione per gli URL, che ti consente di navigare rapidamente attraverso la struttura di file e cartelle.
  • +
  • Navigasjonslinje (brødsmulelinje) for URL-er slik at du raskt kan navigere gjennom hierarkiet av filer og mapper.
  • Steed- (oder Krömelspoor-)Balken för URLs, mit de Du Di fix dör de Hierarchie ut Dateien un Ornern bewegen kannst
  • Navigatie- (of broodkruimel)balk voor URL's, waarmee u snel kunt navigeren door de hiërarchie van bestanden en mappen.
  • Pasek nawigacji (lub okruchy chleba) dla adresów URL, umożliwiające szybkie przechodzenie w hierarchii plików i katalogów.
  • @@ -152,6 +157,7 @@
  • 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.
  • Il supporta multe differente typos de stilos de vista e proprietates e il permitte te configurar le vista exactemente como tu vole.
  • Supporta diversi stili di visualizzazione e proprietà e ti consente di configurare la vista come desideri.
  • +
  • Støtter flere forskjellige visningsstiler og kan sette opp visningen akkurat slik du vil ha den.
  • Ünnerstütt en Reeg verscheden Ansichtstilen un -egenschappen un lett Di de Ansicht jüst so topassen, as Du dat bruukst.
  • 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.
  • Obsługa wielu różnych rodzajów stylów widoków i właściwości oraz możliwość ustawienia widoku dopasowanego do potrzeb.
  • @@ -177,6 +183,7 @@
  • Affichage divisé, permettant de facilement copier ou déplacer des fichiers dans les différents emplacements.
  • Scinde vista, il permitte te copiar o mover facilemente files inter locationes.
  • La vista divisa, che ti consente di copiare o spostare i file tra le diverse posizioni in maniera semplice.
  • +
  • Delt visning, så du lett kan kopiere eller flytte filer mellom steder.
  • Deelt Ansicht, mit De Du Dateien eenfach twischen Steden koperen oder bewegen kannst.
  • Gesplitst beeld, waarmee u gemakkelijk bestanden kunt kopiëren of verplaatsen tussen locaties.
  • Widok podzielony, umożliwiający łatwe kopiowane lub przenoszenie plików pomiędzy położeniami.
  • @@ -202,6 +209,7 @@
  • Des informations supplémentaires et des raccourcis sont disponible comme panneaux ancrable librement déplaçable et affichant exactement ce que vous voulez.
  • 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.
  • Informazioni aggiuntive e scorciatoie sono disponibili come pannelli agganciabili, che possono essere spostati liberamente e visualizzare esattamente ciò che desideri.
  • +
  • Mer informasjon og snarveier er tilgjengelige som dokkbare ruter, som du kan flytte fritt rundt og bruke til å vise akkurat hva du vil.
  • Bito-Infos un Leestekens laat sik as Paneels andocken, Du kannst ehr verschuven un se jüst dat wiesen laten, wat Du weten wullt.
  • Extra informatie en sneltoetsen zijn beschikbaar als vast te zetten panelen, die u vrij kunt verplaatsen en precies kunt tonen wat u wilt.
  • Dodatkowe szczegóły i skróty dostępne jako dokowalne panele, umożliwiające ich dowolne przenoszenie i wyświetlanie dopasowane do potrzeb.
  • @@ -229,6 +237,7 @@
  • Supporto de scheda multiple
  • Supporto di schede multiple
  • Daugelio kortelių palaikymas
  • +
  • Støtte for flere faner
  • Ünnerstütten för Paneels
  • Ondersteuning voor meerdere tabbladen
  • Obsługa wielu kart
  • @@ -255,6 +264,7 @@
  • Les dialogues d'information sont affiché de manière discrète.
  • Dialogos de information es monstrate de modo non importun.
  • Le finestre informative sono visualizzate in modo molto discreto.
  • +
  • Informasjonsdialoger vises på en lite påtrengende måte.
  • Informatschoondialogen kaamt Di nich in'n Weg.
  • Informatiedialogen worden op een prettige manier getoond.
  • Pokazywanie informacyjnych okien dialogowych w nienatrętny sposób.
  • @@ -280,6 +290,7 @@
  • Prise en charge d'annulation et recommencement
  • Supporto de annulla/reface
  • Supporto di annulla/rifai
  • +
  • Støtte for angring/omgjøring
  • Ünnerstütten för Torüchnehmen un Wedderherstellen
  • Ondersteuning ongedaan maken/opnieuw
  • Obsługa cofnij/ponów
  • @@ -307,6 +318,7 @@
  • Accès au réseau transparent grâce au système des KIO.
  • Accesso de rete transparente a transverso del systema KIO.
  • Accesso trasparente alla rete tramite il sistema KIO.
  • +
  • Gjennomsiktig nettverkstilgang via KIO-systemet.
  • Direkt Nettwarktogriep över dat KDE-In-/Utgaav-(KIO-)Moduulsysteem
  • Transparante toegang tot het netwerk via het KIO systeem.
  • Przezroczysty dostęp do sieci przez system KIO.
  • From 013b2346f56e846009dd1eebfc88c737d94dad0f Mon Sep 17 00:00:00 2001 From: l10n daemon script Date: Sun, 10 Aug 2014 05:48:43 +0000 Subject: [PATCH 03/13] SVN_SILENT made messages (after extraction) --- src/dolphin.appdata.xml | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/dolphin.appdata.xml b/src/dolphin.appdata.xml index 958464976c..de59e6a2fc 100644 --- a/src/dolphin.appdata.xml +++ b/src/dolphin.appdata.xml @@ -17,6 +17,7 @@ Dolphin Dolphin Dolphin + Dolphin Dolphin Dolphin Dolphin @@ -46,6 +47,7 @@ Gerente de File Gestore file Failų tvarkyklė + Filbehandler Dateipleger Bestandsbeheerder Zarządzanie plikami @@ -73,6 +75,7 @@

    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.

    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.

    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.

    +

    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.

    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.

    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.

    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.

    @@ -101,6 +104,7 @@

    Characteristicas:

    Funzionalità:

    Galimybės

    +

    Egenskaper:

    Markmalen:

    Mogelijkheden:

    Możliwości:

    @@ -127,6 +131,7 @@
  • Barre de navigation (ou fil d'Ariane) permettant de naviguer rapidement dans la hiérarchie de fichiers et de dossiers.
  • Barra de navigation (o "breadcrumb") pro URLs, que il permitte te navigar rapidemente a transverso del hierarchia de files e dossieres.
  • La barra di navigazione per gli URL, che ti consente di navigare rapidamente attraverso la struttura di file e cartelle.
  • +
  • Navigasjonslinje (brødsmulelinje) for URL-er slik at du raskt kan navigere gjennom hierarkiet av filer og mapper.
  • Steed- (oder Krömelspoor-)Balken för URLs, mit de Du Di fix dör de Hierarchie ut Dateien un Ornern bewegen kannst
  • Navigatie- (of broodkruimel)balk voor URL's, waarmee u snel kunt navigeren door de hiërarchie van bestanden en mappen.
  • Pasek nawigacji (lub okruchy chleba) dla adresów URL, umożliwiające szybkie przechodzenie w hierarchii plików i katalogów.
  • @@ -152,6 +157,7 @@
  • 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.
  • Il supporta multe differente typos de stilos de vista e proprietates e il permitte te configurar le vista exactemente como tu vole.
  • Supporta diversi stili di visualizzazione e proprietà e ti consente di configurare la vista come desideri.
  • +
  • Støtter flere forskjellige visningsstiler og kan sette opp visningen akkurat slik du vil ha den.
  • Ünnerstütt en Reeg verscheden Ansichtstilen un -egenschappen un lett Di de Ansicht jüst so topassen, as Du dat bruukst.
  • 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.
  • Obsługa wielu różnych rodzajów stylów widoków i właściwości oraz możliwość ustawienia widoku dopasowanego do potrzeb.
  • @@ -177,6 +183,7 @@
  • Affichage divisé, permettant de facilement copier ou déplacer des fichiers dans les différents emplacements.
  • Scinde vista, il permitte te copiar o mover facilemente files inter locationes.
  • La vista divisa, che ti consente di copiare o spostare i file tra le diverse posizioni in maniera semplice.
  • +
  • Delt visning, så du lett kan kopiere eller flytte filer mellom steder.
  • Deelt Ansicht, mit De Du Dateien eenfach twischen Steden koperen oder bewegen kannst.
  • Gesplitst beeld, waarmee u gemakkelijk bestanden kunt kopiëren of verplaatsen tussen locaties.
  • Widok podzielony, umożliwiający łatwe kopiowane lub przenoszenie plików pomiędzy położeniami.
  • @@ -202,6 +209,7 @@
  • Des informations supplémentaires et des raccourcis sont disponible comme panneaux ancrable librement déplaçable et affichant exactement ce que vous voulez.
  • 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.
  • Informazioni aggiuntive e scorciatoie sono disponibili come pannelli agganciabili, che possono essere spostati liberamente e visualizzare esattamente ciò che desideri.
  • +
  • Mer informasjon og snarveier er tilgjengelige som dokkbare ruter, som du kan flytte fritt rundt og bruke til å vise akkurat hva du vil.
  • Bito-Infos un Leestekens laat sik as Paneels andocken, Du kannst ehr verschuven un se jüst dat wiesen laten, wat Du weten wullt.
  • Extra informatie en sneltoetsen zijn beschikbaar als vast te zetten panelen, die u vrij kunt verplaatsen en precies kunt tonen wat u wilt.
  • Dodatkowe szczegóły i skróty dostępne jako dokowalne panele, umożliwiające ich dowolne przenoszenie i wyświetlanie dopasowane do potrzeb.
  • @@ -229,6 +237,7 @@
  • Supporto de scheda multiple
  • Supporto di schede multiple
  • Daugelio kortelių palaikymas
  • +
  • Støtte for flere faner
  • Ünnerstütten för Paneels
  • Ondersteuning voor meerdere tabbladen
  • Obsługa wielu kart
  • @@ -255,6 +264,7 @@
  • Les dialogues d'information sont affiché de manière discrète.
  • Dialogos de information es monstrate de modo non importun.
  • Le finestre informative sono visualizzate in modo molto discreto.
  • +
  • Informasjonsdialoger vises på en lite påtrengende måte.
  • Informatschoondialogen kaamt Di nich in'n Weg.
  • Informatiedialogen worden op een prettige manier getoond.
  • Pokazywanie informacyjnych okien dialogowych w nienatrętny sposób.
  • @@ -280,6 +290,7 @@
  • Prise en charge d'annulation et recommencement
  • Supporto de annulla/reface
  • Supporto di annulla/rifai
  • +
  • Støtte for angring/omgjøring
  • Ünnerstütten för Torüchnehmen un Wedderherstellen
  • Ondersteuning ongedaan maken/opnieuw
  • Obsługa cofnij/ponów
  • @@ -307,6 +318,7 @@
  • Accès au réseau transparent grâce au système des KIO.
  • Accesso de rete transparente a transverso del systema KIO.
  • Accesso trasparente alla rete tramite il sistema KIO.
  • +
  • Gjennomsiktig nettverkstilgang via KIO-systemet.
  • Direkt Nettwarktogriep över dat KDE-In-/Utgaav-(KIO-)Moduulsysteem
  • Transparante toegang tot het netwerk via het KIO systeem.
  • Przezroczysty dostęp do sieci przez system KIO.
  • From 38381bc6a2999b1d8a0b8a6e2b8d703faa0944d9 Mon Sep 17 00:00:00 2001 From: Emmanuel Pescosta Date: Sun, 10 Aug 2014 18:52:06 +0200 Subject: [PATCH 04/13] Implemented DolphinTabWidget class to encapsulate the tab handling from DolphinMainWindow. REVIEW: 119115 --- src/CMakeLists.txt | 1 + src/dolphinmainwindow.cpp | 441 ++++++-------------------------------- src/dolphinmainwindow.h | 99 ++------- src/dolphintabpage.cpp | 2 +- src/dolphintabpage.h | 2 +- src/dolphintabwidget.cpp | 345 +++++++++++++++++++++++++++++ src/dolphintabwidget.h | 178 +++++++++++++++ 7 files changed, 608 insertions(+), 460 deletions(-) create mode 100644 src/dolphintabwidget.cpp create mode 100644 src/dolphintabwidget.h diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 7b0210aef9..6f256a2f43 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -174,6 +174,7 @@ set(dolphin_SRCS dolphintabbar.cpp dolphinrecenttabsmenu.cpp dolphintabpage.cpp + dolphintabwidget.cpp filterbar/filterbar.cpp main.cpp panels/information/filemetadataconfigurationdialog.cpp diff --git a/src/dolphinmainwindow.cpp b/src/dolphinmainwindow.cpp index d321d3b4a7..0882bac717 100644 --- a/src/dolphinmainwindow.cpp +++ b/src/dolphinmainwindow.cpp @@ -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" @@ -97,11 +97,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(), @@ -134,6 +131,13 @@ 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))); + setCentralWidget(m_tabWidget); + setupActions(); m_actionHandler = new DolphinViewActionHandler(actionCollection(), this); @@ -144,30 +148,6 @@ DolphinMainWindow::DolphinMainWindow() : connect(this, SIGNAL(urlChanged(KUrl)), m_remoteEncoding, SLOT(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); @@ -200,48 +180,12 @@ DolphinMainWindow::~DolphinMainWindow() void DolphinMainWindow::openDirectories(const QList& 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::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& 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 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) @@ -287,21 +231,14 @@ 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(); + setUrlAsCaption(url); - const QString iconName = KMimeType::iconNameForUrl(url); - m_tabBar->setTabIcon(m_tabIndex, KIcon(iconName)); - m_tabBar->setTabText(m_tabIndex, squeezedText(tabName(view->url()))); - - emit urlChanged(url); - } + emit urlChanged(url); } void DolphinMainWindow::slotTerminalDirectoryChanged(const KUrl& url) @@ -322,7 +259,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) { @@ -368,99 +305,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("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(KIcon(KMimeType::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() @@ -499,12 +356,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(); } @@ -520,7 +371,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 @@ -555,7 +406,7 @@ void DolphinMainWindow::closeEvent(QCloseEvent* event) break; case KDialog::No: // Close only the current tab - closeTab(); + m_tabWidget->closeTab(); default: event->ignore(); return; @@ -570,32 +421,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() @@ -699,13 +530,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(); } @@ -768,14 +595,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(); @@ -841,7 +660,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 @@ -903,111 +722,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; @@ -1041,20 +755,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); @@ -1214,27 +914,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(); @@ -1243,14 +944,20 @@ void DolphinMainWindow::setActiveViewContainer(DolphinViewContainer* viewContain updateViewActions(); updateGoActions(); - const KUrl url = m_activeViewContainer->url(); + const KUrl url = viewContainer->url(); setUrlAsCaption(url); - m_tabBar->setTabText(m_tabIndex, squeezedText(tabName(url))); - m_tabBar->setTabIcon(m_tabIndex, KIcon(KMimeType::iconNameForUrl(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::setupActions() { // setup 'File' menu @@ -1272,14 +979,14 @@ void DolphinMainWindow::setupActions() newTab->setIcon(KIcon("tab-new")); newTab->setText(i18nc("@action:inmenu File", "New Tab")); newTab->setShortcut(KShortcut(Qt::CTRL | Qt::Key_T, Qt::CTRL | Qt::SHIFT | Qt::Key_N)); - connect(newTab, SIGNAL(triggered()), this, SLOT(openNewTab())); + connect(newTab, SIGNAL(triggered()), this, SLOT(openNewActivatedTab())); KAction* closeTab = actionCollection()->addAction("close_tab"); closeTab->setIcon(KIcon("tab-close")); closeTab->setText(i18nc("@action:inmenu File", "Close Tab")); closeTab->setShortcut(Qt::CTRL | Qt::Key_W); closeTab->setEnabled(false); - connect(closeTab, SIGNAL(triggered()), this, SLOT(closeTab())); + connect(closeTab, SIGNAL(triggered()), m_tabWidget, SLOT(closeTab())); KStandardAction::quit(this, SLOT(quit()), actionCollection()); @@ -1351,7 +1058,7 @@ void DolphinMainWindow::setupActions() DolphinRecentTabsMenu* recentTabsMenu = new DolphinRecentTabsMenu(this); actionCollection()->addAction("closed_tabs", recentTabsMenu); - connect(this, SIGNAL(rememberClosedTab(KUrl,KUrl)), + connect(m_tabWidget, SIGNAL(rememberClosedTab(KUrl,KUrl)), recentTabsMenu, SLOT(rememberClosedTab(KUrl,KUrl))); connect(recentTabsMenu, SIGNAL(restoreClosedTab(KUrl,KUrl)), this, SLOT(openNewActivatedTab(KUrl,KUrl))); @@ -1412,14 +1119,14 @@ void DolphinMainWindow::setupActions() activateNextTab->setIconText(i18nc("@action:inmenu", "Next Tab")); activateNextTab->setText(i18nc("@action:inmenu", "Activate Next Tab")); activateNextTab->setEnabled(false); - connect(activateNextTab, SIGNAL(triggered()), SLOT(activateNextTab())); + connect(activateNextTab, SIGNAL(triggered()), m_tabWidget, SLOT(activateNextTab())); activateNextTab->setShortcuts(QApplication::isRightToLeft() ? prevTabKeys : nextTabKeys); KAction* 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, SIGNAL(triggered()), SLOT(activatePrevTab())); + connect(activatePrevTab, SIGNAL(triggered()), m_tabWidget, SLOT(activatePrevTab())); activatePrevTab->setShortcuts(QApplication::isRightToLeft() ? nextTabKeys : prevTabKeys); // for context menu @@ -1548,10 +1255,12 @@ void DolphinMainWindow::setupDockWidgets() connect(this, SIGNAL(urlChanged(KUrl)), placesPanel, SLOT(setUrl(KUrl))); connect(placesDock, SIGNAL(visibilityChanged(bool)), - this, SLOT(slotPlacesPanelVisibilityChanged(bool))); + m_tabWidget, SLOT(slotPlacesPanelVisibilityChanged(bool))); connect(this, SIGNAL(settingsChanged()), placesPanel, SLOT(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); @@ -1674,15 +1383,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(); } @@ -1733,7 +1440,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")); @@ -1751,24 +1458,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; @@ -1798,12 +1487,6 @@ void DolphinMainWindow::setUrlAsCaption(const KUrl& url) 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 KIcon& icon, const QKeySequence& shortcut, QAction* dockAction, diff --git a/src/dolphinmainwindow.h b/src/dolphinmainwindow.h index 6f37f42ee6..7bce7f13e9 100644 --- a/src/dolphinmainwindow.h +++ b/src/dolphinmainwindow.h @@ -38,19 +38,16 @@ typedef KIO::FileUndoManager::CommandType CommandType; class DolphinViewActionHandler; class DolphinApplication; class DolphinSettingsDialog; -class DolphinTabBar; class DolphinViewContainer; class DolphinRemoteEncoding; -class DolphinTabPage; +class DolphinTabWidget; class KAction; class KFileItem; class KFileItemList; class KJob; class KNewFileMenu; class KUrl; -class QSplitter; class QToolButton; -class QVBoxLayout; /** * @short Main window for Dolphin. @@ -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,25 @@ 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); +private: void setupActions(); void setupDockWidgets(); void updateEditActions(); @@ -511,10 +462,6 @@ private: */ void updateSplitAction(); - /** Returns the name of the tab for the URL \a url. */ - QString tabName(const KUrl& url) const; - - bool isKompareInstalled() const; /** @@ -523,8 +470,6 @@ private: */ 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 m_viewTab; - DolphinViewActionHandler* m_actionHandler; DolphinRemoteEncoding* m_remoteEncoding; QWeakPointer m_settingsDialog; diff --git a/src/dolphintabpage.cpp b/src/dolphintabpage.cpp index 82be6d59c1..d1184a9f2c 100644 --- a/src/dolphintabpage.cpp +++ b/src/dolphintabpage.cpp @@ -246,7 +246,7 @@ void DolphinTabPage::slotViewActivated() } emit activeViewUrlChanged(activeViewContainer()->url()); - emit activeViewChanged(); + emit activeViewChanged(activeViewContainer()); } DolphinViewContainer* DolphinTabPage::createViewContainer(const KUrl& url) const diff --git a/src/dolphintabpage.h b/src/dolphintabpage.h index 95c02ed0a1..278524792c 100644 --- a/src/dolphintabpage.h +++ b/src/dolphintabpage.h @@ -121,7 +121,7 @@ public: void restoreState(const QByteArray& state); signals: - void activeViewChanged(); + void activeViewChanged(DolphinViewContainer* viewContainer); void activeViewUrlChanged(const KUrl& url); private slots: diff --git a/src/dolphintabwidget.cpp b/src/dolphintabwidget.cpp new file mode 100644 index 0000000000..4bb70b4eab --- /dev/null +++ b/src/dolphintabwidget.cpp @@ -0,0 +1,345 @@ +/*************************************************************************** + * Copyright (C) 2014 by Emmanuel Pescosta * + * * + * 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 +#include +#include +#include + +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(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 " % 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(); + } + const QByteArray state = group.readEntry("Tab " % QString::number(i), QByteArray()); + tabPageAt(i)->restoreState(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, KIcon(KMimeType::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& 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::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& 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 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); + if (tabPage->splitViewEnabled()) { + emit rememberClosedTab(tabPage->primaryViewContainer()->url(), + tabPage->secondaryViewContainer()->url()); + } else { + emit rememberClosedTab(tabPage->primaryViewContainer()->url(), KUrl()); + } + + 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::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(sender())); + if (index >= 0) { + tabBar()->setTabText(index, tabName(url)); + tabBar()->setTabIcon(index, KIcon(KMimeType::iconNameForUrl(url))); + } +} + +void DolphinTabWidget::currentTabChanged(int index) +{ + emit activeViewChanged(tabPageAt(index)->activeViewContainer()); +} + +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; +} diff --git a/src/dolphintabwidget.h b/src/dolphintabwidget.h new file mode 100644 index 0000000000..a9bef11be1 --- /dev/null +++ b/src/dolphintabwidget.h @@ -0,0 +1,178 @@ +/*************************************************************************** + * Copyright (C) 2014 by Emmanuel Pescosta * + * * + * 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 +#include + +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& primaryUrl, const KUrl& secondaryUrl); + +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& dirs); + + /** + * Opens the directory which contains the files \p files + * and selects all files (implements the --select option + * of Dolphin). + */ + void openFiles(const QList& 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); + +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 \ No newline at end of file From 4ed068fffff2343cc0dcd236c38832b7662f8d78 Mon Sep 17 00:00:00 2001 From: Frank Reininghaus Date: Tue, 12 Aug 2014 09:08:30 +0200 Subject: [PATCH 05/13] Fix crash when restoring a session stored with Dolphin 4.13 or earlier Since DolphinTabPage::saveState() and DolphinTabPage::restoreState(const QByteArray& state) save and restore the state of each tab in a different format than DolphinMainWindow did before the refactoring, we can run into problems: the first time a user logs into a session that has Dolphin 4.14, Dolphin might read session data that does not contain the QByteArray that DolphinTabPage wants to read the data from. In restoreState, isSplitViewEnabled will thus have the value false, and no secondary view will be created. Later on, m_primaryViewActive will also be set to false, but the else branch of the following "if (m_primaryViewActive)" then tries to activate the secondary view, which does not exist -> we get a crash. The easiest solution is to not restore the tab state if no session data in the new format is found. BUG: 338187 REVIEW: 119718 FIXED-IN: 4.14.0 --- src/dolphintabpage.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/dolphintabpage.cpp b/src/dolphintabpage.cpp index 82be6d59c1..4c49869f77 100644 --- a/src/dolphintabpage.cpp +++ b/src/dolphintabpage.cpp @@ -187,6 +187,10 @@ QByteArray DolphinTabPage::saveState() const void DolphinTabPage::restoreState(const QByteArray& state) { + if (state.isEmpty()) { + return; + } + QByteArray sd = state; QDataStream stream(&sd, QIODevice::ReadOnly); From bf1ac8ee9b2edcf9e90f74bae7f392c1b3c318b2 Mon Sep 17 00:00:00 2001 From: Frank Reininghaus Date: Tue, 12 Aug 2014 09:17:41 +0200 Subject: [PATCH 06/13] Always clear DolphinView's m_currentItemUrl member in updateViewState() Before this patch, we still kept the URL in m_currentItemUrl if the URL was not found in the model. This could cause problems the next time updateViewState() was called, because the current index would then be set to 0, which could cause other issues. For example, all items between the first item in the view and a folder which was expanded in Details View could be selected. In principle, it is possible that updateViewState() is called multiple times if many large files are being pasted in the view, but since the item which should be made the current item (and which the view should be scrolled to) should always be the first pasted item, this change will most likely not cause any other problems. BUG: 329377 REVIEW: 119703 FIXED-IN: 4.14.0 --- src/views/dolphinview.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/views/dolphinview.cpp b/src/views/dolphinview.cpp index c1f585da94..02b8815e07 100644 --- a/src/views/dolphinview.cpp +++ b/src/views/dolphinview.cpp @@ -1289,11 +1289,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()) { From c7e300db9066ebc990ae49ae97c590a68e5dd39d Mon Sep 17 00:00:00 2001 From: l10n daemon script Date: Wed, 13 Aug 2014 05:58:14 +0000 Subject: [PATCH 07/13] SVN_SILENT made messages (after extraction) --- src/dolphin.appdata.xml | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/dolphin.appdata.xml b/src/dolphin.appdata.xml index de59e6a2fc..27fae876bd 100644 --- a/src/dolphin.appdata.xml +++ b/src/dolphin.appdata.xml @@ -33,6 +33,7 @@ Dolphin Dolphin xxDolphinxx + Dolphin File Manager مدير ملفات Gestor de fitxers @@ -63,6 +64,7 @@ Filhanterare Програма для керування файлами xxFile Managerxx + 檔案管理員

    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.

    دولفين هو مدير ملفات خفيف. صُمِّم دولفين مع أخذ سهولة الاستخدام والبساطة بعين الاعتبار، مع السماح بالمرونة والتخصيص. يعني هذا أنه يمكنك إدارة ملفاتك كما تريد تماماً.

    @@ -90,6 +92,7 @@

    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.

    Dolphin — невибаглива до ресурсів програма для керування файлами. Її створено простою у користуванні і гнучкою у налаштовуванні. Це означає, що ви можете зробити керування файлами саме таким, як вам потрібно.

    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

    +

    Dolphin 是一套輕量級的檔案管理員。它設計的理念是易用與簡單,但仍然保持足夠的彈性。這表示您可以用您想要使用的方式來管理您的檔案。

    Features:

    المزايا:

    Característiques:

    @@ -120,6 +123,7 @@

    Funktioner:

    Можливості:

    xxFeatures:xx

    +

    特色:

    • Navigation (or breadcrumb) bar for URLs, allowing you to quickly navigate through the hierarchy of files and folders.
    • Barra de navegació (o fil d'Ariadna) per els URL, permetent una navegació ràpida per la jerarquia de fitxers i carpetes.
    • @@ -146,6 +150,7 @@
    • Navigeringsrad (eller länkstig) för webbadresser, som låter dig snabbt navigera igenom hierarkin av filer och kataloger.
    • Панель навігації (звичайний режим і режим послідовної навігації) для адрес надає вам змогу швидко пересуватися ієрархією файлів та каталогів.
    • xxNavigation (or breadcrumb) bar for URLs, allowing you to quickly navigate through the hierarchy of files and folders.xx
    • +
    • 網址導覽列讓您可以快速瀏覽檔案與資料夾。
    • Supports several different kinds of view styles and properties and allows you to configure the view exactly how you want it.
    • يدعم العديد من الأنواع المختلفة من الخصائص وأنماط العرض ويسمك لك بضبط العرض كما تريد تماماً.
    • Accepta diferents classes diverses d'estils de visualització i propietats i us permet configurar la visualització exactament com la vulgueu.
    • @@ -172,6 +177,7 @@
    • Stöder flera olika sorters visningsstilar och egenskaper och låter dig anpassa visningen exakt som du vill ha den.
    • Підтримка декількох різних типів та параметрів перегляду надає вам змогу налаштувати перегляд каталогів саме так, як вам це потрібно.
    • xxSupports several different kinds of view styles and properties and allows you to configure the view exactly how you want it.xx
    • +
    • 支援數個檢視模式,您也可以調整檢視模式的屬性。
    • Split view, allowing you to easily copy or move files between locations.
    • العرض المقسوم، يسمح لك بنسخ ونقل الملفات بين مكانين بسهولة.
    • Divisió de visualització, permetent copiar o moure fitxers fàcilment entre les ubicacions.
    • @@ -198,6 +204,7 @@
    • Delad visning, som låter dig enkelt kopiera eller flytta filer mellan platser.
    • За допомогою режиму двопанельного розділеного перегляду ви зможе без проблем копіювати або пересувати файли між каталогами.
    • xxSplit view, allowing you to easily copy or move files between locations.xx
    • +
    • 分割檢視讓您可以輕鬆複製或移動檔案。
    • Additional information and shortcuts are available as dock-able panels, allowing you to move them around freely and display exactly what you want.
    • تتوفر معلومات واختصارات إضافية كألواح قابلة للتركيب، مما يسمح لك بنقلها بحريّة وعرضها بالضبط كما تريد.
    • Hi ha informació addicional i dreceres disponibles com a plafons acoblables, permetent moure'ls lliurement i mostrar exactament el què vulgueu.
    • @@ -224,6 +231,7 @@
    • 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.
    • За допомогою бічних пересувних панелей ви зможете отримувати додаткову інформацію та пересуватися каталогами. Ви можете розташувати ці панелі так, як вам це зручно, і наказати програмі показувати на них саме те, що вам потрібно.
    • xxAdditional information and shortcuts are available as dock-able panels, allowing you to move them around freely and display exactly what you want.xx
    • +
    • 額外資訊與嵌入式面板捷徑讓您可以輕易顯示您常用的項目。
    • Multiple tab support
    • دعم تعدّد الألسنة
    • Implementació de pestanyes múltiples
    • @@ -253,6 +261,7 @@
    • Stöd för flera flikar
    • Підтримка роботи з вкладками.
    • xxMultiple tab supportxx
    • +
    • 支援多分頁
    • Informational dialogues are displayed in an unobtrusive way.
    • El diàlegs informatius es mostren de manera no molesta.
    • Informationsdialoger vises på en ikke-forstyrrende måde.
    • @@ -279,6 +288,7 @@
    • Dialogrutor med information visas på ett diskret sätt.
    • Показ інформаційних панелей у зручний спосіб, що не заважає роботі.
    • xxInformational dialogues are displayed in an unobtrusive way.xx
    • +
    • 以不唐突的方式顯示資訊對話框。
    • Undo/redo support
    • Implementació de desfer/refer
    • Understøttelse af fortryd/gendan
    • @@ -306,6 +316,7 @@
    • Stöd för ångra och gör om
    • Підтримка скасовування та повторення дій.
    • xxUndo/redo supportxx
    • +
    • 復原/重做功能
    • Transparent network access through the KIO system.
    • اتصال شبكيّ مباشر باستخدام نظام KIO.
    • Accés transparent a la xarxa a través del sistema KIO.
    • @@ -334,6 +345,7 @@
    • Transparent nätverksåtkomst via I/O-slavsystemet.
    • Прозорий доступ до ресурсів у мережі за допомогою системи KIO.
    • xxTransparent network access through the KIO system.xx
    • +
    • 透過 KIO 系統無感地存取網路。
    http://dolphin.kde.org/ From 62418c58a58fac668e713655552b1c614b226298 Mon Sep 17 00:00:00 2001 From: Emmanuel Pescosta Date: Sun, 10 Aug 2014 20:36:44 +0200 Subject: [PATCH 08/13] Use DolphinTabPage saveState/restoreState to remember and re-open closed tabs. REVIEW: 118968 --- src/dolphinmainwindow.cpp | 8 ++++---- src/dolphinrecenttabsmenu.cpp | 19 ++++++------------- src/dolphinrecenttabsmenu.h | 4 ++-- src/dolphintabwidget.cpp | 13 +++++++------ src/dolphintabwidget.h | 8 +++++++- 5 files changed, 26 insertions(+), 26 deletions(-) diff --git a/src/dolphinmainwindow.cpp b/src/dolphinmainwindow.cpp index 0882bac717..588bfda64f 100644 --- a/src/dolphinmainwindow.cpp +++ b/src/dolphinmainwindow.cpp @@ -1058,10 +1058,10 @@ void DolphinMainWindow::setupActions() DolphinRecentTabsMenu* recentTabsMenu = new DolphinRecentTabsMenu(this); actionCollection()->addAction("closed_tabs", recentTabsMenu); - connect(m_tabWidget, 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))); diff --git a/src/dolphinrecenttabsmenu.cpp b/src/dolphinrecenttabsmenu.cpp index 2335f1bf48..fa3eaf166d 100644 --- a/src/dolphinrecenttabsmenu.cpp +++ b/src/dolphinrecenttabsmenu.cpp @@ -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 = KMimeType::iconNameForUrl(url); action->setIcon(KIcon(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(); + const QByteArray state = action->data().value(); 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); } diff --git a/src/dolphinrecenttabsmenu.h b/src/dolphinrecenttabsmenu.h index b5acc735e5..910e564a19 100644 --- a/src/dolphinrecenttabsmenu.h +++ b/src/dolphinrecenttabsmenu.h @@ -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: diff --git a/src/dolphintabwidget.cpp b/src/dolphintabwidget.cpp index 4bb70b4eab..ea71b48566 100644 --- a/src/dolphintabwidget.cpp +++ b/src/dolphintabwidget.cpp @@ -213,12 +213,7 @@ void DolphinTabWidget::closeTab(const int index) } DolphinTabPage* tabPage = tabPageAt(index); - if (tabPage->splitViewEnabled()) { - emit rememberClosedTab(tabPage->primaryViewContainer()->url(), - tabPage->secondaryViewContainer()->url()); - } else { - emit rememberClosedTab(tabPage->primaryViewContainer()->url(), KUrl()); - } + emit rememberClosedTab(tabPage->activeViewContainer()->url(), tabPage->saveState()); removeTab(index); tabPage->deleteLater(); @@ -249,6 +244,12 @@ void DolphinTabWidget::slotPlacesPanelVisibilityChanged(bool visible) } } +void DolphinTabWidget::restoreClosedTab(const QByteArray& state) +{ + openNewActivatedTab(); + currentTabPage()->restoreState(state); +} + void DolphinTabWidget::detachTab(int index) { Q_ASSERT(index >= 0); diff --git a/src/dolphintabwidget.h b/src/dolphintabwidget.h index a9bef11be1..aaadbc997b 100644 --- a/src/dolphintabwidget.h +++ b/src/dolphintabwidget.h @@ -70,7 +70,7 @@ signals: /** * Is emitted when a tab has been closed. */ - void rememberClosedTab(const KUrl& primaryUrl, const KUrl& secondaryUrl); + void rememberClosedTab(const KUrl& url, const QByteArray& state); public slots: /** @@ -133,6 +133,12 @@ public slots: */ 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 From 39d8fb12c1552ec708b5fc1846d7aa9828329417 Mon Sep 17 00:00:00 2001 From: Emmanuel Pescosta Date: Wed, 13 Aug 2014 22:06:28 +0200 Subject: [PATCH 09/13] React on the redirection signal from DolphinView to properly update the tab and window titles. REVIEW: 119697 BUG: 305721 --- src/dolphinmainwindow.cpp | 37 ++++++++++++++++++------------------- src/dolphinmainwindow.h | 12 ++++++------ src/dolphintabpage.cpp | 13 +++++++++++++ src/dolphintabpage.h | 7 +++++++ src/dolphintabwidget.cpp | 9 ++++++++- src/dolphintabwidget.h | 6 ++++++ 6 files changed, 58 insertions(+), 26 deletions(-) diff --git a/src/dolphinmainwindow.cpp b/src/dolphinmainwindow.cpp index 588bfda64f..95b08af96e 100644 --- a/src/dolphinmainwindow.cpp +++ b/src/dolphinmainwindow.cpp @@ -136,6 +136,8 @@ DolphinMainWindow::DolphinMainWindow() : 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(); @@ -236,7 +238,6 @@ void DolphinMainWindow::changeUrl(const KUrl& url) updatePasteAction(); updateViewActions(); updateGoActions(); - setUrlAsCaption(url); emit urlChanged(url); } @@ -945,8 +946,6 @@ void DolphinMainWindow::activeViewChanged(DolphinViewContainer* viewContainer) updateGoActions(); const KUrl url = viewContainer->url(); - setUrlAsCaption(url); - emit urlChanged(url); } @@ -958,6 +957,22 @@ void DolphinMainWindow::tabCountChanged(int count) 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 @@ -1471,22 +1486,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); -} - void DolphinMainWindow::createPanelAction(const KIcon& icon, const QKeySequence& shortcut, QAction* dockAction, diff --git a/src/dolphinmainwindow.h b/src/dolphinmainwindow.h index 7bce7f13e9..9d4c003af7 100644 --- a/src/dolphinmainwindow.h +++ b/src/dolphinmainwindow.h @@ -429,6 +429,12 @@ private slots: */ 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(); @@ -464,12 +470,6 @@ private: 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); - /** * Creates an action for showing/hiding a panel, that is accessible * in "Configure toolbars..." and "Configure shortcuts...". This is necessary diff --git a/src/dolphintabpage.cpp b/src/dolphintabpage.cpp index 23e33c9583..3d1ba5a3e8 100644 --- a/src/dolphintabpage.cpp +++ b/src/dolphintabpage.cpp @@ -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(); @@ -245,14 +247,25 @@ 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(activeViewContainer()); } +void DolphinTabPage::slotViewUrlRedirection(const KUrl& oldUrl, const KUrl& newUrl) +{ + Q_UNUSED(oldUrl); + + emit activeViewUrlChanged(newUrl); +} + DolphinViewContainer* DolphinTabPage::createViewContainer(const KUrl& url) const { DolphinViewContainer* container = new DolphinViewContainer(url, m_splitter); diff --git a/src/dolphintabpage.h b/src/dolphintabpage.h index 278524792c..de5a589152 100644 --- a/src/dolphintabpage.h +++ b/src/dolphintabpage.h @@ -133,6 +133,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. diff --git a/src/dolphintabwidget.cpp b/src/dolphintabwidget.cpp index ea71b48566..76d4b8d48d 100644 --- a/src/dolphintabwidget.cpp +++ b/src/dolphintabwidget.cpp @@ -295,12 +295,19 @@ void DolphinTabWidget::tabUrlChanged(const KUrl& url) if (index >= 0) { tabBar()->setTabText(index, tabName(url)); tabBar()->setTabIcon(index, KIcon(KMimeType::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) { - emit activeViewChanged(tabPageAt(index)->activeViewContainer()); + DolphinViewContainer* viewContainer = tabPageAt(index)->activeViewContainer(); + emit activeViewChanged(viewContainer); + emit currentUrlChanged(viewContainer->url()); } void DolphinTabWidget::tabInserted(int index) diff --git a/src/dolphintabwidget.h b/src/dolphintabwidget.h index aaadbc997b..98bcd985ab 100644 --- a/src/dolphintabwidget.h +++ b/src/dolphintabwidget.h @@ -72,6 +72,12 @@ signals: */ 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 From 4d2877e4bb794def77e4e41e20a8ece69396ae45 Mon Sep 17 00:00:00 2001 From: l10n daemon script Date: Thu, 14 Aug 2014 01:41:42 +0000 Subject: [PATCH 10/13] SVN_SILENT made messages (after extraction) --- src/dolphin.appdata.xml | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/dolphin.appdata.xml b/src/dolphin.appdata.xml index de59e6a2fc..fe0c774e64 100644 --- a/src/dolphin.appdata.xml +++ b/src/dolphin.appdata.xml @@ -33,6 +33,7 @@ Dolphin Dolphin xxDolphinxx + Dolphin File Manager مدير ملفات Gestor de fitxers @@ -63,6 +64,7 @@ Filhanterare Програма для керування файлами xxFile Managerxx + 檔案管理員

    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.

    دولفين هو مدير ملفات خفيف. صُمِّم دولفين مع أخذ سهولة الاستخدام والبساطة بعين الاعتبار، مع السماح بالمرونة والتخصيص. يعني هذا أنه يمكنك إدارة ملفاتك كما تريد تماماً.

    @@ -90,6 +92,7 @@

    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.

    Dolphin — невибаглива до ресурсів програма для керування файлами. Її створено простою у користуванні і гнучкою у налаштовуванні. Це означає, що ви можете зробити керування файлами саме таким, як вам потрібно.

    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

    +

    Dolphin 是一套輕量級的檔案管理員。它設計的理念是易用與簡單,但仍然保持足夠的彈性。這表示您可以用您想要使用的方式來管理您的檔案。

    Features:

    المزايا:

    Característiques:

    @@ -120,6 +123,7 @@

    Funktioner:

    Можливості:

    xxFeatures:xx

    +

    功能:

    • Navigation (or breadcrumb) bar for URLs, allowing you to quickly navigate through the hierarchy of files and folders.
    • Barra de navegació (o fil d'Ariadna) per els URL, permetent una navegació ràpida per la jerarquia de fitxers i carpetes.
    • @@ -146,6 +150,7 @@
    • Navigeringsrad (eller länkstig) för webbadresser, som låter dig snabbt navigera igenom hierarkin av filer och kataloger.
    • Панель навігації (звичайний режим і режим послідовної навігації) для адрес надає вам змогу швидко пересуватися ієрархією файлів та каталогів.
    • xxNavigation (or breadcrumb) bar for URLs, allowing you to quickly navigate through the hierarchy of files and folders.xx
    • +
    • 網址導覽列讓您可以快速瀏覽檔案與資料夾。
    • Supports several different kinds of view styles and properties and allows you to configure the view exactly how you want it.
    • يدعم العديد من الأنواع المختلفة من الخصائص وأنماط العرض ويسمك لك بضبط العرض كما تريد تماماً.
    • Accepta diferents classes diverses d'estils de visualització i propietats i us permet configurar la visualització exactament com la vulgueu.
    • @@ -172,6 +177,7 @@
    • Stöder flera olika sorters visningsstilar och egenskaper och låter dig anpassa visningen exakt som du vill ha den.
    • Підтримка декількох різних типів та параметрів перегляду надає вам змогу налаштувати перегляд каталогів саме так, як вам це потрібно.
    • xxSupports several different kinds of view styles and properties and allows you to configure the view exactly how you want it.xx
    • +
    • 網址導覽列讓您可以快速瀏覽檔案與資料夾。
    • Split view, allowing you to easily copy or move files between locations.
    • العرض المقسوم، يسمح لك بنسخ ونقل الملفات بين مكانين بسهولة.
    • Divisió de visualització, permetent copiar o moure fitxers fàcilment entre les ubicacions.
    • @@ -198,6 +204,7 @@
    • Delad visning, som låter dig enkelt kopiera eller flytta filer mellan platser.
    • За допомогою режиму двопанельного розділеного перегляду ви зможе без проблем копіювати або пересувати файли між каталогами.
    • xxSplit view, allowing you to easily copy or move files between locations.xx
    • +
    • 支援數個檢視模式,您也可以調整檢視模式的屬性。
    • Additional information and shortcuts are available as dock-able panels, allowing you to move them around freely and display exactly what you want.
    • تتوفر معلومات واختصارات إضافية كألواح قابلة للتركيب، مما يسمح لك بنقلها بحريّة وعرضها بالضبط كما تريد.
    • Hi ha informació addicional i dreceres disponibles com a plafons acoblables, permetent moure'ls lliurement i mostrar exactament el què vulgueu.
    • @@ -224,6 +231,7 @@
    • 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.
    • За допомогою бічних пересувних панелей ви зможете отримувати додаткову інформацію та пересуватися каталогами. Ви можете розташувати ці панелі так, як вам це зручно, і наказати програмі показувати на них саме те, що вам потрібно.
    • xxAdditional information and shortcuts are available as dock-able panels, allowing you to move them around freely and display exactly what you want.xx
    • +
    • 分割檢視讓您可以輕鬆複製或移動檔案。
    • Multiple tab support
    • دعم تعدّد الألسنة
    • Implementació de pestanyes múltiples
    • @@ -253,6 +261,7 @@
    • Stöd för flera flikar
    • Підтримка роботи з вкладками.
    • xxMultiple tab supportxx
    • +
    • 額外資訊與嵌入式面板捷徑讓您可以輕易顯示您常用的項目。
    • Informational dialogues are displayed in an unobtrusive way.
    • El diàlegs informatius es mostren de manera no molesta.
    • Informationsdialoger vises på en ikke-forstyrrende måde.
    • @@ -279,6 +288,7 @@
    • Dialogrutor med information visas på ett diskret sätt.
    • Показ інформаційних панелей у зручний спосіб, що не заважає роботі.
    • xxInformational dialogues are displayed in an unobtrusive way.xx
    • +
    • 支援多分頁
    • Undo/redo support
    • Implementació de desfer/refer
    • Understøttelse af fortryd/gendan
    • @@ -306,6 +316,7 @@
    • Stöd för ångra och gör om
    • Підтримка скасовування та повторення дій.
    • xxUndo/redo supportxx
    • +
    • 以不唐突的方式顯示資訊對話框。
    • Transparent network access through the KIO system.
    • اتصال شبكيّ مباشر باستخدام نظام KIO.
    • Accés transparent a la xarxa a través del sistema KIO.
    • @@ -334,6 +345,7 @@
    • Transparent nätverksåtkomst via I/O-slavsystemet.
    • Прозорий доступ до ресурсів у мережі за допомогою системи KIO.
    • xxTransparent network access through the KIO system.xx
    • +
    • 復原支援
    http://dolphin.kde.org/ From b73aeb4598503ee7b4eb11f38edd26783d20bbb6 Mon Sep 17 00:00:00 2001 From: Mathieu Tarral Date: Sun, 10 Aug 2014 22:40:40 +0200 Subject: [PATCH 11/13] Fixes display issues of Dolphin statusbar widgets when a high DPI value is used (>= 196 for example). BUG: 334271 REVIEW: 119701 FIXED-IN: 4.14.1 --- src/statusbar/dolphinstatusbar.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/statusbar/dolphinstatusbar.cpp b/src/statusbar/dolphinstatusbar.cpp index 169395e633..282d385ca4 100644 --- a/src/statusbar/dolphinstatusbar.cpp +++ b/src/statusbar/dolphinstatusbar.cpp @@ -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); From 2d2d55f3df09614e6b7cf267771b52a04dcb5e28 Mon Sep 17 00:00:00 2001 From: Emmanuel Pescosta Date: Wed, 20 Aug 2014 23:06:39 +0200 Subject: [PATCH 12/13] Save the view states in addition to the view urls and splitter state in DolphinTabPage. Also added version numbers to view and tab state. REVIEW: 119792 --- src/dolphintabpage.cpp | 56 +++++++++++++++++++++++++++++++++++++++ src/dolphintabpage.h | 9 +++++++ src/dolphintabwidget.cpp | 13 ++++++--- src/views/dolphinview.cpp | 10 +++++++ 4 files changed, 85 insertions(+), 3 deletions(-) diff --git a/src/dolphintabpage.cpp b/src/dolphintabpage.cpp index 3d1ba5a3e8..f7000ea668 100644 --- a/src/dolphintabpage.cpp +++ b/src/dolphintabpage.cpp @@ -171,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; @@ -196,6 +200,58 @@ void DolphinTabPage::restoreState(const QByteArray& state) 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); + bool isSplitViewEnabled = false; stream >> isSplitViewEnabled; setSplitViewEnabled(isSplitViewEnabled); diff --git a/src/dolphintabpage.h b/src/dolphintabpage.h index de5a589152..2a406f4a9a 100644 --- a/src/dolphintabpage.h +++ b/src/dolphintabpage.h @@ -120,6 +120,15 @@ 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(DolphinViewContainer* viewContainer); void activeViewUrlChanged(const KUrl& url); diff --git a/src/dolphintabwidget.cpp b/src/dolphintabwidget.cpp index 76d4b8d48d..b1b2d858f7 100644 --- a/src/dolphintabwidget.cpp +++ b/src/dolphintabwidget.cpp @@ -72,7 +72,7 @@ void DolphinTabWidget::saveProperties(KConfigGroup& group) const for (int i = 0; i < tabCount; ++i) { const DolphinTabPage* tabPage = tabPageAt(i); - group.writeEntry("Tab " % QString::number(i), tabPage->saveState()); + group.writeEntry("Tab Data " % QString::number(i), tabPage->saveState()); } } @@ -83,8 +83,15 @@ void DolphinTabWidget::readProperties(const KConfigGroup& group) if (i >= count()) { openNewActivatedTab(); } - const QByteArray state = group.readEntry("Tab " % QString::number(i), QByteArray()); - tabPageAt(i)->restoreState(state); + 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); diff --git a/src/views/dolphinview.cpp b/src/views/dolphinview.cpp index 02b8815e07..1de973bd54 100644 --- a/src/views/dolphinview.cpp +++ b/src/views/dolphinview.cpp @@ -1167,6 +1167,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; @@ -1181,6 +1189,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) { From 4290827540d88829d3d06f828a11ac2c3df00d54 Mon Sep 17 00:00:00 2001 From: Arjun AK Date: Fri, 22 Aug 2014 18:42:50 +0530 Subject: [PATCH 13/13] Hide an already visible KMessageWidget message before showing a new one 1. Do some operation that causes the KMessageWidget to show an error message 2. Immediately Repeat the same action. The user has no way to know whether the error message is from the second operation or is a leftover from the first one. By hiding the widget first and then showing it using animatedShow(), the user can clearly see that a new message was generated. Also once the directory successfully loads, the widget should be hidden. BUG: 323077 FIXED-IN: 4.14.1 REVIEW: 119401 --- src/dolphinviewcontainer.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/dolphinviewcontainer.cpp b/src/dolphinviewcontainer.cpp index 2a45152bd0..93af3e8fbc 100644 --- a/src/dolphinviewcontainer.cpp +++ b/src/dolphinviewcontainer.cpp @@ -110,6 +110,7 @@ DolphinViewContainer::DolphinViewContainer(const KUrl& url, QWidget* parent) : m_view = new DolphinView(url, this); connect(m_view, SIGNAL(urlChanged(KUrl)), m_urlNavigator, SLOT(setUrl(KUrl))); connect(m_view, SIGNAL(urlChanged(KUrl)), m_messageWidget, SLOT(hide())); + connect(m_view, SIGNAL(directoryLoadingCompleted()), m_messageWidget, SLOT(hide())); connect(m_view, SIGNAL(writeStateChanged(bool)), this, SIGNAL(writeStateChanged(bool))); connect(m_view, SIGNAL(requestItemInfo(KFileItem)), this, SLOT(showItemInfo(KFileItem))); connect(m_view, SIGNAL(itemActivated(KFileItem)), this, SLOT(slotItemActivated(KFileItem))); @@ -277,6 +278,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(); }