From 65e752ce9fbcc47c17d845c37b5b49f56cd973a7 Mon Sep 17 00:00:00 2001 From: Benjamin C Meyer Date: Wed, 14 Mar 2007 02:54:08 +0100 Subject: [PATCH] Refactor out the view into its own class and add autotest for it Add new icons for the toolbar and application from Oxygen --- autotests/history/historytest.cpp | 51 +++++++------ {src => autotests/view}/.gitignore | 4 +- autotests/view/view.pro | 9 +++ autotests/view/viewtest.cpp | 78 ++++++++++++++++++++ pics/ambit.png | Bin 13171 -> 12806 bytes pics/arrow-left.png | Bin 0 -> 3087 bytes pics/arrow-right.png | Bin 0 -> 3110 bytes pics/columnview.png | Bin 0 -> 1001 bytes pics/iconview.png | Bin 0 -> 1682 bytes pics/treeview.png | Bin 0 -> 1046 bytes src/.gitignore | 1 + src/ambit.qrc | 10 +++ src/history.cpp | 40 +++++------ src/history.h | 10 +-- src/main.cpp | 2 +- src/mainwindow.cpp | 141 ++++++++++++------------------------ src/mainwindow.h | 25 +++---- src/src.pro | 4 +- src/view.cpp | 143 +++++++++++++++++++++++++++++++++++++ src/{history.h => view.h} | 52 ++++++++------ 20 files changed, 386 insertions(+), 184 deletions(-) copy {src => autotests/view}/.gitignore (50%) create mode 100644 autotests/view/view.pro create mode 100644 autotests/view/viewtest.cpp rewrite pics/ambit.png (99%) create mode 100644 pics/arrow-left.png create mode 100644 pics/arrow-right.png create mode 100644 pics/columnview.png create mode 100644 pics/iconview.png create mode 100644 pics/treeview.png create mode 100644 src/ambit.qrc create mode 100644 src/view.cpp copy src/{history.h => view.h} (51%) diff --git a/autotests/history/historytest.cpp b/autotests/history/historytest.cpp index 7b4e3ab..014afb2 100644 --- a/autotests/history/historytest.cpp +++ b/autotests/history/historytest.cpp @@ -38,8 +38,10 @@ void HistoryTest::empty() connect(&his, SIGNAL(goToIndex(const QModelIndex &)), &his, SLOT(currentChanged(const QModelIndex &))); QSignalSpy spy(&his, SIGNAL(goToIndex(const QModelIndex &))); - QCOMPARE(his.backAction()->isEnabled(), false); - QCOMPARE(his.forwardAction()->isEnabled(), false); + his.goBackAction = History::backAction(this); + his.goForwardAction = History::forwardAction(this); + QCOMPARE(his.goBackAction->isEnabled(), false); + QCOMPARE(his.goForwardAction->isEnabled(), false); his.goBack(); his.goForward(); QCOMPARE(spy.count(), 0); @@ -51,6 +53,8 @@ void HistoryTest::back() { qRegisterMetaType("QModelIndex"); History his; + his.goBackAction = History::backAction(this); + his.goForwardAction = History::forwardAction(this); connect(&his, SIGNAL(goToIndex(const QModelIndex &)), &his, SLOT(currentChanged(const QModelIndex &))); QSignalSpy spy(&his, SIGNAL(goToIndex(const QModelIndex &))); @@ -61,17 +65,17 @@ void HistoryTest::back() QModelIndex temp = model.index(QDir::tempPath()); his.currentChanged(home); - QCOMPARE(his.backAction()->isEnabled(), false); - QCOMPARE(his.forwardAction()->isEnabled(), false); + QCOMPARE(his.goBackAction->isEnabled(), false); + QCOMPARE(his.goForwardAction->isEnabled(), false); his.currentChanged(temp); - QCOMPARE(his.backAction()->isEnabled(), true); - QCOMPARE(his.forwardAction()->isEnabled(), false); + QCOMPARE(his.goBackAction->isEnabled(), true); + QCOMPARE(his.goForwardAction->isEnabled(), false); his.currentChanged(desktop); QCOMPARE(spy.count(), 0); his.goBack(); - QCOMPARE(his.backAction()->isEnabled(), true); - QCOMPARE(his.forwardAction()->isEnabled(), true); + QCOMPARE(his.goBackAction->isEnabled(), true); + QCOMPARE(his.goForwardAction->isEnabled(), true); QCOMPARE(spy.count(), 1); QModelIndex idx = (spy.last().first()).value(); QCOMPARE(idx, temp); @@ -79,21 +83,25 @@ void HistoryTest::back() his.goBack(); idx = (spy.last().first()).value(); QCOMPARE(idx, home); - QCOMPARE(his.backAction()->isEnabled(), false); - QCOMPARE(his.forwardAction()->isEnabled(), true); + QCOMPARE(his.goBackAction->isEnabled(), false); + QCOMPARE(his.goForwardAction->isEnabled(), true); QCOMPARE(spy.count(), 2); // nothing should change at this point his.goBack(); QCOMPARE(spy.count(), 2); - QCOMPARE(his.backAction()->isEnabled(), false); - QCOMPARE(his.forwardAction()->isEnabled(), true); + QCOMPARE(his.goBackAction->isEnabled(), false); + QCOMPARE(his.goForwardAction->isEnabled(), true); } void HistoryTest::forward() { qRegisterMetaType("QModelIndex"); History his; + his.goBackAction = History::backAction(this); + connect(his.goBackAction, SIGNAL(triggered()), &his, SLOT(goBack())); + his.goForwardAction = History::forwardAction(this); + connect(his.goForwardAction, SIGNAL(triggered()), &his, SLOT(goForward())); connect(&his, SIGNAL(goToIndex(const QModelIndex &)), &his, SLOT(currentChanged(const QModelIndex &))); QSignalSpy spy(&his, SIGNAL(goToIndex(const QModelIndex &))); @@ -107,29 +115,29 @@ void HistoryTest::forward() his.currentChanged(desktop); his.goBack(); - QCOMPARE(his.forwardAction()->isEnabled(), true); + QCOMPARE(his.goForwardAction->isEnabled(), true); QCOMPARE((spy.last().first()).value(), temp); his.goForward(); QCOMPARE((spy.last().first()).value(), desktop); - QCOMPARE(his.backAction()->isEnabled(), true); - QCOMPARE(his.forwardAction()->isEnabled(), false); + QCOMPARE(his.goBackAction->isEnabled(), true); + QCOMPARE(his.goForwardAction->isEnabled(), false); QCOMPARE(spy.count(), 2); his.goBack(); QCOMPARE((spy.last().first()).value(), temp); - QCOMPARE(his.backAction()->isEnabled(), true); + QCOMPARE(his.goBackAction->isEnabled(), true); his.goBack(); QCOMPARE((spy.last().first()).value(), home); - QCOMPARE(his.backAction()->isEnabled(), false); - QCOMPARE(his.forwardAction()->isEnabled(), true); + QCOMPARE(his.goBackAction->isEnabled(), false); + QCOMPARE(his.goForwardAction->isEnabled(), true); QCOMPARE(spy.count(), 4); // test the actions - his.forwardAction()->activate(QAction::Trigger); + his.goForwardAction->activate(QAction::Trigger); QCOMPARE((spy.last().first()).value(), temp); - his.backAction()->activate(QAction::Trigger); + his.goBackAction->activate(QAction::Trigger); QCOMPARE((spy.last().first()).value(), home); QCOMPARE(spy.count(), 6); @@ -143,9 +151,8 @@ void HistoryTest::forward() his.goBack(); QCOMPARE((spy.last().first()).value(), home); his.currentChanged(desktop); - QCOMPARE(his.forwardAction()->isEnabled(), false); + QCOMPARE(his.goForwardAction->isEnabled(), false); } QTEST_MAIN(HistoryTest) #include "historytest.moc" - diff --git a/src/.gitignore b/autotests/view/.gitignore similarity index 50% copy from src/.gitignore copy to autotests/view/.gitignore index fe23c40..b36229f 100644 --- a/src/.gitignore +++ b/autotests/view/.gitignore @@ -1,4 +1,6 @@ +view *.o +*.moc moc_* Makefile -Ambit.app +history diff --git a/autotests/view/view.pro b/autotests/view/view.pro new file mode 100644 index 0000000..0141c3d --- /dev/null +++ b/autotests/view/view.pro @@ -0,0 +1,9 @@ +SOURCES = viewtest.cpp +CONFIG += qtestlib +CONFIG -= app_bundle + +INCLUDEPATH += ../../src/ +DEPENDPATH += ../../src/ + +SOURCES += view.cpp history.cpp iconview.cpp treeview.cpp columnview.cpp +HEADERS += view.h history.h iconview.h treeview.h columnview.h \ No newline at end of file diff --git a/autotests/view/viewtest.cpp b/autotests/view/viewtest.cpp new file mode 100644 index 0000000..460476e --- /dev/null +++ b/autotests/view/viewtest.cpp @@ -0,0 +1,78 @@ +/** + * Copyright (C) 2007 Benjamin C. Meyer + * + * 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 +#include + +#include "view.h" +#include "qfilesystemmodel_p.h" + +class ViewTest : public QObject +{ + Q_OBJECT + +private slots: + void empty(); + void mode(); + void rootIndex(); +}; + +void ViewTest::empty() +{ + View view; + QCOMPARE(QModelIndex(), view.rootIndex()); + QCOMPARE(View::Icon, view.currentMode()); + QCOMPARE(0, ((int)view.currentView())); + QVERIFY(view.history != 0); + view.setCurrentMode(View::List); + view.goUp(); + view.setRootIndex(QModelIndex()); + view.fileOpen(); +} + +void ViewTest::mode() +{ + View view; + QFileSystemModel model; + view.createViews(&model); + + QCOMPARE(View::Icon, view.currentMode()); + view.setCurrentMode(View::List); + QCOMPARE(View::List, view.currentMode()); + view.setCurrentMode(View::Column); + QCOMPARE(View::Column, view.currentMode()); + view.setCurrentMode(View::Icon); + QCOMPARE(View::Icon, view.currentMode()); +} + +void ViewTest::rootIndex() +{ + qRegisterMetaType("QModelIndex"); + View view; + QFileSystemModel model; + view.createViews(&model); + + QSignalSpy spy(&view, SIGNAL(currentFolderChanged(const QModelIndex &))); + QModelIndex home = model.index(QDir::homePath()); + view.setRootIndex(home); + QCOMPARE(view.rootIndex(), home); + QCOMPARE(spy.count(), 1); +} + +QTEST_MAIN(ViewTest) +#include "viewtest.moc" diff --git a/pics/ambit.png b/pics/ambit.png dissimilarity index 99% index 9a466ad3059a61cfc6b86bcb82f889c20fdaa405..cd3d502ca8da4e654f28be2e61132d363d78771c 100644 GIT binary patch literal 12806 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�l}0X5XyQrdDwD4+0%iP-%T{rRJO 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 d{lfpR_TG~RPP)b2Z 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 literal 0 HcwPel00001 diff --git a/pics/columnview.png b/pics/columnview.png new file mode 100644 index 0000000000000000000000000000000000000000..8c7056b21424a245e2bfb7a07236170fe9106fb8 GIT binary patch literal 1001 zcwPbN0~Y*=P)5J=4h^;eK86@jQg@WL1L3;3prBHE?|i5EZu9teep zQdES~+=v~#CYx+FGv0OVfQ`D!YV7sxoSm7o6I*My+a$_OClPOvClKRzN~PCN?2y{9 zH&Y?SYiOFbk z;GGpu)11z>F-srFEY$d8>^fOXrKZs6Ks^8!PP*>QGG-YdMnVQ2I}d6YHqSZWHv5bS zA4YCo@Iu0u2X^;f4vg_J3hm#xehs|W{+F+$TC4SqB@&50*V^RSF}go7K29v#UcPkE zp9hM2CC};r5uh{u?D-4N_o4)RdEoKGbtEovHNw`Ewbk2wUgJFqsZ&n@&EVGoSw2AL zQz_+vir_Jc4Mc^!5RfG>mdsf4kHiDA^(DjNQu#{CuZ29c+z`6jnPvy^`3fY0< z{A%`}7H9EFCdpj-tQ1=e3W;GfyKq@4v4W>jYd8I=D{1Bn>56LKhZyuDJ0Ep*7*kb(;_vZnbC$V}7QzCv0 z!=@BMDk>zlTlpMF;Qfb>jtcS5O2p&6_dlFMF?Gr;F8a%XVQL|az%aFtZvtLaNR}V# z_wMx7QG6o1sgn|cpmM-Xp|AoFQzW+SD+hum0jZ8#S)uHKe@Q?F-WLHC6@ro$BJk$z zyFnE~YN3Vs^WHoF)$pn+q)I?lg_bf`$c2UZE_e*vUsWM`|3?q*E4>S%t=VjbD+k2? z1Pm;uOe*h?&|2u=;M>SZ@bwa8#bl>nW|V3n{^0iZZeV~nH@8MsUx^EuLBjiik2S+B zgf{GMh~;aDy7QH?5A(^F`V#{FS`5i}IzA@pI%iqeI19-}yVEVsvTkw~?RLnw26Dg# zJk}v|s$+xfdIwl5!2XLa)N~t6Vw;dI%&acVy38{%?m7a@v?{w=@& XweA8W@36`p00000NkvXXu0mjfU4Y9K literal 0 HcwPel00001 diff --git a/pics/iconview.png b/pics/iconview.png new file mode 100644 index 0000000000000000000000000000000000000000..e119d8d39c0aa2ccd06efc3d126503a3c43cba45 GIT binary patch literal 1682 zcwPaL25tF?P)YzP#Uj`Q9(Te!T)o{$qD{cQO}JGr5+cF@%`! z`=(DM62Tbm(bIDpmvd|v&F7bt#ox)_r*r+xz`(#ifgCPmYisKv_d=?+w$`hts0ajb zu%rYBfj*nfnqC7YF9M1=q$nRVp&^X&^77){-rgD|hK7c!RS)DQr>d%|yt=x&h_yLr z4J`E%7za&r^50TDN8jKELMtmPGfF%@KBlZ8^!fSeWilD>`uaNJZkL6*l3a1A6gPyF zE5nL=o}L36dC023{r$a{PN&tF*FGlW-KI=jXla1Cl0nt+eY*k#2%2(hOJ!vILvb4z z4q8b{Ri2#3q)C@Lo> zCn065Nem$9Ie41LYdk4SO7NOa&t*-Q>w^TNts&@BsZ>OsH3#CBf9mRLzb6S3;n{vf>&HzY|STpe|UIU#UM+y zGlZmdFg`v$ZUiTj$siow-``C?KR+LFKizZ7VeZ)2SVRthql7OlEm^&kJFYwpEl zgakhF_VyM~4)pjq6p?XF;CU#aX>uR~_ZYKc#l$Ef2Mu!8*47O7(!$eK;+^Y&j6Zx}Wo5;TpPii<5MZsXt*vJ4;^HFY z0qF%Ahn&^bRrCAw^wjV!(Ds&=7V{jksVK-*SC(j}2joi+4-ekK!GRgCtgQ6f+uK9? zh4b_CAb}-iCa#1Y^&E0=VSZa%n~_J~g95gdyr3%NDx)189ibKR>FFurIk|JA-;@U! zhw@xbj^77Bd7Sg|%yS^t1Ge}>{A%Qj=H<4drbHqa%FD}xR#H+DVy(~5&yhIitMuXF zp-~v~(6Et#92+l6YKxUrptrZz2)41xzP>(hdwbjDMRj$xhb?JCLxahY($dmEUUzr5 zcYJ(o-Q85vQTsWgN$2eeZMa3O#|qnb|~W^r**-L-LR zlT4CBUedUb+&5_FMBhqcfJG(1hhAS_14=;+T*wuQd|@LlL|lp+g18V*d~Jv5R6q+Q z00b8z(ghB)v9S?wA?v}b*!Vzs$RY5=skCz_d0b;NZb2Tnyu9?5mzN`42pon}0GkqI zxtp7t2&ckstGT(^ybDTVTjbz5Z83`^v6cf^?uo--ks%I4O1l)`fH)Vze9#lfBd}1w zbvC3GnWSyYsBs}~5l{kNJ>o)%7Ol?C&d^34#vw034)G?f^u|&N*JgqM%lGIc4^#r& z1=ImF01Z}#g?T=J1ZrL;uC%weXE+raWPuAomJOe}4#*e5b-;yeWUjxz-`m;QF@V8? zz+W008;wGw0LeKzIp6t>yt_tbf$QZVX|JxsPg5)7_dC$op8p>@!RDxbS;Gf z=lWV)%h;Ct15RJ$b7ijpY%?Ln{{B<{SAie=r=G<;#*1Q_&w6SJ)@vo|E8nuLr}oKu zSIdM7LO#KY@}P_J{ZBSO4=nS8?E~8s+$Xe}EUfAaYZu~~B%9|cmi`nL&nOFJNj zvNMG1x_~kE`NRl-7ZP`AP<~ZkYeEdx>fR6xA9smF#1PCFvt+Ip=W@SEcp9#|GS>@O!vG&oG z0KUAcxETphRUsKn^I>;;i}m>-w7s<%m`frH7>0aY`Jm$F`z}NYL=j?H78^D)D~ePJ z6@4mhz6e-Wv+~K(oz`;nz$28mW-WYG>%NS0NFq_lH+6cBJd2oo7z~AovDnBw$=Qz++tb5Ge=Z z62RM0-`rvsK(8BheuyN%qzXN(tcUIw^Pt{nGNKQP1$OU7>tAxyHPTQKuq^ri4wEXR z69C|U+O>Lv`PWv9OjxsJGe50PG+(p=;;2Hh>m!8V-J92e?@0(Dc)7dnOY9qw1L8eK z%?BBjYoU{q@9`*r;nz#O-kI52h~K%lw;!8;QD8ceIdF4-@KHE?M;t;`gpeaHUvE%z z5JFWSXVq7Lq#*G>x)U!TB|5xpPXWM`rdgb&4RKahHi*|SXK5R7Hmte6mwj)-nDR*9 z^6WU9no*!}>(Zvb!uN$f?yk~IFQ>mrll&I8Glrj7PpNd#ok!9*bZ7yPRjd=fC| QApigX07*qoM6N<$f?zt-#sB~S literal 0 HcwPel00001 diff --git a/src/.gitignore b/src/.gitignore index fe23c40..e3c5035 100644 --- a/src/.gitignore +++ b/src/.gitignore @@ -1,3 +1,4 @@ +qrc_ambit.cpp *.o moc_* Makefile diff --git a/src/ambit.qrc b/src/ambit.qrc new file mode 100644 index 0000000..c2076a9 --- /dev/null +++ b/src/ambit.qrc @@ -0,0 +1,10 @@ + + + ../pics/ambit.png + ../pics/arrow-left.png + ../pics/arrow-right.png + ../pics/iconview.png + ../pics/treeview.png + ../pics/columnview.png + + diff --git a/src/history.cpp b/src/history.cpp index fd6a7be..d76a42c 100644 --- a/src/history.cpp +++ b/src/history.cpp @@ -20,38 +20,34 @@ #include #include -#include #include -History::History(QObject *parent) : QObject(parent), currentLocation(-1) +History::History(QObject *parent) : QObject(parent), goForwardAction(0), goBackAction(0), currentLocation(-1) { - goBackAction = new QAction(tr("Back"), this); - goBackAction->setShortcuts(QKeySequence::Back); - goBackAction->setIcon(qApp->style()->standardIcon(QStyle::SP_ArrowBack)); - goBackAction->setEnabled(false); - goBackAction->setToolTip(tr("Back")); - connect(goBackAction, SIGNAL(triggered()), this, SLOT(goBack())); - - goForwardAction = new QAction(tr("Forward"), this); - goForwardAction->setShortcuts(QKeySequence::Forward); - goForwardAction->setIcon(qApp->style()->standardIcon(QStyle::SP_ArrowForward)); - goForwardAction->setEnabled(false); - goBackAction->setToolTip(tr("Forward")); - connect(goForwardAction, SIGNAL(triggered()), this, SLOT(goForward())); } History::~History() { } -QAction *History::backAction() const +QAction *History::backAction(QObject *parent) { - return goBackAction; + QAction *action = new QAction(tr("Back"), parent); + action->setShortcuts(QKeySequence::Back); + action->setIcon(QIcon(":/pics/arrow-left.png")); + action->setEnabled(false); + action->setToolTip(tr("Back")); + return action; } -QAction *History::forwardAction() const +QAction *History::forwardAction(QObject *parent) { - return goForwardAction; + QAction *action = new QAction(tr("Forward"), parent); + action->setShortcuts(QKeySequence::Forward); + action->setIcon(QIcon(":/pics/arrow-right.png")); + action->setEnabled(false); + action->setToolTip(tr("Forward")); + return action; } void History::currentChanged(const QModelIndex &index) @@ -63,8 +59,10 @@ void History::currentChanged(const QModelIndex &index) history.append(index); ++currentLocation; } - goForwardAction->setEnabled(history.size() - currentLocation > 1); - goBackAction->setEnabled(currentLocation > 0); + if (goForwardAction) + goForwardAction->setEnabled(history.size() - currentLocation > 1); + if (goBackAction) + goBackAction->setEnabled(currentLocation > 0); } void History::goBack() diff --git a/src/history.h b/src/history.h index 674359a..004c2bb 100644 --- a/src/history.h +++ b/src/history.h @@ -37,8 +37,11 @@ public: History(QObject *parent = 0); ~History(); - QAction *backAction() const; - QAction *forwardAction() const; + static QAction *backAction(QObject *parent); + static QAction *forwardAction(QObject *parent); + + QAction *goForwardAction; + QAction *goBackAction; public slots: void goBack(); @@ -46,9 +49,6 @@ public slots: void currentChanged(const QModelIndex &index); private: - QAction *goBackAction; - QAction *goForwardAction; - QList history; int currentLocation; }; diff --git a/src/main.cpp b/src/main.cpp index 5a55803..259bafc 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -23,7 +23,7 @@ int main(int argc, char **argv) { QApplication application(argc, argv); - application.setWindowIcon(QIcon("../pics/ambit.png")); + application.setWindowIcon(QIcon(":/pics/ambit.png")); application.setApplicationName("Ambit"); MainWindow window; window.show(); diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index bbbffb3..1679098 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -18,9 +18,7 @@ #include "mainwindow.h" -#include "treeview.h" -#include "iconview.h" -#include "columnview.h" +#include "view.h" #include "aboutdialog.h" #include "history.h" @@ -33,12 +31,6 @@ MainWindow::MainWindow(QWidget * parent) : QMainWindow(parent), model(0) { //setAttribute(Qt::WA_MacMetalStyle, true); - - history = new History(this); - connect(this, SIGNAL(currentFolderChanged(const QModelIndex &)), - history, SLOT(currentChanged(const QModelIndex &))); - connect(history, SIGNAL(goToIndex(const QModelIndex &)), - this, SLOT(setRootIndex(const QModelIndex &))); model = new QFileSystemModel(this); model->setReadOnly(false); @@ -72,13 +64,15 @@ void MainWindow::createWidgets() sidebar = new QSidebar(model, initialList, this); connect(sidebar, SIGNAL(goTo(const QModelIndex &)), this, SLOT(setRootIndex(const QModelIndex &))); - connect(this, SIGNAL(currentFolderChanged(const QModelIndex &)), + + view = new View(this); + view->createViews(model); + connect(view, SIGNAL(currentFolderChanged(const QModelIndex &)), sidebar, SLOT(selectIndex(const QModelIndex &))); - stackedWidget = new QStackedWidget(this); splitter->addWidget(sidebar); - splitter->addWidget(stackedWidget); - splitter->setStretchFactor(splitter->indexOf(stackedWidget), QSizePolicy::Expanding); + splitter->addWidget(view); + splitter->setStretchFactor(splitter->indexOf(view), QSizePolicy::Expanding); setCentralWidget(splitter); historyActionsGroup = new QActionGroup(this); @@ -88,38 +82,11 @@ void MainWindow::createWidgets() viewActionsGroup->setExclusive(true); connect(viewActionsGroup, SIGNAL(triggered(QAction *)), this, SLOT(showView(QAction *))); - IconView *iconView = new IconView(this); - addView(iconView, tr("Icons"), style()->standardIcon(QStyle::SP_FileDialogListView)); - TreeView *treeView = new TreeView(this); - addView(treeView, tr("List"), style()->standardIcon(QStyle::SP_FileDialogDetailedView)); - ColumnView *columnView = new ColumnView(this); - addView(columnView, tr("Column"), style()->standardIcon(QStyle::SP_FileDialogDetailedView)); - statusBarLabel = new QLabel(statusBar()); statusBarLabel->setAlignment(Qt::AlignCenter); statusBar()->addWidget(statusBarLabel, 1); } -void MainWindow::addView(QAbstractItemView *view, const QString &name, const QIcon &icon) -{ - views.append(view); - view->setObjectName(name); - view->setSelectionBehavior(QAbstractItemView::SelectRows); - view->setModel(model); - stackedWidget->addWidget(view); - QAction *action = new QAction(icon, tr("as ") + name, view); - action->setCheckable(true); - if (viewActionsGroup->actions().isEmpty()) { - action->setChecked(true); - } else { - view->setSelectionModel(views.first()->selectionModel()); - } - viewActionsGroup->addAction(action); - action->setShortcut((QString("Ctrl+%1").arg(viewActionsGroup->actions().count()))); - connect(view, SIGNAL(doubleClicked(const QModelIndex &)), - this, SLOT(fileOpen())); -} - void MainWindow::createActions() { about = new QAction(tr("About ") + qApp->applicationName(), this); @@ -129,11 +96,31 @@ void MainWindow::createActions() fileOpenAction = new QAction(tr("Open"), this); fileOpenAction->setShortcut(tr("Ctrl+O")); - connect(fileOpenAction, SIGNAL(triggered()), this, SLOT(fileOpen())); + connect(fileOpenAction, SIGNAL(triggered()), view, SLOT(fileOpen())); + + fileCloseAction = new QAction(tr("Close Window"), this); + fileCloseAction->setShortcut(tr("Ctrl+W")); + connect(fileCloseAction, SIGNAL(triggered()), this, SLOT(close())); fileQuitAction = new QAction(tr("Quit"), this); fileQuitAction->setShortcut(tr("Ctrl+Q")); - connect(fileQuitAction, SIGNAL(triggered()), this, SLOT(close())); + connect(fileQuitAction, SIGNAL(triggered()), qApp, SLOT(quit())); + + QAction *iconAction = new QAction(QIcon(":/pics/iconview.png"), "as Icons", this); + viewActionsGroup->addAction(iconAction); + iconAction->setCheckable(true); + iconAction->setShortcut((QString("Ctrl+%1").arg(viewActionsGroup->actions().count()))); + iconAction->setChecked(true); + + QAction *treeAction = new QAction(QIcon(":/pics/treeview.png"), "as List", this); + viewActionsGroup->addAction(treeAction); + treeAction->setCheckable(true); + treeAction->setShortcut((QString("Ctrl+%1").arg(viewActionsGroup->actions().count()))); + + QAction *columnAction = new QAction(QIcon(":/pics/columnview.png"), "as Columns", this); + viewActionsGroup->addAction(columnAction); + columnAction->setCheckable(true); + columnAction->setShortcut((QString("Ctrl+%1").arg(viewActionsGroup->actions().count()))); goUpAction = new QAction(tr("Enclosing Folder"), toolBar); goUpAction->setShortcut(Qt::CTRL + Qt::Key_Up); @@ -149,6 +136,13 @@ void MainWindow::createActions() QAction *action = toolBar->toggleViewAction(); action->setShortcut(Qt::CTRL + Qt::Key_T + Qt::ALT); // TODO text should say "show" or "hide" + + backAction = History::backAction(this); + connect(backAction, SIGNAL(triggered()), view->history, SLOT(goBack())); + forwardAction = History::forwardAction(this); + connect(forwardAction, SIGNAL(triggered()), view->history, SLOT(goForward())); + view->history->goBackAction = backAction; + view->history->goForwardAction = forwardAction; } void MainWindow::arrangeBy(QAction *action) @@ -160,6 +154,7 @@ void MainWindow::createMenu() { fileMenu = menuBar()->addMenu(tr("&File")); fileMenu->addAction(fileOpenAction); + fileMenu->addAction(fileCloseAction); fileMenu->addAction(fileQuitAction); editMenu = menuBar()->addMenu(tr("&Edit")); @@ -184,8 +179,8 @@ void MainWindow::createMenu() // Go goMenu = menuBar()->addMenu(tr("Go")); - goMenu->addAction(history->backAction()); - goMenu->addAction(history->forwardAction()); + goMenu->addAction(backAction); + goMenu->addAction(forwardAction); goMenu->addAction(goUpAction); goMenu->addSeparator(); @@ -199,8 +194,8 @@ void MainWindow::createMenu() void MainWindow::createToolBar() { toolBar->setMovable(false); - toolBar->addAction(history->backAction()); - toolBar->addAction(history->forwardAction()); + toolBar->addAction(backAction); + toolBar->addAction(forwardAction); for (int i = 0; i < viewActionsGroup->actions().count(); ++i) toolBar->addAction(viewActionsGroup->actions().at(i)); setUnifiedTitleAndToolBarOnMac(true); @@ -210,7 +205,7 @@ void MainWindow::showView(QAction *action) { for (int i = 0; i < viewActionsGroup->actions().count(); ++i) { if (viewActionsGroup->actions().at(i) == action) { - stackedWidget->setCurrentWidget(views.at(i)); + view->setCurrentMode((View::ViewMode)(i)); break; } } @@ -218,66 +213,19 @@ void MainWindow::showView(QAction *action) void MainWindow::goUp() { - QAbstractItemView *view = currentView(); - QModelIndex current = view->currentIndex(); - QModelIndex root = view->rootIndex(); - if (current.isValid() && current.parent() != root) - root = current; - root = root.parent(); - view->setCurrentIndex(root); - if (view->visualRect(root).isNull()) - view->setRootIndex(root); -} - -void MainWindow::fileOpen() -{ - QModelIndex index = currentView()->currentIndex(); - if (!index.isValid()) - return; - if (model->hasChildren(index)) { - QMetaObject::invokeMethod(currentView(), "openIndex", Q_ARG(QModelIndex, index)); - return; - } - - QUrl url = QUrl::fromLocalFile(index.data(QFileSystemModel::FilePathRole).toString()); - QDesktopServices::openUrl(url); + view->goUp(); } void MainWindow::setRootIndex(const QModelIndex &index) { - if (rootIndex() == index) { - qWarning() << index << "is the current root"; - return; - } - - if (!model->hasChildren(index)) { - fileOpen(); - return; - } - + view->setRootIndex(index); goUpAction->setEnabled(index.parent().isValid()); setWindowIcon(index.data(Qt::DecorationRole).value()); setWindowTitle(index.data().toString()); - for (int i = 0; i < views.count(); ++i) { - views.at(i)->setRootIndex(index); - } - // update statusbar qint64 freeSpace = getDiskInformation(index.data(QFileSystemModel::FilePathRole).toString()).free; QString freeSpaceString = humanSize(freeSpace); statusBarLabel->setText(QString("%1 available").arg(freeSpaceString)); - - emit currentFolderChanged(index); -} - -QModelIndex MainWindow::rootIndex() const -{ - return currentView()->rootIndex(); -} - -QAbstractItemView *MainWindow::currentView() const -{ - return views.at(stackedWidget->currentIndex()); } void MainWindow::showAbout() @@ -289,4 +237,3 @@ void MainWindow::showAbout() aboutDialog->addAuthors(authors); aboutDialog->show(); } - diff --git a/src/mainwindow.h b/src/mainwindow.h index 66257ca..b37ec23 100644 --- a/src/mainwindow.h +++ b/src/mainwindow.h @@ -22,10 +22,11 @@ #include #include -class QSplitter; class QSidebar; +class View; +class QSplitter; + class QToolBar; -class QStackedWidget; class QAbstractItemView; class QActionGroup; class QMenuBar; @@ -38,20 +39,13 @@ class MainWindow : public QMainWindow Q_OBJECT -signals: - void currentFolderChanged(const QModelIndex &index); - public: MainWindow(QWidget *parent = 0); ~MainWindow(); - QModelIndex rootIndex() const; - QAbstractItemView *currentView() const; - public slots: void setRootIndex(const QModelIndex &index); void goUp(); - void fileOpen(); void showAbout(); private slots: @@ -63,16 +57,16 @@ private: void createActions(); void createToolBar(); void createWidgets(); - void addView(QAbstractItemView *view, const QString &name, const QIcon &icon); + + QFileSystemModel *model; QSplitter *splitter; QSidebar *sidebar; - QStackedWidget *stackedWidget; - QList views; + View *view; + QActionGroup *viewActionsGroup; QActionGroup *historyActionsGroup; QActionGroup *arrangeByActionGroup; - QFileSystemModel *model; QToolBar *toolBar; QLabel *statusBarLabel; @@ -84,12 +78,13 @@ private: QMenu *helpMenu; QAction *fileOpenAction; + QAction *fileCloseAction; QAction *fileQuitAction; + QAction *backAction; + QAction *forwardAction; QAction *goUpAction; QAction *minimizeWindowAction; QAction *about; - - History *history; }; #endif // MAINWINDOW_H diff --git a/src/src.pro b/src/src.pro index ab15670..e4e8050 100644 --- a/src/src.pro +++ b/src/src.pro @@ -7,7 +7,7 @@ mac { DEPENDPATH += . INCLUDEPATH += . - +RESOURCES += ambit.qrc DESTDIR = ../ OBJECTS_DIR = build MOC_DIR = build @@ -18,6 +18,7 @@ CONFIG += warn_on debug # Input HEADERS += mainwindow.h \ + view.h \ treeview.h \ history.h \ iconview.h \ @@ -29,6 +30,7 @@ HEADERS += mainwindow.h \ qfileinfogatherer_p.h SOURCES += main.cpp \ + view.cpp \ mainwindow.cpp \ treeview.cpp \ history.cpp \ diff --git a/src/view.cpp b/src/view.cpp new file mode 100644 index 0000000..efaae5f --- /dev/null +++ b/src/view.cpp @@ -0,0 +1,143 @@ +/** + * Copyright (C) 2007 Benjamin C. Meyer + * + * 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 "view.h" + +#include "iconview.h" +#include "treeview.h" +#include "columnview.h" +#include "history.h" +#include "qfilesystemmodel_p.h" + +#include + +View::View(QWidget *parent) : QStackedWidget(parent), model(0) +{ + history = new History(this); + connect(this, SIGNAL(currentFolderChanged(const QModelIndex &)), + history, SLOT(currentChanged(const QModelIndex &))); + connect(history, SIGNAL(goToIndex(const QModelIndex &)), + this, SLOT(setRootIndex(const QModelIndex &))); +} + +View::~View() +{ +} + +void View::createViews(QFileSystemModel *model) +{ + this->model = model; + IconView *iconView = new IconView(this); + addView(iconView); + TreeView *treeView = new TreeView(this); + addView(treeView); + ColumnView *columnView = new ColumnView(this); + addView(columnView); +} + +QModelIndex View::rootIndex() const +{ + if (!model) + return QModelIndex(); + return currentView()->rootIndex(); +} + +void View::setCurrentMode(ViewMode mode) +{ + if (!views.isEmpty()) + setCurrentWidget(views.at((int)mode)); +} + +View::ViewMode View::currentMode() const +{ + if (currentIndex() > 0) + return (ViewMode)(currentIndex()); + return Icon; +} + +QAbstractItemView *View::currentView() const +{ + if (views.isEmpty()) + return 0; + return views.at(currentIndex()); +} + +void View::fileOpen() +{ + if (!model) + return; + QModelIndex index = currentView()->currentIndex(); + if (!index.isValid()) + return; + if (model->hasChildren(index)) { + QMetaObject::invokeMethod(currentView(), "openIndex", Q_ARG(QModelIndex, index)); + return; + } + + QUrl url = QUrl::fromLocalFile(index.data(QFileSystemModel::FilePathRole).toString()); + QDesktopServices::openUrl(url); +} + +void View::setRootIndex(const QModelIndex &index) +{ + if (!model) + return; + if (rootIndex() == index) { + qWarning() << index << "is the current root"; + return; + } + + if (!model->hasChildren(index)) { + fileOpen(); + return; + } + + for (int i = 0; i < views.count(); ++i) { + views.at(i)->setRootIndex(index); + } + + emit currentFolderChanged(index); +} + +void View::goUp() +{ + QAbstractItemView *view = currentView(); + if (!view) + return; + QModelIndex current = view->currentIndex(); + QModelIndex root = view->rootIndex(); + if (current.isValid() && current.parent() != root) + root = current; + root = root.parent(); + view->setCurrentIndex(root); + if (view->visualRect(root).isNull()) + view->setRootIndex(root); +} + +void View::addView(QAbstractItemView *view) +{ + views.append(view); + view->setSelectionBehavior(QAbstractItemView::SelectRows); + view->setModel(model); + addWidget(view); + + if (!views.isEmpty()) + view->setSelectionModel(views.first()->selectionModel()); + connect(view, SIGNAL(doubleClicked(const QModelIndex &)), + this, SLOT(fileOpen())); +} diff --git a/src/history.h b/src/view.h similarity index 51% copy from src/history.h copy to src/view.h index 674359a..bf496c4 100644 --- a/src/history.h +++ b/src/view.h @@ -16,42 +16,52 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -#ifndef HISTORY_H -#define HISTORY_H +#ifndef VIEW_H +#define VIEW_H -#include -#include -#include +#include +#include -class QAction; +class QFileSystemModel; +class History; -class History : public QObject +class View : public QStackedWidget { Q_OBJECT signals: - void goToIndex(const QModelIndex &index); + void currentFolderChanged(const QModelIndex &index); public: - History(QObject *parent = 0); - ~History(); + enum ViewMode { + Icon = 0, + List, + Column + }; - QAction *backAction() const; - QAction *forwardAction() const; + View(QWidget *parent = 0); + ~View(); + + void createViews(QFileSystemModel *model); + + void setCurrentMode(ViewMode mode); + ViewMode currentMode() const; + + QModelIndex rootIndex() const; + QAbstractItemView *currentView() const; + History *history; public slots: - void goBack(); - void goForward(); - void currentChanged(const QModelIndex &index); + void setRootIndex(const QModelIndex &index); + void goUp(); + void fileOpen(); private: - QAction *goBackAction; - QAction *goForwardAction; - - QList history; - int currentLocation; + void addView(QAbstractItemView *view); + QFileSystemModel *model; + QList views; }; -#endif // MAINWINDOW_H +#endif // VIEW_H -- 2.11.4.GIT