1
// vim: set tabstop=4 shiftwidth=4 noexpandtab:
3
Gwenview - A simple image viewer for KDE
4
Copyright 2000-2004 Aur�ien G�eau
6
This program is free software; you can redistribute it and/or
7
modify it under the terms of the GNU General Public License
8
as published by the Free Software Foundation; either version 2
9
of the License, or (at your option) any later version.
11
This program is distributed in the hope that it will be useful,
12
but WITHOUT ANY WARRANTY; without even the implied warranty of
13
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
GNU General Public License for more details.
16
You should have received a copy of the GNU General Public License
17
along with this program; if not, write to the Free Software
18
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
24
#include <qdockarea.h>
29
#include <kaboutdata.h>
32
#include <kapplication.h>
33
#include <kbookmarkmanager.h>
34
#include <kbookmarkmenu.h>
35
#include <kcmdlineargs.h>
36
#include <kcombobox.h>
39
#include <kdeversion.h>
40
#include <kdockwidget.h>
41
#include <kedittoolbar.h>
42
#include <kfiledialog.h>
44
#include <khelpmenu.h>
45
#include <kiconloader.h>
47
#include <kio/netaccess.h>
48
#include <kkeydialog.h>
49
#include <klargefile.h>
52
#include <kmessagebox.h>
53
#include <kpopupmenu.h>
54
#include <ksqueezedtextlabel.h>
55
#include <kstandarddirs.h>
56
#include <kstatusbar.h>
57
#include <kstdaccel.h>
58
#include <kstdaction.h>
59
#include <ktoolbarbutton.h>
60
#include <kurlcompletion.h>
61
#include <kurlpixmapprovider.h>
62
#include <kurlrequesterdlg.h>
68
#include <libkipi/plugin.h>
69
#include <libkipi/pluginloader.h>
73
#include "fileoperation.h"
74
#include "gvarchive.h"
75
#include "gvbatchmanipulator.h"
76
#include "gvbookmarkowner.h"
77
#include "gvconfigdialog.h"
78
#include "gvdirview.h"
79
#include "gvdocument.h"
80
#include "gvexternaltooldialog.h"
81
#include "gvfileviewbase.h"
82
#include "gvfileviewstack.h"
83
#include "gvhistory.h"
84
#include "gvscrollpixmapview.h"
85
#include "gvslideshow.h"
86
#include "gvslideshowdialog.h"
87
#include "gvmetaedit.h"
88
#include "gvprintdialog.h"
90
#include "thumbnailloadjob.h"
95
#include "gvkipiinterface.h"
100
#include "gvmainwindow.moc"
102
const char CONFIG_DOCK_GROUP[]="dock";
103
const char CONFIG_MAINWINDOW_GROUP[]="main window";
104
const char CONFIG_FILEWIDGET_GROUP[]="file widget";
105
const char CONFIG_DIRWIDGET_GROUP[]="dir widget";
106
const char CONFIG_PIXMAPWIDGET_GROUP[]="pixmap widget";
107
const char CONFIG_FILEOPERATION_GROUP[]="file operations";
108
const char CONFIG_SLIDESHOW_GROUP[]="slide show";
109
const char CONFIG_CACHE_GROUP[]="cache";
110
const char CONFIG_THUMBNAILLOADJOB_GROUP[]="thumbnail loading";
112
const char CONFIG_BUSYPTR_IN_FS[]="busy ptr in full screen";
113
const char CONFIG_SHOW_LOCATION_TOOLBAR[]="show address bar";
114
const char CONFIG_AUTO_DELETE_THUMBNAIL_CACHE[]="Delete Thumbnail Cache whe exit";
115
const char CONFIG_GWENVIEW_DOCK_VERSION[]="Gwenview version";
117
const char CONFIG_SESSION_URL[] = "url";
119
// This version is here to avoid configuration migration troubles when changes
120
// are made to the dock behavior
121
const int GWENVIEW_DOCK_VERSION=2;
125
#define LOG(x) kdDebug() << k_funcinfo << x << endl
130
enum { StackIDBrowse, StackIDView };
133
// This function is used in the ctor to find out whether to start in viewing
134
// or browsing mode if URL is passed on the command line.
135
static bool urlIsDirectory(QWidget* parent, const KURL& url) {
136
if( url.filename( false ).isEmpty()) return true; // file:/somewhere/<nothing here>
137
// Do direct stat instead of using KIO if the file is local (faster)
138
if( url.isLocalFile()
139
&& !KIO::probably_slow_mounted( url.path())) {
140
KDE_struct_stat buff;
141
if ( KDE_stat( QFile::encodeName(url.path()), &buff ) == 0 ) {
142
return S_ISDIR( buff.st_mode );
146
#if KDE_IS_VERSION(3, 2, 0)
147
if( KIO::NetAccess::stat( url, entry, parent)) {
149
if( KIO::NetAccess::stat( url, entry)) {
151
KIO::UDSEntry::ConstIterator it;
152
for(it=entry.begin();it!=entry.end();++it) {
153
if ((*it).m_uds==KIO::UDS_FILE_TYPE) {
154
return S_ISDIR( (*it).m_long );
162
GVMainWindow::GVMainWindow()
163
: KMainWindow(), mLoadingCursor(false)
165
FileOperation::readConfig(KGlobal::config(),CONFIG_FILEOPERATION_GROUP);
166
readConfig(KGlobal::config(),CONFIG_MAINWINDOW_GROUP);
169
mDocument=new GVDocument(this);
170
mGVHistory=new GVHistory(actionCollection());
174
createLocationToolBar();
176
setStandardToolBarMenuEnabled(true);
177
createGUI("gwenviewui.rc", false);
180
mWindowListActions.setAutoDelete(true);
181
updateWindowActions();
183
applyMainWindowSettings();
185
mFileViewStack->setFocus();
187
if( !kapp->isSessionRestored()) {
189
KCmdLineArgs *args = KCmdLineArgs::parsedArgs();
191
if (args->count()==0) {
193
url.setPath( QDir::currentDirPath() );
194
mFileViewStack->setDirURL(url);
196
bool fullscreen=args->isSet("f");
197
if (fullscreen) mToggleFullScreen->activate();
198
KURL url=args->url(0);
200
if( urlIsDirectory(this, url)) {
201
mFileViewStack->setDirURL(url);
203
if (!fullscreen) mToggleBrowse->activate();
212
bool GVMainWindow::queryClose() {
213
if (!mDocument->saveBeforeClosing()) return false;
215
KConfig* config=KGlobal::config();
216
FileOperation::writeConfig(config, CONFIG_FILEOPERATION_GROUP);
217
mPixmapView->writeConfig(config, CONFIG_PIXMAPWIDGET_GROUP);
218
mFileViewStack->writeConfig(config, CONFIG_FILEWIDGET_GROUP);
219
mDirView->writeConfig(config, CONFIG_DIRWIDGET_GROUP);
220
mSlideShow->writeConfig(config, CONFIG_SLIDESHOW_GROUP);
221
ThumbnailLoadJob::writeConfig(config, CONFIG_THUMBNAILLOADJOB_GROUP);
223
// Don't store dock layout if only the image dock is visible. This avoid
224
// saving layout when in "fullscreen" or "image only" mode.
225
if (mFileViewStack->isVisible() || mDirView->isVisible()) {
226
mDockArea->writeDockConfig(config,CONFIG_DOCK_GROUP);
228
writeConfig(config,CONFIG_MAINWINDOW_GROUP);
230
// If we are in fullscreen mode, we need to make the needed GUI elements
231
// visible before saving the window settings.
232
if (mToggleFullScreen->isChecked()) {
235
if (toolBar()->area()) {
236
toolBar()->area()->show();
243
bottomDock()->show();
248
if (mAutoDeleteThumbnailCache) {
249
QString dir=ThumbnailLoadJob::thumbnailBaseDir();
251
if (QFile::exists(dir)) {
254
#if KDE_IS_VERSION(3, 2, 0)
255
KIO::NetAccess::del(url, 0);
257
KIO::NetAccess::del(url);
262
saveMainWindowSettings(KGlobal::config(), "MainWindow");
267
void GVMainWindow::saveProperties( KConfig* cfg ) {
268
cfg->writeEntry( CONFIG_SESSION_URL, mFileViewStack->url().url());
271
void GVMainWindow::readProperties( KConfig* cfg ) {
272
KURL url(cfg->readEntry(CONFIG_SESSION_URL));
273
if( urlIsDirectory(this, url)) {
274
mFileViewStack->setDirURL(url);
280
//-----------------------------------------------------------------------
284
//-----------------------------------------------------------------------
285
void GVMainWindow::openURL(const KURL& url) {
286
mDocument->setURL(url);
287
mFileViewStack->setDirURL(url.upURL());
288
mFileViewStack->setFileNameToSelect(url.filename());
292
void GVMainWindow::slotDirURLChanged(const KURL& dirURL) {
293
LOG(dirURL.prettyURL(0,KURL::StripFileProtocol));
295
if (dirURL.path()!="/") {
296
mGoUp->setEnabled(true);
297
QPopupMenu *upPopup = mGoUp->popupMenu();
300
KURL url = dirURL.upURL();
301
for (; url.hasPath() && pos<10; url=url.upURL(), ++pos) {
302
upPopup->insertItem(url.url());
303
if (url.path()=="/") break;
306
mGoUp->setEnabled(false);
310
updateImageActions();
314
void GVMainWindow::updateLocationURL() {
317
if (mToggleBrowse->isChecked()) {
318
url=mFileViewStack->dirURL();
319
if (!url.isValid()) {
320
url=mDocument->url();
323
url=mDocument->url();
325
LOG(url.prettyURL());
326
mURLEdit->setEditText(url.prettyURL(0,KURL::StripFileProtocol));
327
mURLEdit->addToHistory(url.prettyURL(0,KURL::StripFileProtocol));
330
void GVMainWindow::goUp() {
331
goUpTo(mGoUp->popupMenu()->idAt(0));
334
void GVMainWindow::goUpTo(int id) {
335
KPopupMenu* menu=mGoUp->popupMenu();
336
KURL url(menu->text(id));
338
int index=menu->indexOf(id);
340
childURL=KURL(menu->text(menu->idAt(index-1)));
342
childURL=mDocument->dirURL();
344
mFileViewStack->setDirURL(url);
345
mFileViewStack->setFileNameToSelect(childURL.fileName());
349
//-----------------------------------------------------------------------
353
//-----------------------------------------------------------------------
354
void GVMainWindow::openHomeDir() {
356
url.setPath( QDir::homeDirPath() );
357
mFileViewStack->setDirURL(url);
361
void GVMainWindow::renameFile() {
362
if (mFileViewStack->isVisible()) {
363
mFileViewStack->renameFile();
365
mPixmapView->renameFile();
370
void GVMainWindow::copyFiles() {
371
if (mFileViewStack->isVisible()) {
372
mFileViewStack->copyFiles();
374
mPixmapView->copyFile();
379
void GVMainWindow::moveFiles() {
380
if (mFileViewStack->isVisible()) {
381
mFileViewStack->moveFiles();
383
mPixmapView->moveFile();
388
void GVMainWindow::deleteFiles() {
389
if (mFileViewStack->isVisible()) {
390
mFileViewStack->deleteFiles();
392
mPixmapView->deleteFile();
397
void GVMainWindow::showFileProperties() {
398
if (mFileViewStack->isVisible()) {
399
mFileViewStack->showFileProperties();
401
mPixmapView->showFileProperties();
406
void GVMainWindow::rotateLeft() {
407
modifyImage(GVImageUtils::ROT_270);
410
void GVMainWindow::rotateRight() {
411
modifyImage(GVImageUtils::ROT_90);
414
void GVMainWindow::mirror() {
415
modifyImage(GVImageUtils::HFLIP);
418
void GVMainWindow::flip() {
419
modifyImage(GVImageUtils::VFLIP);
422
void GVMainWindow::modifyImage(GVImageUtils::Orientation orientation) {
423
const KURL::List& urls=mFileViewStack->selectedURLs();
424
if (mFileViewStack->isVisible() && urls.size()>1) {
425
GVBatchManipulator manipulator(this, urls, orientation);
426
connect(&manipulator, SIGNAL(imageModified(const KURL&)),
427
mFileViewStack, SLOT(updateThumbnail(const KURL&)) );
429
if (urls.find(mDocument->url())!=urls.end()) {
433
mDocument->transform(orientation);
437
void GVMainWindow::showFileDialog() {
438
KURL url=KFileDialog::getOpenURL();
439
if (!url.isValid()) return;
445
void GVMainWindow::printFile() {
448
printer.setDocName(mDocument->filename());
449
const KAboutData* pAbout = KApplication::kApplication()->aboutData();
450
QString nm = pAbout->appName();
452
nm += pAbout->version();
453
printer.setCreator( nm );
455
KPrinter::addDialogPage( new GVPrintDialogPage( mDocument, this, "GV page"));
457
if (printer.setup(this, QString::null, true)) {
458
mDocument->print(&printer);
463
//-----------------------------------------------------------------------
467
//-----------------------------------------------------------------------
468
void GVMainWindow::slotImageLoading() {
469
if (mShowBusyPtrInFullScreen || !mToggleFullScreen->isChecked()) {
470
if( !mLoadingCursor ) {
471
kapp->setOverrideCursor(KCursor::workingCursor());
473
mLoadingCursor = true;
478
void GVMainWindow::slotImageLoaded() {
480
kapp->restoreOverrideCursor();
481
mLoadingCursor = false;
483
updateImageActions();
488
void GVMainWindow::hideToolBars() {
489
QPtrListIterator<KToolBar> it=toolBarIterator();
492
for(;it.current()!=0L; ++it) {
503
void GVMainWindow::showToolBars() {
504
QPtrListIterator<KToolBar> it=toolBarIterator();
508
for(;it.current()!=0L; ++it) {
519
void GVMainWindow::toggleFullScreen() {
520
if (mToggleFullScreen->isChecked()) {
526
* If the toolbar is docked we hide the DockArea to avoid
527
* having a one pixel band remaining
528
* For the same reason, we hide all the empty DockAreas
530
* NOTE: This does not work really well if the toolbar is in
531
* the left or right dock area.
534
if (leftDock()->isEmpty()) leftDock()->hide();
535
if (rightDock()->isEmpty()) rightDock()->hide();
536
if (topDock()->isEmpty()) topDock()->hide();
537
if (bottomDock()->isEmpty()) bottomDock()->hide();
539
if (mToggleBrowse->isChecked()) {
540
mPixmapView->reparent(mViewModeWidget, QPoint(0,0));
541
mCentralStack->raiseWidget(StackIDView);
543
KActionPtrList actions;
544
actions.append(mFileViewStack->selectPrevious());
545
actions.append(mFileViewStack->selectNext());
546
actions.append(mToggleFullScreen);
547
mPixmapView->setFullScreenActions(actions);
548
mPixmapView->setFullScreen(true);
549
mPixmapView->setFocus();
551
// Stop the slideshow if it's running, harmless if it does not
554
// Make sure the file view points to the right URL, it might not be the
555
// case if we are getting out of a slideshow
556
mFileViewStack->setDirURL(mDocument->url().upURL());
557
mFileViewStack->setFileNameToSelect(mDocument->url().fileName());
566
bottomDock()->show();
569
mPixmapView->setFullScreen(false);
571
if (mToggleBrowse->isChecked()) {
572
mPixmapDock->setWidget(mPixmapView);
573
mCentralStack->raiseWidget(StackIDBrowse);
575
mFileViewStack->setFocus();
580
void GVMainWindow::startSlideShow() {
582
KFileItemListIterator it( *mFileViewStack->currentFileView()->items() );
583
for ( ; it.current(); ++it ) {
584
KFileItem* item=it.current();
585
if (!item->isDir() && !GVArchive::fileItemIsArchive(item)) {
586
list.append(item->url());
589
if (list.count()==0) {
593
GVSlideShowDialog dialog(this,mSlideShow);
594
if (!dialog.exec()) return;
596
if (!mToggleFullScreen->isChecked()) {
597
mToggleFullScreen->activate();
599
mSlideShow->start(list);
603
void GVMainWindow::showConfigDialog() {
604
GVConfigDialog dialog(this);
609
void GVMainWindow::showExternalToolDialog() {
610
GVExternalToolDialog* dialog=new GVExternalToolDialog(this);
615
void GVMainWindow::showKeyDialog() {
616
KKeyDialog dialog(true, this);
617
dialog.insert(actionCollection());
619
KIPI::PluginLoader::PluginList pluginList=mPluginLoader->pluginList();
620
KIPI::PluginLoader::PluginList::ConstIterator it(pluginList.begin());
621
KIPI::PluginLoader::PluginList::ConstIterator itEnd(pluginList.end());
622
for( ; it!=itEnd; ++it ) {
623
KIPI::Plugin* plugin=(*it)->plugin();
625
dialog.insert(plugin->actionCollection(), (*it)->name());
629
dialog.configure(true);
633
void GVMainWindow::showToolBarDialog() {
634
saveMainWindowSettings(KGlobal::config(), "MainWindow");
635
KEditToolbar dlg(actionCollection());
636
connect(&dlg,SIGNAL(newToolbarConfig()),this,SLOT(applyMainWindowSettings()));
642
void GVMainWindow::applyMainWindowSettings() {
643
KMainWindow::applyMainWindowSettings(KGlobal::config(), "MainWindow");
648
void GVMainWindow::escapePressed() {
649
if (mToggleFullScreen->isChecked()) {
650
mToggleFullScreen->activate();
655
void GVMainWindow::slotDirRenamed(const KURL& oldURL, const KURL& newURL) {
656
LOG(oldURL.prettyURL(0,KURL::StripFileProtocol) << " to " << newURL.prettyURL(0,KURL::StripFileProtocol));
658
KURL url(mFileViewStack->dirURL());
659
if (!oldURL.isParentOf(url) ) {
660
LOG(oldURL.prettyURL() << " is not a parent of " << url.prettyURL());
664
QString oldPath=oldURL.path();
665
LOG("current path: " << url.path() );
666
QString path=newURL.path() + url.path().mid(oldPath.length());
667
LOG("new path: " << path);
669
mFileViewStack->setDirURL(url);
673
void GVMainWindow::slotGo() {
674
KURL url(mURLEditCompletion->replacedPath(mURLEdit->currentText()));
675
LOG(url.prettyURL());
676
if( urlIsDirectory(this, url)) {
677
LOG(" '-> is a directory");
678
mFileViewStack->setDirURL(url);
680
LOG(" '-> is not a directory");
683
mFileViewStack->setFocus();
686
void GVMainWindow::slotShownFileItemRefreshed(const KFileItem* item) {
688
if (int(item->size())!=mDocument->fileSize()) {
689
LOG("need reload " << int(item->size()) << "!=" << mDocument->fileSize());
695
void GVMainWindow::slotToggleCentralStack() {
697
if (mToggleBrowse->isChecked()) {
698
mPixmapDock->setWidget(mPixmapView);
699
mCentralStack->raiseWidget(StackIDBrowse);
700
mFileViewStack->setSilentMode( false );
701
// force re-reading the directory to show the error
702
if( mFileViewStack->lastURLError()) mFileViewStack->retryURL();
704
mPixmapView->reparent(mViewModeWidget, QPoint(0,0));
705
mCentralStack->raiseWidget(StackIDView);
706
mFileViewStack->setSilentMode( true );
709
// Make sure the window list actions are disabled if we are in view mode,
710
// otherwise weird things happens when we go back to browse mode
711
QPtrListIterator<KAction> it(mWindowListActions);
712
for (;it.current(); ++it) {
713
it.current()->setEnabled(mToggleBrowse->isChecked());
719
void GVMainWindow::resetDockWidgets() {
720
mFolderDock->undock();
721
mPixmapDock->undock();
724
mFolderDock->manualDock(mFileDock, KDockWidget::DockLeft, 4000);
725
mPixmapDock->manualDock(mFolderDock, KDockWidget::DockBottom, 3734);
726
mMetaDock->manualDock(mPixmapDock, KDockWidget::DockBottom, 8560);
730
//-----------------------------------------------------------------------
734
//-----------------------------------------------------------------------
735
void GVMainWindow::updateStatusInfo() {
737
uint count=mFileViewStack->fileCount();
738
QString url=mDocument->dirURL().prettyURL(0,KURL::StripFileProtocol);
740
txt=i18n("%1 - No Images").arg(url);
742
txt=i18n("%1 - One Image","%1 - %n images",count).arg(url);
744
mSBDirLabel->setText(txt);
750
void GVMainWindow::updateFileInfo() {
751
QString filename=mDocument->filename();
752
if (!filename.isEmpty()) {
753
QString info=QString("%1 %2x%3 @ %4%")
754
.arg(filename).arg(mDocument->width()).arg(mDocument->height())
755
.arg(int(mPixmapView->zoom()*100) );
756
mSBDetailLabel->show();
757
mSBDetailLabel->setText(info);
759
mSBDetailLabel->hide();
761
setCaption(filename);
765
void GVMainWindow::updateImageActions() {
766
bool filenameIsValid=!mDocument->isNull();
768
mStartSlideShow->setEnabled(filenameIsValid);
769
mRenameFile->setEnabled(filenameIsValid);
770
mCopyFiles->setEnabled(filenameIsValid);
771
mMoveFiles->setEnabled(filenameIsValid);
772
mDeleteFiles->setEnabled(filenameIsValid);
773
mShowFileProperties->setEnabled(filenameIsValid);
774
mRotateLeft->setEnabled(filenameIsValid);
775
mRotateRight->setEnabled(filenameIsValid);
776
mMirror->setEnabled(filenameIsValid);
777
mFlip->setEnabled(filenameIsValid);
778
mSaveFile->setEnabled(filenameIsValid);
779
mSaveFileAs->setEnabled(filenameIsValid);
780
mFilePrint->setEnabled(filenameIsValid);
781
mReload->setEnabled(filenameIsValid);
786
void GVMainWindow::createWidgets() {
787
KConfig* config=KGlobal::config();
789
mCentralStack=new QWidgetStack(this);
790
setCentralWidget(mCentralStack);
792
mDockArea=new KDockArea(mCentralStack);
793
mCentralStack->addWidget(mDockArea, StackIDBrowse);
794
mDockArea->manager()->setSplitterHighResolution(true);
795
mDockArea->manager()->setSplitterOpaqueResize(true);
797
mViewModeWidget=new QWidget(mCentralStack);
798
QVBoxLayout* layout=new QVBoxLayout(mViewModeWidget);
799
layout->setAutoAdd(true);
800
mCentralStack->addWidget(mViewModeWidget);
803
mSBDirLabel=new KSqueezedTextLabel("", statusBar());
804
statusBar()->addWidget(mSBDirLabel,1);
805
mSBDetailLabel=new QLabel("", statusBar());
806
statusBar()->addWidget(mSBDetailLabel);
809
mPixmapDock = mDockArea->createDockWidget("Image",SmallIcon("gwenview"),NULL,i18n("Image"));
810
mPixmapView=new GVScrollPixmapView(mPixmapDock,mDocument,actionCollection());
811
mPixmapDock->setWidget(mPixmapView);
814
mFolderDock = mDockArea->createDockWidget("Folders",SmallIcon("folder_open"),NULL,i18n("Folders"));
815
mDirView=new GVDirView(mFolderDock);
816
mFolderDock->setWidget(mDirView);
819
mFileDock = mDockArea->createDockWidget("Files",SmallIcon("image"),NULL,i18n("Files"));
820
QVBox* vbox=new QVBox(this);
821
(void)new KToolBar(vbox, "fileViewToolBar", true);
822
mFileViewStack=new GVFileViewStack(vbox, actionCollection());
823
mFileDock->setWidget(vbox);
824
mFileDock->setEnableDocking(KDockWidget::DockNone);
825
mDockArea->setMainDockWidget(mFileDock);
827
// Meta info edit widget
828
mMetaDock = mDockArea->createDockWidget("File Attributes", SmallIcon("doc"),NULL,
830
mMetaEdit = new GVMetaEdit(mMetaDock, mDocument);
831
mMetaDock->setWidget(mMetaEdit);
833
// Slide show controller (not really a widget)
834
mSlideShow=new GVSlideShow(mDocument);
836
// Default position on desktop
837
setGeometry(20,20,720,520);
839
// Default dock config
840
// (The "magic numbers" were found by adjusting the layout from within the
841
// app and looking at the result in the configuration file)
842
mFolderDock->manualDock(mFileDock, KDockWidget::DockLeft, 4000);
843
mPixmapDock->manualDock(mFolderDock, KDockWidget::DockBottom, 3734);
844
mMetaDock->manualDock(mPixmapDock, KDockWidget::DockBottom, 8560);
846
// Load dock config if up to date
847
if (config->hasGroup(CONFIG_DOCK_GROUP)) {
848
config->setGroup(CONFIG_DOCK_GROUP);
849
if (config->readNumEntry(CONFIG_GWENVIEW_DOCK_VERSION, 1)==GWENVIEW_DOCK_VERSION) {
850
mDockArea->readDockConfig(config,CONFIG_DOCK_GROUP);
852
KMessageBox::sorry(this, i18n(
853
"<qt><b>Configuration update</b><br>"
854
"Due to some changes in the dock behavior, your old dock configuration has been discarded. "
855
"Please adjust your docks again.</qt>")
857
// Store the default dock config and create the
858
// GWENVIEW_DOCK_VERSION entry
859
mDockArea->writeDockConfig(config,CONFIG_DOCK_GROUP);
860
config->writeEntry(CONFIG_GWENVIEW_DOCK_VERSION, GWENVIEW_DOCK_VERSION);
864
// There was no dock config, lets create the GWENVIEW_DOCK_VERSION entry
865
config->setGroup(CONFIG_DOCK_GROUP);
866
config->writeEntry(CONFIG_GWENVIEW_DOCK_VERSION, GWENVIEW_DOCK_VERSION);
871
mFileViewStack->readConfig(config,CONFIG_FILEWIDGET_GROUP);
872
mDirView->readConfig(config,CONFIG_DIRWIDGET_GROUP);
873
mPixmapView->readConfig(config,CONFIG_PIXMAPWIDGET_GROUP);
874
mSlideShow->readConfig(config,CONFIG_SLIDESHOW_GROUP);
875
ThumbnailLoadJob::readConfig(config,CONFIG_THUMBNAILLOADJOB_GROUP);
876
GVCache::instance()->readConfig(config,CONFIG_CACHE_GROUP);
880
void GVMainWindow::createActions() {
882
mToggleBrowse=new KToggleAction(i18n("Browse"), "folder", CTRL + Key_Return, this, SLOT(slotToggleCentralStack()), actionCollection(), "toggle_browse");
883
mToggleBrowse->setChecked(true);
884
mToggleBrowse->setShortcut(CTRL + Key_Return);
887
KStdAction::open(this,SLOT(showFileDialog()),actionCollection() );
888
mSaveFile=KStdAction::save(mDocument,SLOT(save()),actionCollection() );
889
mSaveFileAs=KStdAction::saveAs(mDocument,SLOT(saveAs()),actionCollection() );
890
mFilePrint = KStdAction::print(this, SLOT(printFile()), actionCollection());
891
mRenameFile=new KAction(i18n("&Rename..."),Key_F2,this,SLOT(renameFile()),actionCollection(),"file_rename");
892
mCopyFiles=new KAction(i18n("&Copy To..."),Key_F7,this,SLOT(copyFiles()),actionCollection(),"file_copy");
893
mMoveFiles=new KAction(i18n("&Move To..."),Key_F8,this,SLOT(moveFiles()),actionCollection(),"file_move");
894
mDeleteFiles=new KAction(i18n("&Delete"),"editdelete",Key_Delete,this,SLOT(deleteFiles()),actionCollection(),"file_delete");
895
mShowFileProperties=new KAction(i18n("Properties"),0,this,SLOT(showFileProperties()),actionCollection(),"file_properties");
896
KStdAction::quit( kapp, SLOT (closeAllWindows()), actionCollection() );
899
mRotateLeft=new KAction(i18n("Rotate &Left"),"rotate_left",CTRL + Key_L, this, SLOT(rotateLeft()),actionCollection(),"rotate_left");
900
mRotateRight=new KAction(i18n("Rotate &Right"),"rotate_right",CTRL + Key_R, this, SLOT(rotateRight()),actionCollection(),"rotate_right");
901
mMirror=new KAction(i18n("&Mirror"),"mirror",0, this, SLOT(mirror()),actionCollection(),"mirror");
902
mFlip=new KAction(i18n("&Flip"),"flip",0, this, SLOT(flip()),actionCollection(),"flip");
905
mReload=new KAction(i18n("Reload"), "reload", Key_F5, mDocument, SLOT(reload()), actionCollection(), "reload");
906
mReload->setEnabled(false);
908
#if KDE_IS_VERSION(3, 1, 90)
909
mToggleFullScreen= KStdAction::fullScreen(this,SLOT(toggleFullScreen()),actionCollection(),0);
911
mToggleFullScreen=new KToggleAction(i18n("Full Screen"),"window_fullscreen",CTRL + Key_F,this,SLOT(toggleFullScreen()),actionCollection(),"fullscreen");
913
mStartSlideShow=new KAction(i18n("Slide Show..."),"slideshow",0,this,SLOT(startSlideShow()),actionCollection(),"slideshow");
916
mGoUp=new KToolBarPopupAction(i18n("Up"), "up", ALT + Key_Up, this, SLOT(goUp()), actionCollection(), "go_up");
917
mOpenHomeDir=KStdAction::home(this, SLOT(openHomeDir()), actionCollection() );
920
QString file = locate( "data", "kfile/bookmarks.xml" );
921
if (file.isEmpty()) {
922
file = locateLocal( "data", "kfile/bookmarks.xml" );
925
KBookmarkManager* manager=KBookmarkManager::managerForFile(file,false);
926
manager->setUpdate(true);
927
manager->setShowNSBookmarks(false);
929
GVBookmarkOwner* bookmarkOwner=new GVBookmarkOwner(this);
931
KActionMenu* bookmark=new KActionMenu(i18n( "&Bookmarks" ), "bookmark", actionCollection(), "bookmarks" );
932
new KBookmarkMenu(manager, bookmarkOwner, bookmark->popupMenu(), 0, true);
934
connect(bookmarkOwner,SIGNAL(openURL(const KURL&)),
935
mFileViewStack,SLOT(setDirURL(const KURL&)) );
937
connect(mFileViewStack,SIGNAL(directoryChanged(const KURL&)),
938
bookmarkOwner,SLOT(setURL(const KURL&)) );
941
mResetDockWidgets = new KAction(i18n("Reset"), 0, this, SLOT(resetDockWidgets()), actionCollection(), "reset_dock_widgets");
945
KStdAction::preferences(this, SLOT(showConfigDialog()), actionCollection() );
947
KStdAction::keyBindings(this, SLOT(showKeyDialog()), actionCollection() );
948
(void)new KAction(i18n("Configure External Tools..."), "configure", 0,
949
this, SLOT(showExternalToolDialog()), actionCollection(), "configure_tools");
950
(void)KStdAction::configureToolbars(
951
this, SLOT(showToolBarDialog()), actionCollection() );
953
actionCollection()->readShortcutSettings();
957
void GVMainWindow::createHideShowAction(KDockWidget* dock) {
959
if (dock->mayBeHide()) {
960
caption=i18n("Hide %1").arg(dock->caption());
962
caption=i18n("Show %1").arg(dock->caption());
965
KAction* action=new KAction(caption, 0, dock, SLOT(changeHideShowState()), (QObject*)0 );
967
action->setIconSet( QIconSet(*dock->icon()) );
969
mWindowListActions.append(action);
973
void GVMainWindow::updateWindowActions() {
974
unplugActionList("winlist");
975
mWindowListActions.clear();
976
createHideShowAction(mFolderDock);
977
createHideShowAction(mPixmapDock);
978
createHideShowAction(mMetaDock);
979
plugActionList("winlist", mWindowListActions);
983
void GVMainWindow::createConnections() {
984
connect(mGoUp->popupMenu(), SIGNAL(activated(int)),
985
this,SLOT(goUpTo(int)));
987
// Dir view connections
988
connect(mDirView,SIGNAL(dirURLChanged(const KURL&)),
989
mFileViewStack,SLOT(setDirURL(const KURL&)) );
991
connect(mDirView, SIGNAL(dirRenamed(const KURL&, const KURL&)),
992
this, SLOT(slotDirRenamed(const KURL&, const KURL&)) );
994
// Pixmap view connections
995
connect(mPixmapView,SIGNAL(selectPrevious()),
996
mFileViewStack,SLOT(slotSelectPrevious()) );
997
connect(mPixmapView,SIGNAL(selectNext()),
998
mFileViewStack,SLOT(slotSelectNext()) );
999
connect(mPixmapView,SIGNAL(zoomChanged(double)),
1000
this,SLOT(updateFileInfo()) );
1002
// File view connections
1003
connect(mFileViewStack,SIGNAL(urlChanged(const KURL&)),
1004
mDocument,SLOT(setURL(const KURL&)) );
1005
connect(mFileViewStack,SIGNAL(directoryChanged(const KURL&)),
1006
this,SLOT(slotDirURLChanged(const KURL&)) );
1007
connect(mFileViewStack,SIGNAL(directoryChanged(const KURL&)),
1008
mDirView,SLOT(setURL(const KURL&)) );
1009
connect(mFileViewStack,SIGNAL(directoryChanged(const KURL&)),
1010
mGVHistory,SLOT(addURLToHistory(const KURL&)) );
1012
connect(mFileViewStack,SIGNAL(completed()),
1013
this,SLOT(updateStatusInfo()) );
1014
connect(mFileViewStack,SIGNAL(canceled()),
1015
this,SLOT(updateStatusInfo()) );
1016
connect(mFileViewStack,SIGNAL(imageDoubleClicked()),
1017
mToggleBrowse,SLOT(activate()) );
1018
connect(mFileViewStack,SIGNAL(shownFileItemRefreshed(const KFileItem*)),
1019
this,SLOT(slotShownFileItemRefreshed(const KFileItem*)) );
1021
// GVHistory connections
1022
connect(mGVHistory, SIGNAL(urlChanged(const KURL&)),
1023
mFileViewStack, SLOT(setDirURL(const KURL&)) );
1025
// GVDocument connections
1026
connect(mDocument,SIGNAL(loading()),
1027
this,SLOT(slotImageLoading()) );
1028
connect(mDocument,SIGNAL(loaded(const KURL&)),
1029
this,SLOT(slotImageLoaded()) );
1030
connect(mDocument,SIGNAL(saved(const KURL&)),
1031
mFileViewStack,SLOT(updateThumbnail(const KURL&)) );
1032
connect(mDocument,SIGNAL(reloaded(const KURL&)),
1033
mFileViewStack,SLOT(updateThumbnail(const KURL&)) );
1036
connect(mSlideShow,SIGNAL(finished()),
1037
mToggleFullScreen,SLOT(activate()) );
1040
connect(mURLEdit, SIGNAL(activated(const QString &)),
1041
this,SLOT(slotGo()) );
1042
connect(mURLEdit, SIGNAL(returnPressed()),
1043
this,SLOT(slotGo()) );
1045
// Non configurable stop-fullscreen accel
1046
QAccel* accel=new QAccel(this);
1047
accel->connectItem(accel->insertItem(Key_Escape),this,SLOT(escapePressed()));
1050
connect(mDockArea->manager(), SIGNAL(change()),
1051
this, SLOT(updateWindowActions()) );
1055
void GVMainWindow::createLocationToolBar() {
1057
mURLEdit=new KHistoryCombo(this);
1058
mURLEdit->setDuplicatesEnabled(false);
1059
mURLEdit->setPixmapProvider(new KURLPixmapProvider);
1061
mURLEditCompletion=new KURLCompletion();
1062
//mURLEditCompletion->setDir("/");
1064
mURLEdit->setCompletionObject(mURLEditCompletion);
1065
mURLEdit->setAutoDeleteCompletionObject(true);
1067
KWidgetAction* comboAction=new KWidgetAction( mURLEdit, i18n("Location Bar"), 0,
1068
0, 0, actionCollection(), "location_url");
1069
comboAction->setShortcutConfigurable(false);
1070
comboAction->setAutoSized(true);
1073
(void)new KAction( i18n("Clear Location Bar"),
1074
QApplication::reverseLayout()?"clear_left" : "locationbar_erase",
1075
0, this, SLOT(clearLocationLabel()), actionCollection(), "clear_location");
1078
/* we use "kde toolbar widget" to avoid the flat background (looks bad with
1079
* styles like Keramik). See konq_misc.cc.
1081
QLabel* urlLabel=new QLabel(i18n("L&ocation:"), this, "kde toolbar widget");
1082
(void)new KWidgetAction( urlLabel, i18n("L&ocation: "), Key_F6, this, SLOT( activateLocationLabel()),
1083
actionCollection(), "location_label");
1084
urlLabel->setBuddy(mURLEdit);
1087
(void)new KAction(i18n("Go"), "key_enter", 0, this, SLOT(slotGo()), actionCollection(), "location_go");
1092
void GVMainWindow::clearLocationLabel() {
1093
mURLEdit->clearEdit();
1094
mURLEdit->setFocus();
1098
void GVMainWindow::activateLocationLabel() {
1099
mURLEdit->setFocus();
1100
mURLEdit->lineEdit()->selectAll();
1105
void GVMainWindow::loadPlugins() {
1106
// Sets up the plugin interface, and load the plugins
1107
GVKIPIInterface* interface = new GVKIPIInterface(this, mFileViewStack);
1108
mPluginLoader = new KIPI::PluginLoader(QStringList(), interface );
1109
connect( mPluginLoader, SIGNAL( replug() ), this, SLOT( slotReplug() ) );
1110
mPluginLoader->loadPlugins();
1114
// Helper class for slotReplug(), gcc does not want to instantiate templates
1115
// with local classes, so this is declared outside of slotReplug()
1118
QPtrList<KAction> mActions;
1120
MenuInfo(const QString& name) : mName(name) {}
1123
void GVMainWindow::slotReplug() {
1124
typedef QMap<KIPI::Category, MenuInfo> CategoryMap;
1125
CategoryMap categoryMap;
1126
categoryMap[KIPI::IMAGESPLUGIN]=MenuInfo("image_actions");
1127
categoryMap[KIPI::EFFECTSPLUGIN]=MenuInfo("effect_actions");
1128
categoryMap[KIPI::TOOLSPLUGIN]=MenuInfo("tool_actions");
1129
categoryMap[KIPI::IMPORTPLUGIN]=MenuInfo("import_actions");
1130
categoryMap[KIPI::EXPORTPLUGIN]=MenuInfo("export_actions");
1131
categoryMap[KIPI::BATCHPLUGIN]=MenuInfo("batch_actions");
1132
categoryMap[KIPI::COLLECTIONSPLUGIN]=MenuInfo("collection_actions");
1134
// Fill the mActions
1135
KIPI::PluginLoader::PluginList pluginList=mPluginLoader->pluginList();
1136
KIPI::PluginLoader::PluginList::ConstIterator it(pluginList.begin());
1137
KIPI::PluginLoader::PluginList::ConstIterator itEnd(pluginList.end());
1138
for( ; it!=itEnd; ++it ) {
1139
if (!(*it)->shouldLoad()) continue;
1140
KIPI::Plugin* plugin = (*it)->plugin();
1142
if (!plugin) continue;
1144
plugin->setup(this);
1145
KActionPtrList actions = plugin->actions();
1146
KActionPtrList::ConstIterator actionIt=actions.begin(), end=actions.end();
1147
for (; actionIt!=end; ++actionIt) {
1148
KIPI::Category category = plugin->category(*actionIt);
1150
if (!categoryMap.contains(category)) {
1151
kdWarning() << "Unknown category '" << category << "'\n";
1155
categoryMap[category].mActions.append(*actionIt);
1157
plugin->actionCollection()->readShortcutSettings();
1160
// Create a dummy "no plugin" action list
1161
KAction* noPlugin=new KAction(i18n("No Plugin"), 0, 0, 0, actionCollection(), "no_plugin");
1162
noPlugin->setShortcutConfigurable(false);
1163
noPlugin->setEnabled(false);
1164
QPtrList<KAction> noPluginList;
1165
noPluginList.append(noPlugin);
1168
CategoryMap::ConstIterator catIt=categoryMap.begin(), catItEnd=categoryMap.end();
1169
for (; catIt!=catItEnd; ++catIt) {
1170
const MenuInfo& info=catIt.data();
1171
unplugActionList(info.mName);
1172
if (info.mActions.count()>0) {
1173
plugActionList(info.mName, info.mActions);
1175
plugActionList(info.mName, noPluginList);
1180
void GVMainWindow::loadPlugins() {
1181
QPopupMenu *popup = static_cast<QPopupMenu*>(
1182
factory()->container( "plugins", this));
1187
void GVMainWindow::slotReplug() {
1192
//-----------------------------------------------------------------------
1196
//-----------------------------------------------------------------------
1197
void GVMainWindow::setShowBusyPtrInFullScreen(bool value) {
1198
mShowBusyPtrInFullScreen=value;
1201
void GVMainWindow::setAutoDeleteThumbnailCache(bool value){
1202
mAutoDeleteThumbnailCache=value;
1206
//-----------------------------------------------------------------------
1210
//-----------------------------------------------------------------------
1211
void GVMainWindow::readConfig(KConfig* config,const QString& group) {
1212
config->setGroup(group);
1213
mShowBusyPtrInFullScreen=config->readBoolEntry(CONFIG_BUSYPTR_IN_FS, true);
1214
mAutoDeleteThumbnailCache=config->readBoolEntry(CONFIG_AUTO_DELETE_THUMBNAIL_CACHE, false);
1218
void GVMainWindow::writeConfig(KConfig* config,const QString& group) const {
1219
config->setGroup(group);
1220
config->writeEntry(CONFIG_BUSYPTR_IN_FS, mShowBusyPtrInFullScreen);
1221
config->writeEntry(CONFIG_AUTO_DELETE_THUMBNAIL_CACHE, mAutoDeleteThumbnailCache);