Merge branch 'master' into frameworks

Conflicts:
	dolphin/src/dolphinmainwindow.cpp
	dolphin/src/dolphinviewcontainer.cpp
This commit is contained in:
Emmanuel Pescosta 2014-07-10 22:49:05 +02:00
commit fc4315d57e
10 changed files with 901 additions and 477 deletions

View file

@ -150,7 +150,9 @@ set(dolphin_SRCS
dolphinmainwindow.cpp
dolphinviewcontainer.cpp
dolphincontextmenu.cpp
dolphintabbar.cpp
dolphinrecenttabsmenu.cpp
dolphintabpage.cpp
filterbar/filterbar.cpp
main.cpp
panels/information/filemetadataconfigurationdialog.cpp

View file

@ -4,39 +4,54 @@
<metadata_license>CC0-1.0</metadata_license>
<project_license>GPL-2.0+</project_license>
<name>Dolphin</name>
<name xml:lang="ar">دولفين</name>
<name xml:lang="ca">Dolphin</name>
<name xml:lang="cs">Dolphin</name>
<name xml:lang="da">Dolphin</name>
<name xml:lang="de">Dolphin</name>
<name xml:lang="fi">Dolphin</name>
<name xml:lang="ia">Dolphin</name>
<name xml:lang="lt">Dolphin</name>
<name xml:lang="nds">Dolphin</name>
<name xml:lang="nl">Dolphin</name>
<name xml:lang="pl">Dolphin</name>
<name xml:lang="pt">Dolphin</name>
<name xml:lang="pt-BR">Dolphin</name>
<name xml:lang="ro">Dolphin</name>
<name xml:lang="sk">Dolphin</name>
<name xml:lang="sr">Делфин</name>
<name xml:lang="sr-Latn">Dolphin</name>
<name xml:lang="sr-ijekavian">Делфин</name>
<name xml:lang="sr-ijekavianlatin">Dolphin</name>
<name xml:lang="sv">Dolphin</name>
<name xml:lang="uk">Dolphin</name>
<name xml:lang="x-test">xxDolphinxx</name>
<summary>File Manager</summary>
<summary xml:lang="ar">مدير ملفات</summary>
<summary xml:lang="ca">Gestor de fitxers</summary>
<summary xml:lang="cs">Správce souborů</summary>
<summary xml:lang="da">Filhåndtering</summary>
<summary xml:lang="de">Dateiverwaltung</summary>
<summary xml:lang="fi">Tiedostonhallinta</summary>
<summary xml:lang="ia">Gerente de File</summary>
<summary xml:lang="lt">Failų tvarkyklė</summary>
<summary xml:lang="nds">Dateipleger</summary>
<summary xml:lang="nl">Bestandsbeheerder</summary>
<summary xml:lang="pl">Zarządzanie plikami</summary>
<summary xml:lang="pt">Gestor de Ficheiros</summary>
<summary xml:lang="pt-BR">Gerenciador de arquivos</summary>
<summary xml:lang="ro">Gestionar de fișiere</summary>
<summary xml:lang="sk">Správca súborov</summary>
<summary xml:lang="sr">Менаџер фајлова</summary>
<summary xml:lang="sr-Latn">Menadžer fajlova</summary>
<summary xml:lang="sr-ijekavian">Менаџер фајлова</summary>
<summary xml:lang="sr-ijekavianlatin">Menadžer fajlova</summary>
<summary xml:lang="sv">Filhanterare</summary>
<summary xml:lang="uk">Програма для керування файлами</summary>
<summary xml:lang="x-test">xxFile Managerxx</summary>
<description>
<p>Dolphin is a lightweight file manager. It has been designed with ease of use and simplicity in mind, while still allowing flexibility and customisation. This means that you can do your file management exactly the way you want to do it.</p>
<p xml:lang="ar">دولفين هو مدير ملفات خفيف. صُمِّم دولفين مع أخذ سهولة الاستخدام والبساطة بعين الاعتبار، مع السماح بالمرونة والتخصيص. يعني هذا أنه يمكنك إدارة ملفاتك كما تريد تماماً.</p>
<p xml:lang="ca">El Dolphin és un gestor de fitxers lleuger. S'ha dissenyat pensant en facilitar el seu ús i que sigui simple, permetent la flexibilitat i la personalització. Això vol dir que podeu fer la gestió dels vostres fitxers de la manera exacta com ho vulgueu fer.</p>
<p xml:lang="da">Dolphin er letvægtsfilhåndtering. Den er blevet designet med henblik på brugervenlighed og simpelhed, mens fleksibilitet og tilpasning stadig er muligt. Det betyder at du klare din filhåndtering nøjagtig på den måde du vil gøre det.</p>
<p xml:lang="fi">Dolphin on kevyt tiedostonhallinta. Se on suunniteltu helppokäyttöiseksi ja yksinkertaiseksi, mutta silti joustavaksi ja mukautettavaksi. Voit siis hallita tiedostojasi juuri niin kuin haluat.</p>
@ -47,22 +62,33 @@
<p xml:lang="pt">O Dolphin é um gestor de ficheiros leve. Foi desenhado com a facilidade de uso e simplicidade em mente, permitindo à mesma a flexibilidade e personalização. Isto significa que poderá fazer a sua gestão de ficheiros exactamente da forma que deseja.</p>
<p xml:lang="pt-BR">Dolphin é um gerenciador de arquivos leve e fácil de usar. Foi projetado para ser simples e ao mesmo tempo manter a flexibilidade e personalização. Isso significa que você poderá gerenciar seus arquivos da forma que desejar.</p>
<p xml:lang="sk">Dolphin je odľahčený správca súborov. Bol navrhnutý na jednoduché použitie a jednoduchosť, ale s možnosťami flexibility a prispôsobenia. To znamená, že môžete vykonávať správu súborov presne tak, ako chcete.</p>
<p xml:lang="sr">Делфин је лагани менаџер фајлова. Пројектован је да буде лак за употребу и једноставан, а да ипак омогућава флексибилност и прилагођавање. То значи да ће моћи да баратате фајловима тачно онако како бисте желели.</p>
<p xml:lang="sr-Latn">Dolphin je lagani menadžer fajlova. Projektovan je da bude lak za upotrebu i jednostavan, a da ipak omogućava fleksibilnost i prilagođavanje. To znači da će moći da baratate fajlovima tačno onako kako biste želeli.</p>
<p xml:lang="sr-ijekavian">Делфин је лагани менаџер фајлова. Пројектован је да буде лак за употребу и једноставан, а да ипак омогућава флексибилност и прилагођавање. То значи да ће моћи да баратате фајловима тачно онако како бисте желели.</p>
<p xml:lang="sr-ijekavianlatin">Dolphin je lagani menadžer fajlova. Projektovan je da bude lak za upotrebu i jednostavan, a da ipak omogućava fleksibilnost i prilagođavanje. To znači da će moći da baratate fajlovima tačno onako kako biste želeli.</p>
<p xml:lang="sv">Dolphin är en lättviktig filhanterare. Den har konstruerats med användbarhet och enkelhet i åtanke, men ändå tillåta flexibilitet och anpassning. Det betyder att du kan hantera filer exakt på det sätt som du vill göra det.</p>
<p xml:lang="uk">Dolphin — невибаглива до ресурсів програма для керування файлами. Її створено простою у користуванні і гнучкою у налаштовуванні. Це означає, що ви можете зробити керування файлами саме таким, як вам потрібно.</p>
<p xml:lang="x-test">xxDolphin is a lightweight file manager. It has been designed with ease of use and simplicity in mind, while still allowing flexibility and customisation. This means that you can do your file management exactly the way you want to do it.xx</p>
<p>Features:</p>
<p xml:lang="ar">المزايا:</p>
<p xml:lang="ca">Característiques:</p>
<p xml:lang="cs">Vlastnosti:</p>
<p xml:lang="da">Funktioner:</p>
<p xml:lang="de">Funktionen:</p>
<p xml:lang="fi">Ominaisuudet:</p>
<p xml:lang="ia">Characteristicas:</p>
<p xml:lang="lt">Galimybės</p>
<p xml:lang="nds">Markmalen:</p>
<p xml:lang="nl">Mogelijkheden:</p>
<p xml:lang="pl">Możliwości:</p>
<p xml:lang="pt">Características:</p>
<p xml:lang="pt-BR">Funcionalidades:</p>
<p xml:lang="ro">Caracteristici:</p>
<p xml:lang="sk">Funkcie:</p>
<p xml:lang="sr">Могућности:</p>
<p xml:lang="sr-Latn">Mogućnosti:</p>
<p xml:lang="sr-ijekavian">Могућности:</p>
<p xml:lang="sr-ijekavianlatin">Mogućnosti:</p>
<p xml:lang="sv">Funktioner:</p>
<p xml:lang="uk">Можливості:</p>
<p xml:lang="x-test">xxFeatures:xx</p>
@ -77,10 +103,15 @@
<li xml:lang="pt">Barra de navegação dos URL's, que lhe permite navegar rapidamente pela hierarquia de ficheiros e pastas.</li>
<li xml:lang="pt-BR">Barra de navegação de URLs, permitindo-lhe navegar rapidamente pela hierarquia de arquivos e pastas.</li>
<li xml:lang="sk">Navigačná lišta pre URL, umožňujúca vám rýchlu navigáciu cez hierarchiu súborov a priečinkov.</li>
<li xml:lang="sr">Навигациона трака (или мрвице) за УРЛ‑ове, преко које се можете брзо кретати кроз стабло фајлова и фасцикли.</li>
<li xml:lang="sr-Latn">Navigaciona traka (ili mrvice) za URLove, preko koje se možete brzo kretati kroz stablo fajlova i fascikli.</li>
<li xml:lang="sr-ijekavian">Навигациона трака (или мрвице) за УРЛ‑ове, преко које се можете брзо кретати кроз стабло фајлова и фасцикли.</li>
<li xml:lang="sr-ijekavianlatin">Navigaciona traka (ili mrvice) za URLove, preko koje se možete brzo kretati kroz stablo fajlova i fascikli.</li>
<li xml:lang="sv">Navigeringsrad (eller länkstig) för webbadresser, som låter dig snabbt navigera igenom hierarkin av filer och kataloger.</li>
<li xml:lang="uk">Панель навігації (звичайний режим і режим послідовної навігації) для адрес надає вам змогу швидко пересуватися ієрархією файлів та каталогів.</li>
<li xml:lang="x-test">xxNavigation (or breadcrumb) bar for URLs, allowing you to quickly navigate through the hierarchy of files and folders.xx</li>
<li>Supports several different kinds of view styles and properties and allows you to configure the view exactly how you want it.</li>
<li xml:lang="ar">يدعم العديد من الأنواع المختلفة من الخصائص وأنماط العرض ويسمك لك بضبط العرض كما تريد تماماً.</li>
<li xml:lang="ca">Accepta diferents classes diverses d'estils de visualització i propietats i us permet configurar la visualització exactament com la vulgueu.</li>
<li xml:lang="da">Understøtter flere forskellige slags visninger og egenskaber og lader dig konfigurere visningen nøjagtig som du vil have den.</li>
<li xml:lang="ia">Il supporta multe differente typos de stilos de vista e proprietates e il permitte te configurar le vista exactemente como tu vole.</li>
@ -90,10 +121,15 @@
<li xml:lang="pt">Suposta diferentes tipos de vistas e propriedades e permite-lhe configurar cada vista exactamente como a deseja.</li>
<li xml:lang="pt-BR">Suporte a diferentes tipos de visualização, permitindo-lhe configurar cada modo de exibição da forma que desejar.</li>
<li xml:lang="sk">Podporuje niekoľko rôznych typov štýlov zobrazenia a vlastností a umožňuje vám nastaviť pohľad presne tak, ako chcete.</li>
<li xml:lang="sr">Неколико начина приказа, са својствима које можете подесити по жељи.</li>
<li xml:lang="sr-Latn">Nekoliko načina prikaza, sa svojstvima koje možete podesiti po želji.</li>
<li xml:lang="sr-ijekavian">Неколико начина приказа, са својствима које можете подесити по жељи.</li>
<li xml:lang="sr-ijekavianlatin">Nekoliko načina prikaza, sa svojstvima koje možete podesiti po želji.</li>
<li xml:lang="sv">Stöder flera olika sorters visningsstilar och egenskaper och låter dig anpassa visningen exakt som du vill ha den.</li>
<li xml:lang="uk">Підтримка декількох різних типів та параметрів перегляду надає вам змогу налаштувати перегляд каталогів саме так, як вам це потрібно.</li>
<li xml:lang="x-test">xxSupports several different kinds of view styles and properties and allows you to configure the view exactly how you want it.xx</li>
<li>Split view, allowing you to easily copy or move files between locations.</li>
<li xml:lang="ar">العرض المقسوم، يسمح لك بنسخ ونقل الملفات بين مكانين بسهولة.</li>
<li xml:lang="ca">Divisió de visualització, permetent copiar o moure fitxers fàcilment entre les ubicacions.</li>
<li xml:lang="da">Opdelt visning lader dig kopiere filer mellem placeringer på en nem måde.</li>
<li xml:lang="ia">Scinde vista, il permitte te copiar o mover facilemente files inter locationes.</li>
@ -103,10 +139,15 @@
<li xml:lang="pt">Uma vista dividida, que lhe permite facilmente copiar ou mover os ficheiros entre locais.</li>
<li xml:lang="pt-BR">Um modo de exibição dividido, permitindo-lhe copiar ou mover arquivos facilmente entre locais.</li>
<li xml:lang="sk">Rozdelený pohľad, umožňuje vám jednoducho kopírovať alebo presúvať súbory medzi umiestneniami.</li>
<li xml:lang="sr">Подељени приказ, за лако копирање и премештање фајлова између локација.</li>
<li xml:lang="sr-Latn">Podeljeni prikaz, za lako kopiranje i premeštanje fajlova između lokacija.</li>
<li xml:lang="sr-ijekavian">Подељени приказ, за лако копирање и премештање фајлова између локација.</li>
<li xml:lang="sr-ijekavianlatin">Podeljeni prikaz, za lako kopiranje i premeštanje fajlova između lokacija.</li>
<li xml:lang="sv">Delad visning, som låter dig enkelt kopiera eller flytta filer mellan platser.</li>
<li xml:lang="uk">За допомогою режиму двопанельного розділеного перегляду ви зможе без проблем копіювати або пересувати файли між каталогами.</li>
<li xml:lang="x-test">xxSplit view, allowing you to easily copy or move files between locations.xx</li>
<li>Additional information and shortcuts are available as dock-able panels, allowing you to move them around freely and display exactly what you want.</li>
<li xml:lang="ar">تتوفر معلومات واختصارات إضافية كألواح قابلة للتركيب، مما يسمح لك بنقلها بحريّة وعرضها بالضبط كما تريد.</li>
<li xml:lang="ca">Hi ha informació addicional i dreceres disponibles com a plafons acoblables, permetent moure'ls lliurement i mostrar exactament el què vulgueu.</li>
<li xml:lang="da">Yderligere information og genveje er tilgængelige som dokbare paneler, som lader dig flytte dem frit omkring og vise nøjagtigt det du vil have.</li>
<li xml:lang="ia">Information additional e vias breve es disponibile como pannellos de basin (dock-panels), il permitte mover los liberemente e monstrar los exactemente como tu vole.</li>
@ -116,20 +157,31 @@
<li xml:lang="pt">Estão disponíveis informações e atalhos adicionais como painéis acopláveis, permitindo-lhe movê-los à vontade e apresentar como desejar.</li>
<li xml:lang="pt-BR">As informações e atalhos adicionais estão disponíveis na forma de painéis acopláveis, permitindo-lhe movê-los à vontade e apresentar como desejar.</li>
<li xml:lang="sk">Dodatočné informácie a skratky sú dostupné ako dokovateľné panely, umožňujúce vám ich voľný presun a zobrazenie presne tak, ako chcete.</li>
<li xml:lang="sr">Допунски подаци и пречице доступни су као усидриви панели, које можете поставити где вам одговара и подесити да приказују тачно оно што желите.</li>
<li xml:lang="sr-Latn">Dopunski podaci i prečice dostupni su kao usidrivi paneli, koje možete postaviti gde vam odgovara i podesiti da prikazuju tačno ono što želite.</li>
<li xml:lang="sr-ijekavian">Допунски подаци и пречице доступни су као усидриви панели, које можете поставити где вам одговара и подесити да приказују тачно оно што желите.</li>
<li xml:lang="sr-ijekavianlatin">Dopunski podaci i prečice dostupni su kao usidrivi paneli, koje možete postaviti gde vam odgovara i podesiti da prikazuju tačno ono što želite.</li>
<li xml:lang="sv">Ytterligare information och genvägar är tillgängliga som dockningsbara paneler, vilket låter dig flytta omkring dem fritt och visa exakt vad du vill.</li>
<li xml:lang="uk">За допомогою бічних пересувних панелей ви зможете отримувати додаткову інформацію та пересуватися каталогами. Ви можете розташувати ці панелі так, як вам це зручно, і наказати програмі показувати на них саме те, що вам потрібно.</li>
<li xml:lang="x-test">xxAdditional information and shortcuts are available as dock-able panels, allowing you to move them around freely and display exactly what you want.xx</li>
<li>Multiple tab support</li>
<li xml:lang="ar">دعم تعدّد الألسنة</li>
<li xml:lang="ca">Implementació de pestanyes múltiples</li>
<li xml:lang="da">Understøttelse af flere faneblade</li>
<li xml:lang="fi">Useiden välilehtien tuki</li>
<li xml:lang="ia">Supporto de scheda multiple</li>
<li xml:lang="lt">Daugelio kortelių palaikymas</li>
<li xml:lang="nds">Ünnerstütten för Paneels</li>
<li xml:lang="nl">Ondersteuning voor meerdere tabbladen</li>
<li xml:lang="pl">Obsługa wielu kart</li>
<li xml:lang="pt">Suporte para várias páginas</li>
<li xml:lang="pt-BR">Suporte a várias abas</li>
<li xml:lang="ro">Suport pentru file multiple</li>
<li xml:lang="sk">Podpora viacerých kariet</li>
<li xml:lang="sr">Вишеструки језичци.</li>
<li xml:lang="sr-Latn">Višestruki jezičci.</li>
<li xml:lang="sr-ijekavian">Вишеструки језичци.</li>
<li xml:lang="sr-ijekavianlatin">Višestruki jezičci.</li>
<li xml:lang="sv">Stöd för flera flikar</li>
<li xml:lang="uk">Підтримка роботи з вкладками.</li>
<li xml:lang="x-test">xxMultiple tab supportxx</li>
@ -143,6 +195,10 @@
<li xml:lang="pt">As janelas informativas são apresentadas de forma não-intrusiva.</li>
<li xml:lang="pt-BR">As janelas informativas são apresentadas de forma não-intrusiva.</li>
<li xml:lang="sk">Informačné dialógy sú zobrazené nevtieravým spôsobom.</li>
<li xml:lang="sr">Информативни дијалози који се ненаметљиво појављују.</li>
<li xml:lang="sr-Latn">Informativni dijalozi koji se nenametljivo pojavljuju.</li>
<li xml:lang="sr-ijekavian">Информативни дијалози који се ненаметљиво појављују.</li>
<li xml:lang="sr-ijekavianlatin">Informativni dijalozi koji se nenametljivo pojavljuju.</li>
<li xml:lang="sv">Dialogrutor med information visas på ett diskret sätt.</li>
<li xml:lang="uk">Показ інформаційних панелей у зручний спосіб, що не заважає роботі.</li>
<li xml:lang="x-test">xxInformational dialogues are displayed in an unobtrusive way.xx</li>
@ -156,11 +212,17 @@
<li xml:lang="pl">Obsługa cofnij/ponów</li>
<li xml:lang="pt">Suporte para desfazer/refazer</li>
<li xml:lang="pt-BR">Suporte para desfazer/refazer</li>
<li xml:lang="ro">Suport pentru desfacere/refacere</li>
<li xml:lang="sk">Podpora Späť/Znova</li>
<li xml:lang="sr">Опозивање и понављање.</li>
<li xml:lang="sr-Latn">Opozivanje i ponavljanje.</li>
<li xml:lang="sr-ijekavian">Опозивање и понављање.</li>
<li xml:lang="sr-ijekavianlatin">Opozivanje i ponavljanje.</li>
<li xml:lang="sv">Stöd för ångra och gör om</li>
<li xml:lang="uk">Підтримка скасовування та повторення дій.</li>
<li xml:lang="x-test">xxUndo/redo supportxx</li>
<li>Transparent network access through the KIO system.</li>
<li xml:lang="ar">اتصال شبكيّ مباشر باستخدام نظام KIO.</li>
<li xml:lang="ca">Accés transparent a la xarxa a través del sistema KIO.</li>
<li xml:lang="da">Transparent netværksadgang igennem KIO-systemet</li>
<li xml:lang="ia">Accesso de rete transparente a transverso del systema KIO.</li>
@ -169,7 +231,12 @@
<li xml:lang="pl">Przezroczysty dostęp do sieci przez system KIO.</li>
<li xml:lang="pt">Acesso transparente à rede através do sistema KIO.</li>
<li xml:lang="pt-BR">Acesso transparente à rede através do sistema KIO.</li>
<li xml:lang="ro">Acces transparent la rețea prin sistemul KIO.</li>
<li xml:lang="sk">Transparentný prístup na sieť cez KIO systém.</li>
<li xml:lang="sr">Прозиран мрежни приступ кроз систем КУ/И.</li>
<li xml:lang="sr-Latn">Proziran mrežni pristup kroz sistem KU/I.</li>
<li xml:lang="sr-ijekavian">Прозиран мрежни приступ кроз систем КУ/И.</li>
<li xml:lang="sr-ijekavianlatin">Proziran mrežni pristup kroz sistem KU/I.</li>
<li xml:lang="sv">Transparent nätverksåtkomst via I/O-slavsystemet.</li>
<li xml:lang="uk">Прозорий доступ до ресурсів у мережі за допомогою системи KIO.</li>
<li xml:lang="x-test">xxTransparent network access through the KIO system.xx</li>

View file

@ -35,7 +35,6 @@ DolphinApplication::DolphinApplication() :
m_mainWindow = new DolphinMainWindow();
m_mainWindow->setAttribute(Qt::WA_DeleteOnClose);
m_mainWindow->show();
KCmdLineArgs* args = KCmdLineArgs::parsedArgs();
@ -72,6 +71,9 @@ DolphinApplication::DolphinApplication() :
} else {
m_mainWindow->openDirectories(urls);
}
} else {
const KUrl homeUrl(GeneralSettings::homeUrl());
m_mainWindow->openNewActivatedTab(homeUrl);
}
if (resetSplitSettings) {
@ -79,6 +81,8 @@ DolphinApplication::DolphinApplication() :
}
args->clear();
m_mainWindow->show();
}
DolphinApplication::~DolphinApplication()

View file

@ -26,7 +26,9 @@
#include "dolphincontextmenu.h"
#include "dolphinnewfilemenu.h"
#include "dolphinrecenttabsmenu.h"
#include "dolphintabbar.h"
#include "dolphinviewcontainer.h"
#include "dolphintabpage.h"
#include "panels/folders/folderspanel.h"
#include "panels/places/placespanel.h"
#include "panels/information/informationpanel.h"
@ -75,10 +77,8 @@
#include <KStandardDirs>
#include <kstatusbar.h>
#include <KStandardAction>
#include <ktabbar.h>
#include <KToggleAction>
#include <KUrlNavigator>
#include <KUrl>
#include <KUrlComboBox>
#include <KToolInvocation>
@ -103,7 +103,7 @@ DolphinMainWindow::DolphinMainWindow() :
m_tabBar(0),
m_activeViewContainer(0),
m_centralWidgetLayout(0),
m_tabIndex(0),
m_tabIndex(-1),
m_viewTab(),
m_actionHandler(0),
m_remoteEncoding(0),
@ -114,10 +114,6 @@ DolphinMainWindow::DolphinMainWindow() :
{
setObjectName("Dolphin#");
m_viewTab.append(ViewTab());
ViewTab& viewTab = m_viewTab[m_tabIndex];
viewTab.wasActive = true; // The first opened tab is automatically active
connect(&DolphinNewFileMenuObserver::instance(), &DolphinNewFileMenuObserver::errorMessage,
this, &DolphinMainWindow::showErrorMessage);
@ -141,61 +137,41 @@ DolphinMainWindow::DolphinMainWindow() :
setAcceptDrops(true);
viewTab.splitter = new QSplitter(this);
viewTab.splitter->setChildrenCollapsible(false);
setupActions();
const KUrl homeUrl(generalSettings->homeUrl());
setUrlAsCaption(homeUrl);
m_actionHandler = new DolphinViewActionHandler(actionCollection(), this);
connect(m_actionHandler, &DolphinViewActionHandler::actionBeingHandled, this, &DolphinMainWindow::clearStatusBar);
connect(m_actionHandler, &DolphinViewActionHandler::createDirectory, this, &DolphinMainWindow::createDirectory);
viewTab.primaryView = createViewContainer(homeUrl, viewTab.splitter);
m_activeViewContainer = viewTab.primaryView;
connectViewSignals(m_activeViewContainer);
DolphinView* view = m_activeViewContainer->view();
m_activeViewContainer->show();
m_actionHandler->setCurrentView(view);
m_remoteEncoding = new DolphinRemoteEncoding(this, m_actionHandler);
connect(this, &DolphinMainWindow::urlChanged,
m_remoteEncoding, &DolphinRemoteEncoding::slotAboutToOpenUrl);
m_tabBar = new KTabBar(this);
m_tabBar->setMovable(true);
m_tabBar->setTabsClosable(true);
connect(m_tabBar, &KTabBar::currentChanged,
this, &DolphinMainWindow::setActiveTab);
connect(m_tabBar, &KTabBar::tabCloseRequested,
this, static_cast<void(DolphinMainWindow::*)(int)>(&DolphinMainWindow::closeTab));
connect(m_tabBar, &KTabBar::contextMenu,
this, &DolphinMainWindow::openTabContextMenu);
connect(m_tabBar, &KTabBar::newTabRequest,
this, static_cast<void(DolphinMainWindow::*)()>(&DolphinMainWindow::openNewTab));
connect(m_tabBar, &KTabBar::testCanDecode,
this, &DolphinMainWindow::slotTestCanDecode);
connect(m_tabBar, &KTabBar::mouseMiddleClick,
this, static_cast<void(DolphinMainWindow::*)(int)>(&DolphinMainWindow::closeTab));
connect(m_tabBar, &KTabBar::tabMoved,
this, &DolphinMainWindow::slotTabMoved);
connect(m_tabBar, &KTabBar::receivedDropEvent,
this, &DolphinMainWindow::tabDropEvent);
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);
m_centralWidgetLayout->addWidget(viewTab.splitter, 1);
setCentralWidget(centralWidget);
setupDockWidgets();
emit urlChanged(homeUrl);
setupGUI(Keys | Save | Create | ToolBar);
stateChanged("new_file");
@ -204,14 +180,6 @@ DolphinMainWindow::DolphinMainWindow() :
connect(clipboard, &QClipboard::dataChanged,
this, &DolphinMainWindow::updatePasteAction);
if (generalSettings->splitView()) {
toggleSplitView();
}
updateEditActions();
updatePasteAction();
updateViewActions();
updateGoActions();
QAction* showFilterBarAction = actionCollection()->action("show_filter_bar");
showFilterBarAction->setChecked(generalSettings->filterBar());
@ -235,37 +203,20 @@ DolphinMainWindow::~DolphinMainWindow()
void DolphinMainWindow::openDirectories(const QList<KUrl>& dirs)
{
if (dirs.isEmpty()) {
return;
}
if (dirs.count() == 1) {
m_activeViewContainer->setUrl(dirs.first());
return;
}
const int oldOpenTabsCount = m_viewTab.count();
const bool hasSplitView = GeneralSettings::splitView();
// Open each directory inside a new tab. If the "split view" option has been enabled,
// always show two directories within one tab.
QList<KUrl>::const_iterator it = dirs.constBegin();
while (it != dirs.constEnd()) {
openNewTab(*it);
++it;
const KUrl& primaryUrl = *(it++);
if (hasSplitView && (it != dirs.constEnd())) {
const int tabIndex = m_viewTab.count() - 1;
m_viewTab[tabIndex].secondaryView->setUrl(*it);
++it;
const KUrl& secondaryUrl = *(it++);
openNewTab(primaryUrl, secondaryUrl);
} else {
openNewTab(primaryUrl);
}
}
// Remove the previously opened tabs
for (int i = 0; i < oldOpenTabsCount; ++i) {
closeTab(0);
}
}
void DolphinMainWindow::openFiles(const QList<KUrl>& files)
@ -290,14 +241,9 @@ void DolphinMainWindow::openFiles(const QList<KUrl>& files)
// 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.
const int tabCount = m_viewTab.count();
for (int i = 0; i < tabCount; ++i) {
m_viewTab[i].primaryView->view()->markUrlsAsSelected(files);
m_viewTab[i].primaryView->view()->markUrlAsCurrent(files.at(0));
if (m_viewTab[i].secondaryView) {
m_viewTab[i].secondaryView->view()->markUrlsAsSelected(files);
m_viewTab[i].secondaryView->view()->markUrlAsCurrent(files.at(0));
}
foreach (DolphinTabPage* tabPage, m_viewTab) {
tabPage->markUrlsAsSelected(files);
tabPage->markUrlAsCurrent(files.first());
}
}
@ -352,11 +298,11 @@ void DolphinMainWindow::changeUrl(const KUrl& url)
updateViewActions();
updateGoActions();
setUrlAsCaption(url);
if (m_viewTab.count() > 1) {
m_tabBar->setTabText(m_tabIndex, squeezedText(tabName(m_activeViewContainer->url())));
}
const QString iconName = KIO::iconNameForUrl(url);
m_tabBar->setTabIcon(m_tabIndex, QIcon::fromTheme(iconName));
m_tabBar->setTabText(m_tabIndex, squeezedText(tabName(view->url())));
emit urlChanged(url);
}
}
@ -379,11 +325,7 @@ void DolphinMainWindow::slotSelectionChanged(const KFileItemList& selection)
{
updateEditActions();
Q_ASSERT(m_viewTab[m_tabIndex].primaryView);
int selectedUrlsCount = m_viewTab[m_tabIndex].primaryView->view()->selectedItemsCount();
if (m_viewTab[m_tabIndex].secondaryView) {
selectedUrlsCount += m_viewTab[m_tabIndex].secondaryView->view()->selectedItemsCount();
}
const int selectedUrlsCount = m_viewTab.at(m_tabIndex)->selectedItemsCount();
QAction* compareFilesAction = actionCollection()->action("compare_files");
if (selectedUrlsCount == 2) {
@ -448,41 +390,41 @@ void DolphinMainWindow::openNewTab()
}
}
void DolphinMainWindow::openNewTab(const KUrl& url)
void DolphinMainWindow::openNewTab(const KUrl& primaryUrl, const KUrl& secondaryUrl)
{
QWidget* focusWidget = QApplication::focusWidget();
if (m_viewTab.count() == 1) {
// Only one view is open currently and hence no tab is shown at
// all. Before creating a tab for 'url', provide a tab for the current URL.
const KUrl currentUrl = m_activeViewContainer->url();
m_tabBar->addTab(QIcon::fromTheme(KIO::iconNameForUrl(currentUrl)),
squeezedText(tabName(currentUrl)));
m_tabBar->blockSignals(false);
DolphinTabPage* tabPage = new DolphinTabPage(primaryUrl, secondaryUrl, this);
m_viewTab.append(tabPage);
connect(tabPage, SIGNAL(activeViewChanged()),
this, SLOT(activeViewChanged()));
// The places-selector from the URL navigator should only be shown
// if the places dock is invisible
QDockWidget* placesDock = findChild<QDockWidget*>("placesDock");
const bool placesSelectorVisible = !placesDock || !placesDock->isVisible();
tabPage->setPlacesSelectorVisible(placesSelectorVisible);
DolphinViewContainer* primaryContainer = tabPage->primaryViewContainer();
connectViewSignals(primaryContainer);
if (tabPage->splitViewEnabled()) {
DolphinViewContainer* secondaryContainer = tabPage->secondaryViewContainer();
connectViewSignals(secondaryContainer);
}
m_tabBar->addTab(QIcon::fromTheme(KIO::iconNameForUrl(url)),
squeezedText(tabName(url)));
tabPage->hide();
ViewTab viewTab;
viewTab.splitter = new QSplitter(this);
viewTab.splitter->setChildrenCollapsible(false);
viewTab.primaryView = createViewContainer(url, viewTab.splitter);
viewTab.primaryView->setActive(false);
connectViewSignals(viewTab.primaryView);
m_tabBar->addTab(QIcon::fromTheme(KIO::iconNameForUrl(primaryUrl)),
squeezedText(tabName(primaryUrl)));
m_viewTab.append(viewTab);
actionCollection()->action("close_tab")->setEnabled(true);
actionCollection()->action("activate_prev_tab")->setEnabled(true);
actionCollection()->action("activate_next_tab")->setEnabled(true);
// Provide a split view, if the startup settings are set this way
if (GeneralSettings::splitView()) {
const int newTabIndex = m_viewTab.count() - 1;
createSecondaryView(newTabIndex);
m_viewTab[newTabIndex].secondaryView->setActive(true);
m_viewTab[newTabIndex].isPrimaryViewActive = false;
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) {
@ -492,17 +434,24 @@ void DolphinMainWindow::openNewTab(const KUrl& url)
}
}
void DolphinMainWindow::openNewActivatedTab(const KUrl& url)
void DolphinMainWindow::openNewActivatedTab(const KUrl& primaryUrl, const KUrl& secondaryUrl)
{
openNewTab(url);
m_tabBar->setCurrentIndex(m_viewTab.count() - 1);
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();
m_tabBar->setCurrentIndex(tabIndex);
setActiveTab(tabIndex);
}
}
@ -513,7 +462,7 @@ void DolphinMainWindow::activatePrevTab()
if (tabIndex == -1) {
tabIndex = m_tabBar->count() - 1;
}
m_tabBar->setCurrentIndex(tabIndex);
setActiveTab(tabIndex);
}
}
@ -549,24 +498,16 @@ void DolphinMainWindow::openInNewWindow()
}
}
void DolphinMainWindow::toggleActiveView()
{
if (!m_viewTab[m_tabIndex].secondaryView) {
// only one view is available
return;
}
Q_ASSERT(m_activeViewContainer);
Q_ASSERT(m_viewTab[m_tabIndex].primaryView);
DolphinViewContainer* left = m_viewTab[m_tabIndex].primaryView;
DolphinViewContainer* right = m_viewTab[m_tabIndex].secondaryView;
setActiveViewContainer(m_activeViewContainer == right ? left : right);
}
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();
}
@ -638,17 +579,8 @@ void DolphinMainWindow::saveProperties(KConfigGroup& group)
group.writeEntry("Active Tab Index", m_tabBar->currentIndex());
for (int i = 0; i < tabCount; ++i) {
const DolphinViewContainer* cont = m_viewTab[i].primaryView;
group.writeEntry(tabProperty("Primary URL", i), cont->url().url());
group.writeEntry(tabProperty("Primary Editable", i),
cont->urlNavigator()->isUrlEditable());
cont = m_viewTab[i].secondaryView;
if (cont) {
group.writeEntry(tabProperty("Secondary URL", i), cont->url().url());
group.writeEntry(tabProperty("Secondary Editable", i),
cont->urlNavigator()->isUrlEditable());
}
const DolphinTabPage* tabPage = m_viewTab.at(i);
group.writeEntry("Tab " % QString::number(i), tabPage->saveState());
}
}
@ -656,38 +588,9 @@ void DolphinMainWindow::readProperties(const KConfigGroup& group)
{
const int tabCount = group.readEntry("Tab Count", 1);
for (int i = 0; i < tabCount; ++i) {
DolphinViewContainer* cont = m_viewTab[i].primaryView;
cont->setUrl(group.readEntry(tabProperty("Primary URL", i)));
const bool editable = group.readEntry(tabProperty("Primary Editable", i), false);
cont->urlNavigator()->setUrlEditable(editable);
cont = m_viewTab[i].secondaryView;
const QString secondaryUrl = group.readEntry(tabProperty("Secondary URL", i));
if (!secondaryUrl.isEmpty()) {
if (!cont) {
// a secondary view should be shown, but no one is available
// currently -> create a new view
toggleSplitView();
cont = m_viewTab[i].secondaryView;
Q_ASSERT(cont);
}
// The right view must be activated before the URL is set. Changing
// the URL in the right view will emit the right URL navigator's
// urlChanged(KUrl) signal, which is connected to the changeUrl(KUrl)
// slot. That slot will change the URL in the left view if it is still
// active. See https://bugs.kde.org/show_bug.cgi?id=330047.
setActiveViewContainer(cont);
cont->setUrl(secondaryUrl);
const bool editable = group.readEntry(tabProperty("Secondary Editable", i), false);
cont->urlNavigator()->setUrlEditable(editable);
} else if (cont) {
// no secondary view should be shown, but the default setting shows
// one already -> close the view
toggleSplitView();
}
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) {
@ -800,28 +703,11 @@ void DolphinMainWindow::invertSelection()
void DolphinMainWindow::toggleSplitView()
{
if (!m_viewTab[m_tabIndex].secondaryView) {
createSecondaryView(m_tabIndex);
setActiveViewContainer(m_viewTab[m_tabIndex].secondaryView);
} else if (m_activeViewContainer == m_viewTab[m_tabIndex].secondaryView) {
// remove secondary view
m_viewTab[m_tabIndex].secondaryView->close();
m_viewTab[m_tabIndex].secondaryView->deleteLater();
m_viewTab[m_tabIndex].secondaryView = 0;
DolphinTabPage* tabPage = m_viewTab.at(m_tabIndex);
tabPage->setSplitViewEnabled(!tabPage->splitViewEnabled());
setActiveViewContainer(m_viewTab[m_tabIndex].primaryView);
} else {
// The primary view is active and should be closed. Hence from a users point of view
// the content of the secondary view should be moved to the primary view.
// From an implementation point of view it is more efficient to close
// the primary view and exchange the internal pointers afterwards.
m_viewTab[m_tabIndex].primaryView->close();
m_viewTab[m_tabIndex].primaryView->deleteLater();
m_viewTab[m_tabIndex].primaryView = m_viewTab[m_tabIndex].secondaryView;
m_viewTab[m_tabIndex].secondaryView = 0;
setActiveViewContainer(m_viewTab[m_tabIndex].primaryView);
if (tabPage->splitViewEnabled()) {
connectViewSignals(tabPage->secondaryViewContainer());
}
updateViewActions();
@ -888,14 +774,8 @@ void DolphinMainWindow::togglePanelLockState()
void DolphinMainWindow::slotPlacesPanelVisibilityChanged(bool visible)
{
const int tabCount = m_viewTab.count();
for (int i = 0; i < tabCount; ++i) {
ViewTab& tab = m_viewTab[i];
Q_ASSERT(tab.primaryView);
tab.primaryView->urlNavigator()->setPlacesSelectorVisible(!visible);
if (tab.secondaryView) {
tab.secondaryView->urlNavigator()->setPlacesSelectorVisible(!visible);
}
foreach (DolphinTabPage* tabPage, m_viewTab) {
tabPage->setPlacesSelectorVisible(visible);
}
}
@ -964,15 +844,7 @@ void DolphinMainWindow::goHome(Qt::MouseButtons buttons)
void DolphinMainWindow::compareFiles()
{
const DolphinViewContainer* primaryViewContainer = m_viewTab[m_tabIndex].primaryView;
Q_ASSERT(primaryViewContainer);
KFileItemList items = primaryViewContainer->view()->selectedItems();
const DolphinViewContainer* secondaryViewContainer = m_viewTab[m_tabIndex].secondaryView;
if (secondaryViewContainer) {
items.append(secondaryViewContainer->view()->selectedItems());
}
const KFileItemList items = m_viewTab.at(m_tabIndex)->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
@ -1042,42 +914,23 @@ void DolphinMainWindow::setActiveTab(int index)
return;
}
m_tabBar->setCurrentIndex(index);
// hide current tab content
ViewTab& hiddenTab = m_viewTab[m_tabIndex];
hiddenTab.isPrimaryViewActive = hiddenTab.primaryView->isActive();
hiddenTab.primaryView->setActive(false);
if (hiddenTab.secondaryView) {
hiddenTab.secondaryView->setActive(false);
if (m_tabIndex >= 0) {
DolphinTabPage* hiddenTabPage = m_viewTab.at(m_tabIndex);
hiddenTabPage->hide();
m_centralWidgetLayout->removeWidget(hiddenTabPage);
}
QSplitter* splitter = m_viewTab[m_tabIndex].splitter;
splitter->hide();
m_centralWidgetLayout->removeWidget(splitter);
// show active tab content
m_tabIndex = index;
ViewTab& viewTab = m_viewTab[index];
m_centralWidgetLayout->addWidget(viewTab.splitter, 1);
viewTab.primaryView->show();
if (viewTab.secondaryView) {
viewTab.secondaryView->show();
}
viewTab.splitter->show();
DolphinTabPage* tabPage = m_viewTab.at(index);
m_centralWidgetLayout->addWidget(tabPage, 1);
tabPage->show();
if (!viewTab.wasActive) {
viewTab.wasActive = true;
// If the tab has not been activated yet the size of the KItemListView is
// undefined and results in an unwanted animation. To prevent this a
// reloading of the directory gets triggered.
viewTab.primaryView->view()->reload();
if (viewTab.secondaryView) {
viewTab.secondaryView->view()->reload();
}
}
setActiveViewContainer(viewTab.isPrimaryViewActive ? viewTab.primaryView :
viewTab.secondaryView);
setActiveViewContainer(tabPage->activeViewContainer());
}
void DolphinMainWindow::closeTab()
@ -1100,17 +953,18 @@ void DolphinMainWindow::closeTab(int index)
m_tabBar->setCurrentIndex((index > 0) ? index - 1 : 1);
}
const KUrl primaryUrl(m_viewTab[index].primaryView->url());
const KUrl secondaryUrl(m_viewTab[index].secondaryView ? m_viewTab[index].secondaryView->url() : KUrl());
emit rememberClosedTab(primaryUrl, secondaryUrl);
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[index].primaryView->deleteLater();
if (m_viewTab[index].secondaryView) {
m_viewTab[index].secondaryView->deleteLater();
}
m_viewTab[index].splitter->deleteLater();
m_viewTab.erase(m_viewTab.begin() + index);
m_viewTab.removeAt(index);
tabPage->deleteLater();
m_tabBar->blockSignals(true);
m_tabBar->removeTab(index);
@ -1122,64 +976,33 @@ void DolphinMainWindow::closeTab(int index)
// if only one tab is left, also remove the tab entry so that
// closing the last tab is not possible
if (m_viewTab.count() == 1) {
m_tabBar->removeTab(0);
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::openTabContextMenu(int index, const QPoint& pos)
void DolphinMainWindow::detachTab(int index)
{
KMenu menu(this);
Q_ASSERT(index >= 0);
QAction* newTabAction = menu.addAction(QIcon::fromTheme("tab-new"), i18nc("@action:inmenu", "New Tab"));
newTabAction->setShortcut(actionCollection()->action("new_tab")->shortcut());
const QString separator(QLatin1Char(' '));
QString command = QLatin1String("dolphin");
QAction* detachTabAction = menu.addAction(QIcon::fromTheme("tab-detach"), i18nc("@action:inmenu", "Detach Tab"));
QAction* closeOtherTabsAction = menu.addAction(QIcon::fromTheme("tab-close-other"), i18nc("@action:inmenu", "Close Other Tabs"));
QAction* closeTabAction = menu.addAction(QIcon::fromTheme("tab-close"), i18nc("@action:inmenu", "Close Tab"));
closeTabAction->setShortcut(actionCollection()->action("close_tab")->shortcut());
QAction* selectedAction = menu.exec(pos);
if (selectedAction == newTabAction) {
const ViewTab& tab = m_viewTab[index];
Q_ASSERT(tab.primaryView);
const KUrl url = tab.secondaryView && tab.secondaryView->isActive() ?
tab.secondaryView->url() : tab.primaryView->url();
openNewTab(url);
m_tabBar->setCurrentIndex(m_viewTab.count() - 1);
} else if (selectedAction == detachTabAction) {
const QString separator(QLatin1Char(' '));
QString command = QLatin1String("dolphin");
const ViewTab& tab = m_viewTab[index];
Q_ASSERT(tab.primaryView);
command += separator + tab.primaryView->url().url();
if (tab.secondaryView) {
command += separator + tab.secondaryView->url().url();
command += separator + QLatin1String("-split");
}
KRun::runCommand(command, this);
closeTab(index);
} else if (selectedAction == closeOtherTabsAction) {
const int count = m_tabBar->count();
for (int i = 0; i < index; ++i) {
closeTab(0);
}
for (int i = index + 1; i < count; ++i) {
closeTab(1);
}
} else if (selectedAction == closeTabAction) {
closeTab(index);
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)
@ -1188,11 +1011,6 @@ void DolphinMainWindow::slotTabMoved(int from, int to)
m_tabIndex = m_tabBar->currentIndex();
}
void DolphinMainWindow::slotTestCanDecode(const QDragMoveEvent* event, bool& canDecode)
{
canDecode = KUrl::List::canDecode(event->mimeData());
}
void DolphinMainWindow::handleUrl(const KUrl& url)
{
delete m_lastHandleUrlStatJob;
@ -1230,9 +1048,8 @@ void DolphinMainWindow::tabDropEvent(int tab, QDropEvent* event)
{
const KUrl::List urls = KUrl::List::fromMimeData(event->mimeData());
if (!urls.isEmpty() && tab != -1) {
const ViewTab& viewTab = m_viewTab[tab];
const DolphinView* view = viewTab.isPrimaryViewActive ? viewTab.primaryView->view()
: viewTab.secondaryView->view();
const DolphinView* view = m_viewTab.at(tab)->activeViewContainer()->view();
QString error;
DragAndDropHelper::dropUrls(view->rootItem(), view->url(), event, error);
if (!error.isEmpty()) {
@ -1401,37 +1218,22 @@ void DolphinMainWindow::slotPlaceActivated(const KUrl& url)
}
}
void DolphinMainWindow::restoreClosedTab(const KUrl& primaryUrl, const KUrl& secondaryUrl)
void DolphinMainWindow::activeViewChanged()
{
openNewActivatedTab(primaryUrl);
if (!secondaryUrl.isEmpty() && secondaryUrl.isValid()) {
const int index = m_tabBar->currentIndex();
createSecondaryView(index);
setActiveViewContainer(m_viewTab[index].secondaryView);
m_viewTab[index].secondaryView->setUrl(secondaryUrl);
}
const DolphinTabPage* tabPage = m_viewTab.at(m_tabIndex);
setActiveViewContainer(tabPage->activeViewContainer());
}
void DolphinMainWindow::setActiveViewContainer(DolphinViewContainer* viewContainer)
{
Q_ASSERT(viewContainer);
Q_ASSERT((viewContainer == m_viewTab[m_tabIndex].primaryView) ||
(viewContainer == m_viewTab[m_tabIndex].secondaryView));
Q_ASSERT((viewContainer == m_viewTab.at(m_tabIndex)->primaryViewContainer()) ||
(viewContainer == m_viewTab.at(m_tabIndex)->secondaryViewContainer()));
if (m_activeViewContainer == viewContainer) {
return;
}
m_activeViewContainer->setActive(false);
m_activeViewContainer = viewContainer;
// Activating the view container might trigger a recursive setActiveViewContainer() call
// inside DolphinMainWindow::toggleActiveView() when having a split view. Temporary
// disconnect the activated() signal in this case:
disconnect(m_activeViewContainer->view(), &DolphinView::activated, this, &DolphinMainWindow::toggleActiveView);
m_activeViewContainer->setActive(true);
connect(m_activeViewContainer->view(), &DolphinView::activated, this, &DolphinMainWindow::toggleActiveView);
m_actionHandler->setCurrentView(viewContainer->view());
updateHistory();
@ -1442,26 +1244,12 @@ void DolphinMainWindow::setActiveViewContainer(DolphinViewContainer* viewContain
const KUrl url = m_activeViewContainer->url();
setUrlAsCaption(url);
if (m_viewTab.count() > 1) {
m_tabBar->setTabText(m_tabIndex, tabName(url));
m_tabBar->setTabIcon(m_tabIndex, QIcon::fromTheme(KIO::iconNameForUrl(url)));
}
m_tabBar->setTabText(m_tabIndex, squeezedText(tabName(url)));
m_tabBar->setTabIcon(m_tabIndex, QIcon::fromTheme(KIO::iconNameForUrl(url)));
emit urlChanged(url);
}
DolphinViewContainer* DolphinMainWindow::createViewContainer(const KUrl& url, QWidget* parent)
{
DolphinViewContainer* container = new DolphinViewContainer(url, parent);
// The places-selector from the URL navigator should only be shown
// if the places dock is invisible
QDockWidget* placesDock = findChild<QDockWidget*>("placesDock");
container->urlNavigator()->setPlacesSelectorVisible(!placesDock || !placesDock->isVisible());
return container;
}
void DolphinMainWindow::setupActions()
{
// setup 'File' menu
@ -1529,7 +1317,6 @@ void DolphinMainWindow::setupActions()
QAction* split = actionCollection()->addAction("split_view");
split->setShortcut(Qt::Key_F3);
updateSplitAction();
connect(split, &QAction::triggered, this, &DolphinMainWindow::toggleSplitView);
QAction* reload = actionCollection()->addAction("reload");
@ -1565,7 +1352,7 @@ void DolphinMainWindow::setupActions()
connect(this, SIGNAL(rememberClosedTab(KUrl,KUrl)),
recentTabsMenu, SLOT(rememberClosedTab(KUrl,KUrl)));
connect(recentTabsMenu, SIGNAL(restoreClosedTab(KUrl,KUrl)),
this, SLOT(restoreClosedTab(KUrl,KUrl)));
this, SLOT(openNewActivatedTab(KUrl,KUrl)));
KStandardAction::forward(this, SLOT(goForward()), actionCollection());
KStandardAction::up(this, SLOT(goUp()), actionCollection());
@ -1686,8 +1473,8 @@ void DolphinMainWindow::setupDockWidgets()
foldersPanel, &FoldersPanel::setUrl);
connect(foldersPanel, &FoldersPanel::folderActivated,
this, &DolphinMainWindow::changeUrl);
connect(foldersPanel, &FoldersPanel::folderMiddleClicked,
this, static_cast<void(DolphinMainWindow::*)(const KUrl&)>(&DolphinMainWindow::openNewTab));
connect(foldersPanel, SIGNAL(folderMiddleClicked(KUrl)),
this, SLOT(openNewTab(KUrl)));
connect(foldersPanel, &FoldersPanel::errorMessage,
this, &DolphinMainWindow::slotPanelErrorMessage);
@ -1738,8 +1525,8 @@ void DolphinMainWindow::setupDockWidgets()
addDockWidget(Qt::LeftDockWidgetArea, placesDock);
connect(placesPanel, &PlacesPanel::placeActivated,
this, &DolphinMainWindow::slotPlaceActivated);
connect(placesPanel, &PlacesPanel::placeMiddleClicked,
this, static_cast<void(DolphinMainWindow::*)(const KUrl&)>(&DolphinMainWindow::openNewTab));
connect(placesPanel, SIGNAL(placeMiddleClicked(KUrl)),
this, SLOT(openNewTab(KUrl)));
connect(placesPanel, &PlacesPanel::errorMessage,
this, &DolphinMainWindow::slotPanelErrorMessage);
connect(this, &DolphinMainWindow::urlChanged,
@ -1871,33 +1658,16 @@ bool DolphinMainWindow::addActionToMenu(QAction* action, KMenu* menu)
void DolphinMainWindow::refreshViews()
{
Q_ASSERT(m_viewTab[m_tabIndex].primaryView);
// remember the current active view, as because of
// the refreshing the active view might change to
// the secondary view
DolphinViewContainer* activeViewContainer = m_activeViewContainer;
const int tabCount = m_viewTab.count();
for (int i = 0; i < tabCount; ++i) {
m_viewTab[i].primaryView->readSettings();
if (m_viewTab[i].secondaryView) {
m_viewTab[i].secondaryView->readSettings();
}
foreach (DolphinTabPage* tabPage, m_viewTab) {
tabPage->refreshViews();
}
setActiveViewContainer(activeViewContainer);
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();
const ViewTab& activeTab = m_viewTab[m_tabIndex];
const bool toggle = ( splitView && !activeTab.secondaryView)
|| (!splitView && activeTab.secondaryView);
if (toggle) {
toggleSplitView();
}
m_viewTab.at(m_tabIndex)->setSplitViewEnabled(splitView);
updateSplitAction();
}
emit settingsChanged();
@ -1915,15 +1685,13 @@ void DolphinMainWindow::connectViewSignals(DolphinViewContainer* container)
connect(container, &DolphinViewContainer::writeStateChanged,
this, &DolphinMainWindow::slotWriteStateChanged);
DolphinView* view = container->view();
const DolphinView* view = container->view();
connect(view, &DolphinView::selectionChanged,
this, &DolphinMainWindow::slotSelectionChanged);
connect(view, &DolphinView::requestItemInfo,
this, &DolphinMainWindow::slotRequestItemInfo);
connect(view, &DolphinView::activated,
this, &DolphinMainWindow::toggleActiveView);
connect(view, &DolphinView::tabRequested,
this, static_cast<void(DolphinMainWindow::*)(const KUrl&)>(&DolphinMainWindow::openNewTab));
connect(view, SIGNAL(tabRequested(KUrl)),
this, SLOT(openNewTab(KUrl)));
connect(view, &DolphinView::requestContextMenu,
this, &DolphinMainWindow::openContextMenu);
connect(view, &DolphinView::directoryLoadingStarted,
@ -1942,22 +1710,23 @@ void DolphinMainWindow::connectViewSignals(DolphinViewContainer* container)
this, &DolphinMainWindow::updateHistory);
connect(navigator, &KUrlNavigator::editableStateChanged,
this, &DolphinMainWindow::slotEditableStateChanged);
connect(navigator, &KUrlNavigator::tabRequested,
this, static_cast<void(DolphinMainWindow::*)(const KUrl&)>(&DolphinMainWindow::openNewTab));
connect(navigator, SIGNAL(tabRequested(KUrl)),
this, SLOT(openNewTab(KUrl)));
}
void DolphinMainWindow::updateSplitAction()
{
QAction* splitAction = actionCollection()->action("split_view");
if (m_viewTab[m_tabIndex].secondaryView) {
if (m_activeViewContainer == m_viewTab[m_tabIndex].secondaryView) {
splitAction->setText(i18nc("@action:intoolbar Close right view", "Close"));
splitAction->setToolTip(i18nc("@info", "Close right view"));
splitAction->setIcon(QIcon::fromTheme("view-right-close"));
} else {
const DolphinTabPage* tabPage = m_viewTab.at(m_tabIndex);
if (tabPage->splitViewEnabled()) {
if (tabPage->primaryViewActive()) {
splitAction->setText(i18nc("@action:intoolbar Close left view", "Close"));
splitAction->setToolTip(i18nc("@info", "Close left view"));
splitAction->setIcon(QIcon::fromTheme("view-left-close"));
splitAction->setIcon(KIcon("view-left-close"));
} else {
splitAction->setText(i18nc("@action:intoolbar Close right view", "Close"));
splitAction->setToolTip(i18nc("@info", "Close right view"));
splitAction->setIcon(KIcon("view-right-close"));
}
} else {
splitAction->setText(i18nc("@action:intoolbar Split view", "Split"));
@ -1997,35 +1766,6 @@ bool DolphinMainWindow::isKompareInstalled() const
return installed;
}
void DolphinMainWindow::createSecondaryView(int tabIndex)
{
ViewTab& viewTab = m_viewTab[tabIndex];
QSplitter* splitter = viewTab.splitter;
const int newWidth = (viewTab.primaryView->width() - splitter->handleWidth()) / 2;
const DolphinView* view = viewTab.primaryView->view();
// The final parent of the new view container will be set by adding it
// to the splitter. However, we must make sure that the DolphinMainWindow
// is a parent of the view container already when it is constructed
// because this enables the container's KFileItemModel to assign its
// dir lister to the right main window. The dir lister can then cache
// authentication data.
viewTab.secondaryView = createViewContainer(view->url(), this);
splitter->addWidget(viewTab.secondaryView);
splitter->setSizes(QList<int>() << newWidth << newWidth);
connectViewSignals(viewTab.secondaryView);
viewTab.secondaryView->setActive(false);
viewTab.secondaryView->resize(newWidth, viewTab.primaryView->height());
viewTab.secondaryView->show();
}
QString DolphinMainWindow::tabProperty(const QString& property, int tabIndex) const
{
return "Tab " + QString::number(tabIndex) + ' ' + property;
}
void DolphinMainWindow::setUrlAsCaption(const KUrl& url)
{
QString caption;

View file

@ -29,6 +29,7 @@
#include <ksortablelist.h>
#include <kxmlguiwindow.h>
#include <KIcon>
#include <KUrl>
#include <QList>
#include <QWeakPointer>
@ -38,15 +39,15 @@ typedef KIO::FileUndoManager::CommandType CommandType;
class DolphinViewActionHandler;
class DolphinApplication;
class DolphinSettingsDialog;
class DolphinTabBar;
class DolphinViewContainer;
class DolphinRemoteEncoding;
class DolphinTabPage;
class KAction;
class KFileItem;
class KFileItemList;
class KJob;
class KNewFileMenu;
class KTabBar;
class KUrl;
class QSplitter;
class QToolButton;
class QVBoxLayout;
@ -89,13 +90,6 @@ public:
*/
void openFiles(const QList<KUrl>& files);
/**
* Returns true, if the main window contains two instances
* of a view container. The active view constainer can be
* accessed by DolphinMainWindow::activeViewContainer().
*/
bool isSplit() const;
/**
* Returns the 'Create New...' sub menu which also can be shared
* with other menus (e. g. a context menu).
@ -354,15 +348,22 @@ private slots:
void openNewTab();
/**
* Opens a new tab in the background showing the URL \a url.
* Opens a new tab in the background showing the URL \a primaryUrl and the
* optional URL \a secondaryUrl.
*/
void openNewTab(const KUrl& url);
void openNewTab(const KUrl& primaryUrl, const KUrl& secondaryUrl = KUrl());
/**
* Opens a new tab showing the URL \a url and activates
* the tab.
* Opens a new tab showing the URL \a primaryUrl and the optional URL
* \a secondaryUrl and activates the tab.
*/
void openNewActivatedTab(const KUrl& url);
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();
@ -378,9 +379,6 @@ private slots:
*/
void openInNewWindow();
/** Toggles the active view if two views are shown within the main window. */
void toggleActiveView();
/**
* Indicates in the statusbar that the execution of the command \a command
* has been finished.
@ -402,10 +400,10 @@ private slots:
void closeTab(int index);
/**
* Opens a context menu for the tab with the index \a index
* on the position \a pos.
* Opens the tab with the index \a index in a new Dolphin instance and closes
* this tab.
*/
void openTabContextMenu(int index, const QPoint& pos);
void detachTab(int index);
/**
* Is connected to the QTabBar signal tabMoved(int from, int to).
@ -414,12 +412,6 @@ private slots:
*/
void slotTabMoved(int from, int to);
/**
* Is connected to the KTabBar signal testCanDecode() and adjusts
* the output parameter \a accept.
*/
void slotTestCanDecode(const QDragMoveEvent* event, bool& accept);
/**
* If the URL can be listed, open it in the current view, otherwise
* run it through KRun.
@ -475,11 +467,7 @@ private slots:
*/
void slotPlaceActivated(const KUrl& url);
/**
* Is called when the user wants to reopen a previously closed \a tab from
* the recent tabs menu.
*/
void restoreClosedTab(const KUrl& primaryUrl, const KUrl& secondaryUrl);
void activeViewChanged();
private:
/**
@ -490,11 +478,6 @@ private:
*/
void setActiveViewContainer(DolphinViewContainer* view);
/**
* Creates a view container and does a default initialization.
*/
DolphinViewContainer* createViewContainer(const KUrl& url, QWidget* parent);
void setupActions();
void setupDockWidgets();
void updateEditActions();
@ -530,17 +513,9 @@ private:
/** Returns the name of the tab for the URL \a url. */
QString tabName(const KUrl& url) const;
bool isKompareInstalled() const;
void createSecondaryView(int tabIndex);
/**
* Helper method for saveProperties() and readProperties(): Returns
* the property string for a tab with the index \a tabIndex and
* the property \a property.
*/
QString tabProperty(const QString& property, int tabIndex) const;
/**
* Sets the window caption to url.fileName() if this is non-empty,
* "/" if the URL is "file:///", and url.protocol() otherwise.
@ -575,23 +550,13 @@ private:
};
KNewFileMenu* m_newFileMenu;
KTabBar* m_tabBar;
DolphinTabBar* m_tabBar;
DolphinViewContainer* m_activeViewContainer;
QVBoxLayout* m_centralWidgetLayout;
int m_id;
// Members for the tab-handling:
struct ViewTab
{
ViewTab() : isPrimaryViewActive(true), wasActive(false), primaryView(0), secondaryView(0), splitter(0) {}
bool isPrimaryViewActive;
bool wasActive;
DolphinViewContainer* primaryView;
DolphinViewContainer* secondaryView;
QSplitter* splitter;
};
int m_tabIndex;
QList<ViewTab> m_viewTab;
QList<DolphinTabPage*> m_viewTab;
DolphinViewActionHandler* m_actionHandler;
DolphinRemoteEncoding* m_remoteEncoding;
@ -609,11 +574,6 @@ inline DolphinViewContainer* DolphinMainWindow::activeViewContainer() const
return m_activeViewContainer;
}
inline bool DolphinMainWindow::isSplit() const
{
return m_viewTab[m_tabIndex].secondaryView != 0;
}
inline KNewFileMenu* DolphinMainWindow::newFileMenu() const
{
return m_newFileMenu;

174
src/dolphintabbar.cpp Normal file
View file

@ -0,0 +1,174 @@
/***************************************************************************
* Copyright (C) 2014 by Emmanuel Pescosta <emmanuelpescosta099@gmail.com> *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA *
***************************************************************************/
#include "dolphintabbar.h"
#include <QTimer>
#include <QDragEnterEvent>
#include <KLocalizedString>
#include <KMenu>
#include <KIcon>
#include <KUrl>
DolphinTabBar::DolphinTabBar(QWidget* parent) :
QTabBar(parent),
m_autoActivationIndex(-1)
{
setAcceptDrops(true);
setSelectionBehaviorOnRemove(QTabBar::SelectPreviousTab);
setMovable(true);
setTabsClosable(true);
m_autoActivationTimer = new QTimer(this);
m_autoActivationTimer->setSingleShot(true);
m_autoActivationTimer->setInterval(800);
connect(m_autoActivationTimer, SIGNAL(timeout()),
this, SLOT(slotAutoActivationTimeout()));
}
void DolphinTabBar::dragEnterEvent(QDragEnterEvent* event)
{
const QMimeData* mimeData = event->mimeData();
const int index = tabAt(event->pos());
if (KUrl::List::canDecode(mimeData)) {
event->acceptProposedAction();
updateAutoActivationTimer(index);
}
QTabBar::dragEnterEvent(event);
}
void DolphinTabBar::dragLeaveEvent(QDragLeaveEvent* event)
{
updateAutoActivationTimer(-1);
QTabBar::dragLeaveEvent(event);
}
void DolphinTabBar::dragMoveEvent(QDragMoveEvent* event)
{
const QMimeData* mimeData = event->mimeData();
const int index = tabAt(event->pos());
if (KUrl::List::canDecode(mimeData)) {
updateAutoActivationTimer(index);
}
QTabBar::dragMoveEvent(event);
}
void DolphinTabBar::dropEvent(QDropEvent* event)
{
// Disable the auto activation timer
updateAutoActivationTimer(-1);
const QMimeData* mimeData = event->mimeData();
const int index = tabAt(event->pos());
if (index >= 0 && KUrl::List::canDecode(mimeData)) {
emit tabDropEvent(index, event);
}
QTabBar::dropEvent(event);
}
void DolphinTabBar::mousePressEvent(QMouseEvent* event)
{
const int index = tabAt(event->pos());
if (index >= 0 && event->button() == Qt::MiddleButton) {
// Mouse middle click on a tab closes this tab.
emit tabCloseRequested(index);
return;
}
QTabBar::mousePressEvent(event);
}
void DolphinTabBar::mouseDoubleClickEvent(QMouseEvent* event)
{
const int index = tabAt(event->pos());
if (index < 0) {
// Double click on the empty tabbar area opens a new activated tab
// with the url from the current tab.
emit openNewActivatedTab(currentIndex());
return;
}
QTabBar::mouseDoubleClickEvent(event);
}
void DolphinTabBar::contextMenuEvent(QContextMenuEvent* event)
{
const int index = tabAt(event->pos());
if (index >= 0) {
// Tab context menu
KMenu menu(this);
QAction* newTabAction = menu.addAction(KIcon("tab-new"), i18nc("@action:inmenu", "New Tab"));
QAction* detachTabAction = menu.addAction(KIcon("tab-detach"), i18nc("@action:inmenu", "Detach Tab"));
QAction* closeOtherTabsAction = menu.addAction(KIcon("tab-close-other"), i18nc("@action:inmenu", "Close Other Tabs"));
QAction* closeTabAction = menu.addAction(KIcon("tab-close"), i18nc("@action:inmenu", "Close Tab"));
QAction* selectedAction = menu.exec(event->globalPos());
if (selectedAction == newTabAction) {
emit openNewActivatedTab(index);
} else if (selectedAction == detachTabAction) {
emit tabDetachRequested(index);
} else if (selectedAction == closeOtherTabsAction) {
const int tabCount = count();
for (int i = 0; i < index; i++) {
emit tabCloseRequested(0);
}
for (int i = index + 1; i < tabCount; i++) {
emit tabCloseRequested(1);
}
} else if (selectedAction == closeTabAction) {
emit tabCloseRequested(index);
}
return;
}
QTabBar::contextMenuEvent(event);
}
void DolphinTabBar::slotAutoActivationTimeout()
{
if (m_autoActivationIndex >= 0) {
setCurrentIndex(m_autoActivationIndex);
updateAutoActivationTimer(-1);
}
}
void DolphinTabBar::updateAutoActivationTimer(const int index)
{
if (m_autoActivationIndex != index) {
m_autoActivationIndex = index;
if (m_autoActivationIndex < 0) {
m_autoActivationTimer->stop();
} else {
m_autoActivationTimer->start();
}
}
}

65
src/dolphintabbar.h Normal file
View file

@ -0,0 +1,65 @@
/***************************************************************************
* Copyright (C) 2014 by Emmanuel Pescosta <emmanuelpescosta099@gmail.com> *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA *
***************************************************************************/
#ifndef DOLPHIN_TAB_BAR_H
#define DOLPHIN_TAB_BAR_H
#include <QTabBar>
class DolphinTabBar : public QTabBar
{
Q_OBJECT
public:
explicit DolphinTabBar(QWidget* parent);
signals:
void openNewActivatedTab(int index);
void tabDropEvent(int index, QDropEvent* event);
void tabDetachRequested(int index);
protected:
virtual void dragEnterEvent(QDragEnterEvent* event);
virtual void dragLeaveEvent(QDragLeaveEvent* event);
virtual void dragMoveEvent(QDragMoveEvent* event);
virtual void dropEvent(QDropEvent* event);
virtual void mousePressEvent(QMouseEvent* event);
virtual void mouseDoubleClickEvent(QMouseEvent* event);
/**
* Opens a context menu for the tab on the \a event position.
*/
virtual void contextMenuEvent(QContextMenuEvent* event);
private slots:
void slotAutoActivationTimeout();
private:
/**
* If \a index is a valid index (>= 0), store the index and start the timer
* (if the interval >= 0 ms). If the index is not valid (< 0), stop the timer.
*/
void updateAutoActivationTimer(const int index);
private:
QTimer* m_autoActivationTimer;
int m_autoActivationIndex;
};
#endif // DOLPHIN_TAB_BAR_H

258
src/dolphintabpage.cpp Normal file
View file

@ -0,0 +1,258 @@
/***************************************************************************
* Copyright (C) 2014 by Emmanuel Pescosta <emmanuelpescosta099@gmail.com> *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA *
***************************************************************************/
#include "dolphintabpage.h"
#include "dolphinviewcontainer.h"
#include "dolphin_generalsettings.h"
#include <QSplitter>
DolphinTabPage::DolphinTabPage(const KUrl& primaryUrl, const KUrl& secondaryUrl, QWidget* parent) :
QWidget(parent),
m_primaryViewActive(true),
m_splitViewEnabled(false)
{
QVBoxLayout* layout = new QVBoxLayout(this);
layout->setSpacing(0);
layout->setMargin(0);
m_splitter = new QSplitter(Qt::Horizontal, this);
m_splitter->setChildrenCollapsible(false);
layout->addWidget(m_splitter);
// Create a new primary view
m_primaryViewContainer = createViewContainer(primaryUrl);
connect(m_primaryViewContainer->view(), SIGNAL(urlChanged(KUrl)),
this, SIGNAL(activeViewUrlChanged(KUrl)));
m_splitter->addWidget(m_primaryViewContainer);
m_primaryViewContainer->show();
if (secondaryUrl.isValid() || GeneralSettings::splitView()) {
// Provide a secondary view, if the given secondary url is valid or if the
// startup settings are set this way (use the url of the primary view).
m_splitViewEnabled = true;
const KUrl& url = secondaryUrl.isValid() ? secondaryUrl : primaryUrl;
m_secondaryViewContainer = createViewContainer(url);
m_splitter->addWidget(m_secondaryViewContainer);
m_secondaryViewContainer->show();
}
m_primaryViewContainer->setActive(true);
}
bool DolphinTabPage::primaryViewActive() const
{
return m_primaryViewActive;
}
bool DolphinTabPage::splitViewEnabled() const
{
return m_splitViewEnabled;
}
void DolphinTabPage::setSplitViewEnabled(bool enabled)
{
if (m_splitViewEnabled != enabled) {
m_splitViewEnabled = enabled;
if (enabled) {
const KUrl& url = m_primaryViewContainer->url();
m_secondaryViewContainer = createViewContainer(url);
m_splitter->addWidget(m_secondaryViewContainer);
m_secondaryViewContainer->show();
m_secondaryViewContainer->setActive(true);
} else {
// Close the view which is active.
DolphinViewContainer* view = activeViewContainer();
if (m_primaryViewActive) {
// If the primary view is active, we have to swap the pointers
// because the secondary view will be the new primary view.
qSwap(m_primaryViewContainer, m_secondaryViewContainer);
}
m_primaryViewContainer->setActive(true);
view->close();
view->deleteLater();
}
}
}
DolphinViewContainer* DolphinTabPage::primaryViewContainer() const
{
return m_primaryViewContainer;
}
DolphinViewContainer* DolphinTabPage::secondaryViewContainer() const
{
return m_secondaryViewContainer;
}
DolphinViewContainer* DolphinTabPage::activeViewContainer() const
{
return m_primaryViewActive ? m_primaryViewContainer :
m_secondaryViewContainer;
}
KFileItemList DolphinTabPage::selectedItems() const
{
KFileItemList items = m_primaryViewContainer->view()->selectedItems();
if (m_splitViewEnabled) {
items += m_secondaryViewContainer->view()->selectedItems();
}
return items;
}
int DolphinTabPage::selectedItemsCount() const
{
int selectedItemsCount = m_primaryViewContainer->view()->selectedItemsCount();
if (m_splitViewEnabled) {
selectedItemsCount += m_secondaryViewContainer->view()->selectedItemsCount();
}
return selectedItemsCount;
}
void DolphinTabPage::markUrlsAsSelected(const QList<KUrl>& urls)
{
m_primaryViewContainer->view()->markUrlsAsSelected(urls);
if (m_splitViewEnabled) {
m_secondaryViewContainer->view()->markUrlsAsSelected(urls);
}
}
void DolphinTabPage::markUrlAsCurrent(const KUrl& url)
{
m_primaryViewContainer->view()->markUrlAsCurrent(url);
if (m_splitViewEnabled) {
m_secondaryViewContainer->view()->markUrlAsCurrent(url);
}
}
void DolphinTabPage::setPlacesSelectorVisible(bool visible)
{
m_primaryViewContainer->urlNavigator()->setPlacesSelectorVisible(visible);
if (m_splitViewEnabled) {
m_secondaryViewContainer->urlNavigator()->setPlacesSelectorVisible(visible);
}
}
void DolphinTabPage::refreshViews()
{
m_primaryViewContainer->readSettings();
if (m_splitViewEnabled) {
m_secondaryViewContainer->readSettings();
}
}
QByteArray DolphinTabPage::saveState() const
{
QByteArray state;
QDataStream stream(&state, QIODevice::WriteOnly);
stream << m_splitViewEnabled;
stream << m_primaryViewContainer->url();
stream << m_primaryViewContainer->urlNavigator()->isUrlEditable();
if (m_splitViewEnabled) {
stream << m_secondaryViewContainer->url();
stream << m_secondaryViewContainer->urlNavigator()->isUrlEditable();
}
stream << m_primaryViewActive;
stream << m_splitter->saveState();
return state;
}
void DolphinTabPage::restoreState(const QByteArray& state)
{
QByteArray sd = state;
QDataStream stream(&sd, QIODevice::ReadOnly);
bool isSplitViewEnabled = false;
stream >> isSplitViewEnabled;
setSplitViewEnabled(isSplitViewEnabled);
KUrl primaryUrl;
stream >> primaryUrl;
m_primaryViewContainer->setUrl(primaryUrl);
bool primaryUrlEditable;
stream >> primaryUrlEditable;
m_primaryViewContainer->urlNavigator()->setUrlEditable(primaryUrlEditable);
if (isSplitViewEnabled) {
KUrl secondaryUrl;
stream >> secondaryUrl;
m_secondaryViewContainer->setUrl(secondaryUrl);
bool secondaryUrlEditable;
stream >> secondaryUrlEditable;
m_secondaryViewContainer->urlNavigator()->setUrlEditable(secondaryUrlEditable);
}
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::slotViewActivated()
{
const DolphinView* oldActiveView = activeViewContainer()->view();
// Set the view, which was active before, to inactive
// and update the active view type.
if (m_splitViewEnabled) {
activeViewContainer()->setActive(false);
m_primaryViewActive = !m_primaryViewActive;
} else {
m_primaryViewActive = true;
}
const DolphinView* newActiveView = activeViewContainer()->view();
if (newActiveView != oldActiveView) {
disconnect(oldActiveView, SIGNAL(urlChanged(KUrl)),
this, SIGNAL(activeViewUrlChanged(KUrl)));
connect(newActiveView, SIGNAL(urlChanged(KUrl)),
this, SIGNAL(activeViewUrlChanged(KUrl)));
}
emit activeViewUrlChanged(activeViewContainer()->url());
emit activeViewChanged();
}
DolphinViewContainer* DolphinTabPage::createViewContainer(const KUrl& url) const
{
DolphinViewContainer* container = new DolphinViewContainer(url, m_splitter);
container->setActive(false);
const DolphinView* view = container->view();
connect(view, SIGNAL(activated()),
this, SLOT(slotViewActivated()));
return container;
}

152
src/dolphintabpage.h Normal file
View file

@ -0,0 +1,152 @@
/***************************************************************************
* Copyright (C) 2014 by Emmanuel Pescosta <emmanuelpescosta099@gmail.com> *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA *
***************************************************************************/
#ifndef DOLPHIN_TAB_PAGE_H
#define DOLPHIN_TAB_PAGE_H
#include <QWidget>
#include <QPointer>
#include <KUrl>
class QSplitter;
class DolphinViewContainer;
class KFileItemList;
class DolphinTabPage : public QWidget
{
Q_OBJECT
public:
explicit DolphinTabPage(const KUrl& primaryUrl, const KUrl& secondaryUrl = KUrl(), QWidget* parent = 0);
/**
* @return True if primary view is the active view in this tab.
*/
bool primaryViewActive() const;
/**
* @return True if split view is enabled.
*/
bool splitViewEnabled() const;
/**
* Enables or disables the split view mode.
*
* If \a enabled is true, it creates a secondary view with the url of the primary view.
*/
void setSplitViewEnabled(bool enabled);
/**
* @return The primary view containter.
*/
DolphinViewContainer* primaryViewContainer() const;
/**
* @return The secondary view containter, can be 0 if split view is disabled.
*/
DolphinViewContainer* secondaryViewContainer() const;
/**
* @return DolphinViewContainer of the active view
*/
DolphinViewContainer* activeViewContainer() const;
/**
* Returns the selected items. The list is empty if no item has been
* selected.
*/
KFileItemList selectedItems() const;
/**
* Returns the number of selected items (this is faster than
* invoking selectedItems().count()).
*/
int selectedItemsCount() const;
/**
* Marks the items indicated by \p urls to get selected after the
* directory DolphinView::url() has been loaded. Note that nothing
* gets selected if no loading of a directory has been triggered
* by DolphinView::setUrl() or DolphinView::reload().
*/
void markUrlsAsSelected(const QList<KUrl>& urls);
/**
* Marks the item indicated by \p url to be scrolled to and as the
* current item after directory DolphinView::url() has been loaded.
*/
void markUrlAsCurrent(const KUrl& url);
/**
* Sets the places selector visible, if \a visible is true.
* The places selector allows to select the places provided
* by the places model passed in the constructor. Per default
* the places selector is visible.
*/
void setPlacesSelectorVisible(bool visible);
/**
* Refreshes the views of the main window by recreating them according to
* the given Dolphin settings.
*/
void refreshViews();
/**
* Saves all tab related properties (urls, splitter layout, ...).
*
* @return A byte-array which contains all properties.
*/
QByteArray saveState() const;
/**
* Restores all tab related properties (urls, splitter layout, ...) from
* the given \a state.
*/
void restoreState(const QByteArray& state);
signals:
void activeViewChanged();
void activeViewUrlChanged(const KUrl& url);
private slots:
/**
* Handles the view activated event.
*
* It sets the previous active view to inactive, updates the current
* active view type and triggers the activeViewChanged event.
*/
void slotViewActivated();
private:
/**
* Creates a new view container and does the default initialization.
*/
DolphinViewContainer* createViewContainer(const KUrl& url) const;
private:
QSplitter* m_splitter;
QPointer<DolphinViewContainer> m_primaryViewContainer;
QPointer<DolphinViewContainer> m_secondaryViewContainer;
bool m_primaryViewActive;
bool m_splitViewEnabled;
};
#endif // DOLPHIN_TAB_PAGE_H

View file

@ -143,6 +143,8 @@ DolphinViewContainer::DolphinViewContainer(const KUrl& url, QWidget* parent) :
this, &DolphinViewContainer::showErrorMessage);
connect(m_view, &DolphinView::urlIsFileError,
this, &DolphinViewContainer::slotUrlIsFileError);
connect(m_view, &DolphinView::activated,
this, &DolphinViewContainer::activate);
connect(m_urlNavigator, &KUrlNavigator::urlAboutToBeChanged,
this, &DolphinViewContainer::slotUrlNavigatorLocationAboutToBeChanged);