~ubuntu-branches/ubuntu/edgy/gwenview/edgy

« back to all changes in this revision

Viewing changes to src/app/mainwindow.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Jonathan Riddell
  • Date: 2005-12-06 17:59:19 UTC
  • mfrom: (1.1.3 upstream) (2.1.1 sarge)
  • Revision ID: james.westby@ubuntu.com-20051206175919-8yv9nfmw0pws6p52
Tags: 1.3.1-0ubuntu1
* Sync with Debian
* Edit kde.mk for .pot generation

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
// vim: set tabstop=4 shiftwidth=4 noexpandtab:
 
2
/*
 
3
Gwenview - A simple image viewer for KDE
 
4
Copyright 2000-2004 Aur�ien G�eau
 
5
 
 
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.
 
10
 
 
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.
 
15
 
 
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.
 
19
 
 
20
*/
 
21
// Qt
 
22
#include <qcursor.h>
 
23
#include <qdir.h>
 
24
#include <qdockarea.h>
 
25
#include <qhbox.h>
 
26
#include <qtabwidget.h>
 
27
 
 
28
// KDE
 
29
#include <kaboutdata.h>
 
30
#include <kaccel.h>
 
31
#include <kaction.h>
 
32
#include <kapplication.h>
 
33
#include <kbookmarkmanager.h>
 
34
#include <kbookmarkmenu.h>
 
35
#include <kcmdlineargs.h>
 
36
#include <kcombobox.h>
 
37
#include <kconfig.h>
 
38
#include <kdebug.h>
 
39
#include <kdeversion.h>
 
40
#include <kdockwidget.h>
 
41
#include <kedittoolbar.h>
 
42
#include <kfiledialog.h>
 
43
#include <kglobal.h>
 
44
#include <khelpmenu.h>
 
45
#include <kiconloader.h>
 
46
#include <kimageio.h>
 
47
#include <kio/netaccess.h>
 
48
#include <kkeydialog.h>
 
49
#include <klargefile.h>
 
50
#include <klistview.h>
 
51
#include <klocale.h>
 
52
#include <kmenubar.h>
 
53
#include <kmessagebox.h>
 
54
#include <kpopupmenu.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>
 
63
#include <kprinter.h>
 
64
 
 
65
#include <config.h>
 
66
// KIPI
 
67
#ifdef GV_HAVE_KIPI
 
68
#include <libkipi/plugin.h>
 
69
#include <libkipi/pluginloader.h>
 
70
#endif
 
71
 
 
72
// Local
 
73
#include "bookmarkowner.h"
 
74
#include "bookmarkviewcontroller.h"
 
75
#include "configdialog.h"
 
76
#include "dirview.h"
 
77
#include "history.h"
 
78
#include "metaedit.h"
 
79
#include "truncatedtextlabel.h"
 
80
 
 
81
#include "gvcore/fileoperation.h"
 
82
#include "gvcore/archive.h"
 
83
#include "gvcore/batchmanipulator.h"
 
84
#include "gvcore/captionformatter.h"
 
85
#include "gvcore/document.h"
 
86
#include "gvcore/externaltooldialog.h"
 
87
#include "gvcore/fileviewbase.h"
 
88
#include "gvcore/fileviewstack.h"
 
89
#include "gvcore/imageview.h"
 
90
#include "gvcore/slideshow.h"
 
91
#include "gvcore/slideshowdialog.h"
 
92
#include "gvcore/printdialog.h"
 
93
#include "gvcore/cache.h"
 
94
#include "gvcore/thumbnailloadjob.h"
 
95
 
 
96
#include "config.h"
 
97
 
 
98
#ifdef GV_HAVE_KIPI
 
99
#include "gvcore/kipiinterface.h"
 
100
#endif
 
101
 
 
102
#include <kcursor.h>
 
103
 
 
104
#include "mainwindow.moc"
 
105
namespace Gwenview {
 
106
 
 
107
const char CONFIG_DOCK_GROUP[]="dock";
 
108
const char CONFIG_MAINWINDOW_GROUP[]="main window";
 
109
const char CONFIG_FILEWIDGET_GROUP[]="file widget";
 
110
const char CONFIG_DIRWIDGET_GROUP[]="dir widget";
 
111
const char CONFIG_PIXMAPWIDGET_GROUP[]="pixmap widget";
 
112
const char CONFIG_FILEOPERATION_GROUP[]="file operations";
 
113
const char CONFIG_SLIDESHOW_GROUP[]="slide show";
 
114
const char CONFIG_CACHE_GROUP[]="cache";
 
115
const char CONFIG_THUMBNAILLOADJOB_GROUP[]="thumbnail loading";
 
116
 
 
117
const char CONFIG_BUSYPTR_IN_FS[]="busy ptr in full screen";
 
118
const char CONFIG_SHOW_LOCATION_TOOLBAR[]="show address bar";
 
119
const char CONFIG_AUTO_DELETE_THUMBNAIL_CACHE[]="Delete Thumbnail Cache whe exit";
 
120
const char CONFIG_GWENVIEW_DOCK_VERSION[]="Gwenview version";
 
121
 
 
122
const char CONFIG_SESSION_URL[] = "url";
 
123
 
 
124
// This version is here to avoid configuration migration troubles when changes
 
125
// are made to the dock behavior
 
126
const int GWENVIEW_DOCK_VERSION=2;
 
127
 
 
128
// The timeout before an hint in the statusbar disappear (in msec)
 
129
const int HINT_TIMEOUT=10000;
 
130
 
 
131
// Time before we try to load the KIPI plugins (in msec)
 
132
const int LOAD_PLUGIN_DELAY=1000;
 
133
 
 
134
//#define ENABLE_LOG
 
135
#ifdef ENABLE_LOG
 
136
#define LOG(x) kdDebug() << k_funcinfo << x << endl
 
137
#else
 
138
#define LOG(x) ;
 
139
#endif
 
140
 
 
141
enum { StackIDBrowse, StackIDView };
 
142
 
 
143
 
 
144
// This function is used in the ctor to find out whether to start in viewing
 
145
// or browsing mode if URL is passed on the command line.
 
146
static bool urlIsDirectory(QWidget* parent, const KURL& url) {
 
147
        if( url.filename( false ).isEmpty()) return true; // file:/somewhere/<nothing here>
 
148
        // Do direct stat instead of using KIO if the file is local (faster)
 
149
        if( url.isLocalFile()
 
150
                && !KIO::probably_slow_mounted( url.path())) {
 
151
                KDE_struct_stat buff;
 
152
                if ( KDE_stat( QFile::encodeName(url.path()), &buff ) == 0 )  {
 
153
                        return S_ISDIR( buff.st_mode );
 
154
                }
 
155
        }
 
156
        KIO::UDSEntry entry;
 
157
        if( KIO::NetAccess::stat( url, entry, parent)) {
 
158
                KIO::UDSEntry::ConstIterator it;
 
159
                for(it=entry.begin();it!=entry.end();++it) {
 
160
                        if ((*it).m_uds==KIO::UDS_FILE_TYPE) {
 
161
                                return S_ISDIR( (*it).m_long );
 
162
                        }
 
163
                }
 
164
        }
 
165
        return false;
 
166
}
 
167
 
 
168
 
 
169
MainWindow::MainWindow()
 
170
: KMainWindow()
 
171
, mLoadingCursor(false)
 
172
#ifdef GV_HAVE_KIPI
 
173
, mPluginLoader(0)
 
174
#endif
 
175
{
 
176
        FileOperation::readConfig(KGlobal::config(),CONFIG_FILEOPERATION_GROUP);
 
177
        readConfig(KGlobal::config(),CONFIG_MAINWINDOW_GROUP);
 
178
 
 
179
        // Backend
 
180
        mDocument=new Document(this);
 
181
        mHistory=new History(actionCollection());
 
182
        // GUI
 
183
        createActions();
 
184
        createWidgets();
 
185
        createLocationToolBar();
 
186
        createObjectInteractions();
 
187
 
 
188
        setStandardToolBarMenuEnabled(true);
 
189
        createGUI("gwenviewui.rc", false);
 
190
 
 
191
        createConnections();
 
192
        mWindowListActions.setAutoDelete(true);
 
193
        updateWindowActions();
 
194
        applyMainWindowSettings();
 
195
 
 
196
        if( !kapp->isSessionRestored()) {
 
197
                // Command line
 
198
                KCmdLineArgs *args = KCmdLineArgs::parsedArgs();
 
199
 
 
200
                if (args->count()==0) {
 
201
                        KURL url;
 
202
                        url.setPath( QDir::currentDirPath() );
 
203
                        mFileViewStack->setDirURL(url);
 
204
                } else {
 
205
                        bool fullscreen=args->isSet("f");
 
206
                        if (fullscreen) mToggleFullScreen->activate();
 
207
                        KURL url=args->url(0);
 
208
 
 
209
                        if( urlIsDirectory(this, url)) {
 
210
                                mFileViewStack->setDirURL(url);
 
211
                        } else {
 
212
                                if (!fullscreen) mToggleBrowse->activate();
 
213
                                openURL(url);
 
214
                        }
 
215
                        updateLocationURL();
 
216
                }
 
217
        }
 
218
        
 
219
        if (mToggleBrowse->isChecked()) {
 
220
                mFileViewStack->setFocus();
 
221
        } else {
 
222
                mImageView->setFocus();
 
223
        }
 
224
 
 
225
        QTimer::singleShot(LOAD_PLUGIN_DELAY, this, SLOT(loadPlugins()) );
 
226
}
 
227
 
 
228
 
 
229
bool MainWindow::queryClose() {
 
230
        mDocument->saveBeforeClosing();
 
231
 
 
232
        KConfig* config=KGlobal::config();
 
233
        FileOperation::writeConfig(config, CONFIG_FILEOPERATION_GROUP);
 
234
        mImageView->writeConfig(config, CONFIG_PIXMAPWIDGET_GROUP);
 
235
        mFileViewStack->writeConfig(config, CONFIG_FILEWIDGET_GROUP);
 
236
        mDirView->writeConfig(config, CONFIG_DIRWIDGET_GROUP);
 
237
        mSlideShow->writeConfig(config, CONFIG_SLIDESHOW_GROUP);
 
238
        ThumbnailLoadJob::writeConfig(config, CONFIG_THUMBNAILLOADJOB_GROUP);
 
239
 
 
240
        // Don't store dock layout if only the image dock is visible. This avoid
 
241
        // saving layout when in "fullscreen" or "image only" mode.
 
242
        if (mFileViewStack->isVisible() || mDirView->isVisible()) {
 
243
                mDockArea->writeDockConfig(config,CONFIG_DOCK_GROUP);
 
244
        }
 
245
        writeConfig(config,CONFIG_MAINWINDOW_GROUP);
 
246
 
 
247
        if (mAutoDeleteThumbnailCache) {
 
248
                QString dir=ThumbnailLoadJob::thumbnailBaseDir();
 
249
 
 
250
                if (QFile::exists(dir)) {
 
251
                        KURL url;
 
252
                        url.setPath(dir);
 
253
                        KIO::NetAccess::del(url, this);
 
254
                }
 
255
        }
 
256
        
 
257
        if (!mToggleFullScreen->isChecked()) {
 
258
                saveMainWindowSettings(KGlobal::config(), "MainWindow");
 
259
        }
 
260
        return true;
 
261
}
 
262
 
 
263
void MainWindow::saveProperties( KConfig* cfg ) {
 
264
        cfg->writeEntry( CONFIG_SESSION_URL, mFileViewStack->url().url());
 
265
}
 
266
 
 
267
void MainWindow::readProperties( KConfig* cfg ) {
 
268
        KURL url(cfg->readEntry(CONFIG_SESSION_URL));
 
269
        if( urlIsDirectory(this, url)) {
 
270
                mFileViewStack->setDirURL(url);
 
271
        } else {
 
272
                openURL(url);
 
273
        }
 
274
}
 
275
 
 
276
//-----------------------------------------------------------------------
 
277
//
 
278
// Public slots
 
279
//
 
280
//-----------------------------------------------------------------------
 
281
void MainWindow::openURL(const KURL& url) {
 
282
        mDocument->setURL(url);
 
283
        mFileViewStack->setDirURL(url.upURL());
 
284
        mFileViewStack->setFileNameToSelect(url.filename());
 
285
}
 
286
 
 
287
 
 
288
void MainWindow::slotDirURLChanged(const KURL& dirURL) {
 
289
        LOG(dirURL.prettyURL(0,KURL::StripFileProtocol));
 
290
        
 
291
        if (dirURL.path()!="/") {
 
292
                mGoUp->setEnabled(true);
 
293
                QPopupMenu *upPopup = mGoUp->popupMenu();
 
294
                upPopup->clear();
 
295
                int pos = 0;
 
296
                KURL url = dirURL.upURL();
 
297
                for (; url.hasPath() && pos<10; url=url.upURL(), ++pos) {
 
298
                        upPopup->insertItem(url.url());
 
299
                        if (url.path()=="/") break;
 
300
                }
 
301
        } else {
 
302
                mGoUp->setEnabled(false);
 
303
        }
 
304
 
 
305
        updateStatusInfo();
 
306
        updateImageActions();
 
307
        updateLocationURL();
 
308
}
 
309
 
 
310
void MainWindow::updateLocationURL() {
 
311
        LOG("");
 
312
        KURL url;
 
313
        if (mToggleBrowse->isChecked()) {
 
314
                url=mFileViewStack->dirURL();
 
315
                if (!url.isValid()) {
 
316
                        url=mDocument->url();
 
317
                }
 
318
        } else {
 
319
                url=mDocument->url();
 
320
        }
 
321
        LOG(url.prettyURL());
 
322
#if KDE_IS_VERSION( 3, 4, 0 )
 
323
        mURLEdit->setEditText(url.pathOrURL());
 
324
        mURLEdit->addToHistory(url.pathOrURL());
 
325
#else
 
326
        mURLEdit->setEditText(url.prettyURL(0,KURL::StripFileProtocol));
 
327
        mURLEdit->addToHistory(url.prettyURL(0,KURL::StripFileProtocol));
 
328
#endif
 
329
}
 
330
 
 
331
void MainWindow::goUp() {
 
332
        goUpTo(mGoUp->popupMenu()->idAt(0));
 
333
}
 
334
 
 
335
void MainWindow::goUpTo(int id) {
 
336
        KPopupMenu* menu=mGoUp->popupMenu();
 
337
        KURL url(menu->text(id));
 
338
        KURL childURL;
 
339
        int index=menu->indexOf(id);
 
340
        if (index>0) {
 
341
                childURL=KURL(menu->text(menu->idAt(index-1)));
 
342
        } else {
 
343
                childURL=mDocument->dirURL();
 
344
        }
 
345
        mFileViewStack->setDirURL(url);
 
346
        mFileViewStack->setFileNameToSelect(childURL.fileName());
 
347
}
 
348
 
 
349
 
 
350
//-----------------------------------------------------------------------
 
351
//
 
352
// File operations
 
353
//
 
354
//-----------------------------------------------------------------------
 
355
void MainWindow::goHome() {
 
356
        KURL url;
 
357
        url.setPath( QDir::homeDirPath() );
 
358
        mFileViewStack->setDirURL(url);
 
359
}
 
360
 
 
361
 
 
362
void MainWindow::renameFile() {
 
363
        if (mFileViewStack->isVisible()) {
 
364
                mFileViewStack->renameFile();
 
365
        } else {
 
366
                mImageView->renameFile();
 
367
        }
 
368
}
 
369
 
 
370
 
 
371
void MainWindow::copyFiles() {
 
372
        if (mFileViewStack->isVisible()) {
 
373
                mFileViewStack->copyFiles();
 
374
        } else {
 
375
                mImageView->copyFile();
 
376
        }
 
377
}
 
378
 
 
379
 
 
380
void MainWindow::moveFiles() {
 
381
        if (mFileViewStack->isVisible()) {
 
382
                mFileViewStack->moveFiles();
 
383
        } else {
 
384
                mImageView->moveFile();
 
385
        }
 
386
}
 
387
 
 
388
 
 
389
void MainWindow::deleteFiles() {
 
390
        if (mFileViewStack->isVisible()) {
 
391
                mFileViewStack->deleteFiles();
 
392
        } else {
 
393
                mImageView->deleteFile();
 
394
        }
 
395
}
 
396
 
 
397
 
 
398
void MainWindow::showFileProperties() {
 
399
        if (mFileViewStack->isVisible()) {
 
400
                mFileViewStack->showFileProperties();
 
401
        } else {
 
402
                mImageView->showFileProperties();
 
403
        }
 
404
}
 
405
 
 
406
 
 
407
void MainWindow::rotateLeft() {
 
408
        modifyImage(ImageUtils::ROT_270);
 
409
}
 
410
 
 
411
void MainWindow::rotateRight() {
 
412
        modifyImage(ImageUtils::ROT_90);
 
413
}
 
414
 
 
415
void MainWindow::mirror() {
 
416
        modifyImage(ImageUtils::HFLIP);
 
417
}
 
418
 
 
419
void MainWindow::flip() {
 
420
        modifyImage(ImageUtils::VFLIP);
 
421
}
 
422
 
 
423
void MainWindow::modifyImage(ImageUtils::Orientation orientation) {
 
424
        const KURL::List& urls=mFileViewStack->selectedImageURLs();
 
425
        if (mFileViewStack->isVisible() && urls.size()>1) {
 
426
                BatchManipulator manipulator(this, urls, orientation);
 
427
                connect(&manipulator, SIGNAL(imageModified(const KURL&)),
 
428
                        mFileViewStack, SLOT(updateThumbnail(const KURL&)) );
 
429
                manipulator.apply();
 
430
                if (urls.find(mDocument->url())!=urls.end()) {
 
431
                        mDocument->reload();
 
432
                }
 
433
        } else {
 
434
                mDocument->transform(orientation);
 
435
        }
 
436
}
 
437
 
 
438
void MainWindow::showFileDialog() {
 
439
        KURL url=KFileDialog::getOpenURL();
 
440
        if (!url.isValid()) return;
 
441
 
 
442
        openURL(url);
 
443
}
 
444
 
 
445
 
 
446
void MainWindow::printFile() {
 
447
        KPrinter printer;
 
448
 
 
449
        printer.setDocName(mDocument->filename());
 
450
        const KAboutData* pAbout = KApplication::kApplication()->aboutData();
 
451
        QString nm = pAbout->appName();
 
452
        nm += "-";
 
453
        nm += pAbout->version();
 
454
        printer.setCreator( nm );
 
455
 
 
456
        KPrinter::addDialogPage( new PrintDialogPage( mDocument, this, " page"));
 
457
 
 
458
        if (printer.setup(this, QString::null, true)) {
 
459
                mDocument->print(&printer);
 
460
        }
 
461
}
 
462
 
 
463
 
 
464
//-----------------------------------------------------------------------
 
465
//
 
466
// Private slots
 
467
//
 
468
//-----------------------------------------------------------------------
 
469
void MainWindow::slotImageLoading() {
 
470
        if (mShowBusyPtrInFullScreen || !mToggleFullScreen->isChecked()) {
 
471
                if( !mLoadingCursor ) {
 
472
                        kapp->setOverrideCursor(KCursor::workingCursor());
 
473
                }
 
474
                mLoadingCursor = true;
 
475
        }
 
476
}
 
477
 
 
478
 
 
479
void MainWindow::slotImageLoaded() {
 
480
        if( mLoadingCursor )
 
481
                kapp->restoreOverrideCursor();
 
482
        mLoadingCursor = false;
 
483
        updateStatusInfo();
 
484
        updateImageActions();
 
485
        updateLocationURL();
 
486
}
 
487
 
 
488
 
 
489
void MainWindow::hideToolBars() {
 
490
        QPtrListIterator<KToolBar> it=toolBarIterator();
 
491
        KToolBar* bar;
 
492
 
 
493
        for(;it.current()!=0L; ++it) {
 
494
                bar=it.current();
 
495
                if (bar->area()) {
 
496
                        bar->area()->hide();
 
497
                } else {
 
498
                        bar->hide();
 
499
                }
 
500
        }
 
501
}
 
502
 
 
503
 
 
504
void MainWindow::showToolBars() {
 
505
        QPtrListIterator<KToolBar> it=toolBarIterator();
 
506
 
 
507
        KToolBar* bar;
 
508
 
 
509
        for(;it.current()!=0L; ++it) {
 
510
                bar=it.current();
 
511
                if (bar->area()) {
 
512
                        bar->area()->show();
 
513
                } else {
 
514
                        bar->show();
 
515
                }
 
516
        }
 
517
}
 
518
 
 
519
 
 
520
void MainWindow::toggleFullScreen() {
 
521
        if (mToggleFullScreen->isChecked()) {
 
522
                saveMainWindowSettings(KGlobal::config(), "MainWindow");
 
523
 
 
524
                showFullScreen();
 
525
                menuBar()->hide();
 
526
                statusBar()->hide();
 
527
                
 
528
                /* Hide toolbar
 
529
                 * If the toolbar is docked we hide the DockArea to avoid
 
530
                 * having a one pixel band remaining
 
531
                 * For the same reason, we hide all the empty DockAreas
 
532
                 *
 
533
                 * NOTE: This does not work really well if the toolbar is in
 
534
                 * the left or right dock area.
 
535
                 */
 
536
                hideToolBars();
 
537
                if (leftDock()->isEmpty())       leftDock()->hide();
 
538
                if (rightDock()->isEmpty())  rightDock()->hide();
 
539
                if (topDock()->isEmpty())        topDock()->hide();
 
540
                if (bottomDock()->isEmpty()) bottomDock()->hide();
 
541
                
 
542
                if (mToggleBrowse->isChecked()) {
 
543
                        mImageView->reparent(mViewModeWidget, QPoint(0,0));
 
544
                        mCentralStack->raiseWidget(StackIDView);
 
545
                }
 
546
                mImageView->setFullScreen(true);
 
547
                mImageView->setFocus();
 
548
        } else {
 
549
                // Stop the slideshow if it's running, harmless if it does not
 
550
                mSlideShow->stop();
 
551
 
 
552
                // Make sure the file view points to the right URL, it might not be the
 
553
                // case if we are getting out of a slideshow
 
554
                mFileViewStack->setDirURL(mDocument->url().upURL());
 
555
                mFileViewStack->setFileNameToSelect(mDocument->url().fileName());
 
556
 
 
557
                showNormal();
 
558
                menuBar()->show();
 
559
                
 
560
                showToolBars();
 
561
                leftDock()->show();
 
562
                rightDock()->show();
 
563
                topDock()->show();
 
564
                bottomDock()->show();
 
565
                
 
566
                statusBar()->show();
 
567
                mImageView->setFullScreen(false);
 
568
                
 
569
                if (mToggleBrowse->isChecked()) {
 
570
                        mPixmapDock->setWidget(mImageView);
 
571
                        mCentralStack->raiseWidget(StackIDBrowse);
 
572
                }
 
573
                mFileViewStack->setFocus();
 
574
        }
 
575
}
 
576
 
 
577
 
 
578
void MainWindow::startSlideShow() {
 
579
        KURL::List list;
 
580
        KFileItemListIterator it( *mFileViewStack->currentFileView()->items() );
 
581
        for ( ; it.current(); ++it ) {
 
582
                KFileItem* item=it.current();
 
583
                if (!item->isDir() && !Archive::fileItemIsArchive(item)) {
 
584
                        list.append(item->url());
 
585
                }
 
586
        }
 
587
        if (list.count()==0) {
 
588
                return;
 
589
        }
 
590
 
 
591
        SlideShowDialog dialog(this,mSlideShow);
 
592
        if (!dialog.exec()) return;
 
593
        
 
594
        if (!mToggleFullScreen->isChecked()) {
 
595
                mToggleFullScreen->activate();
 
596
        }
 
597
        mSlideShow->start(list);
 
598
}
 
599
 
 
600
 
 
601
void MainWindow::showConfigDialog() {
 
602
        ConfigDialog dialog(this);
 
603
        dialog.exec();
 
604
}
 
605
 
 
606
 
 
607
void MainWindow::showExternalToolDialog() {
 
608
        ExternalToolDialog* dialog=new ExternalToolDialog(this);
 
609
        dialog->show();
 
610
}
 
611
 
 
612
 
 
613
void MainWindow::showKeyDialog() {
 
614
        KKeyDialog dialog(true, this);
 
615
        dialog.insert(actionCollection());
 
616
#ifdef GV_HAVE_KIPI
 
617
        KIPI::PluginLoader::PluginList pluginList=mPluginLoader->pluginList();
 
618
        KIPI::PluginLoader::PluginList::ConstIterator it(pluginList.begin());
 
619
        KIPI::PluginLoader::PluginList::ConstIterator itEnd(pluginList.end());
 
620
        for( ; it!=itEnd; ++it ) {
 
621
                KIPI::Plugin* plugin=(*it)->plugin();
 
622
                if (plugin) {
 
623
                        dialog.insert(plugin->actionCollection(), (*it)->name());
 
624
                }
 
625
        }
 
626
#endif
 
627
        dialog.configure(true);
 
628
}
 
629
 
 
630
 
 
631
void MainWindow::showToolBarDialog() {
 
632
        saveMainWindowSettings(KGlobal::config(), "MainWindow");
 
633
        KEditToolbar dlg(actionCollection());
 
634
        connect(&dlg,SIGNAL(newToolbarConfig()),this,SLOT(applyMainWindowSettings()));
 
635
        if (dlg.exec()) {
 
636
                createGUI();
 
637
        }
 
638
}
 
639
 
 
640
void MainWindow::applyMainWindowSettings() {
 
641
        KMainWindow::applyMainWindowSettings(KGlobal::config(), "MainWindow");
 
642
}
 
643
 
 
644
 
 
645
 
 
646
void MainWindow::escapePressed() {
 
647
        if (mToggleFullScreen->isChecked()) {
 
648
                mToggleFullScreen->activate();
 
649
        }
 
650
}
 
651
 
 
652
 
 
653
void MainWindow::slotDirRenamed(const KURL& oldURL, const KURL& newURL) {
 
654
        LOG(oldURL.prettyURL(0,KURL::StripFileProtocol) << " to " << newURL.prettyURL(0,KURL::StripFileProtocol));
 
655
 
 
656
        KURL url(mFileViewStack->dirURL());
 
657
        if (!oldURL.isParentOf(url) ) {
 
658
                LOG(oldURL.prettyURL() << " is not a parent of " << url.prettyURL());
 
659
                return;
 
660
        }
 
661
 
 
662
        QString oldPath=oldURL.path();
 
663
        LOG("current path: " << url.path() );
 
664
        QString path=newURL.path() + url.path().mid(oldPath.length());
 
665
        LOG("new path: " << path);
 
666
        url.setPath(path);
 
667
        mFileViewStack->setDirURL(url);
 
668
}
 
669
 
 
670
 
 
671
void MainWindow::slotGo() {
 
672
        KURL url(mURLEditCompletion->replacedPath(mURLEdit->currentText()));
 
673
        LOG(url.prettyURL());
 
674
        if( urlIsDirectory(this, url)) {
 
675
                LOG(" '-> is a directory");
 
676
                mFileViewStack->setDirURL(url);
 
677
        } else {
 
678
                LOG(" '-> is not a directory");
 
679
                openURL(url);
 
680
        }
 
681
        mFileViewStack->setFocus();
 
682
}
 
683
 
 
684
void MainWindow::slotShownFileItemRefreshed(const KFileItem*) {
 
685
        LOG("");
 
686
        mDocument->reload();
 
687
}
 
688
        
 
689
 
 
690
void MainWindow::slotToggleCentralStack() {
 
691
        LOG("");
 
692
        if (mToggleBrowse->isChecked()) {
 
693
                mPixmapDock->setWidget(mImageView);
 
694
                mCentralStack->raiseWidget(StackIDBrowse);
 
695
                mFileViewStack->setSilentMode( false );
 
696
                // force re-reading the directory to show the error
 
697
                if( mFileViewStack->lastURLError()) mFileViewStack->retryURL();
 
698
        } else {
 
699
                mImageView->reparent(mViewModeWidget, QPoint(0,0));
 
700
                mCentralStack->raiseWidget(StackIDView);
 
701
                mFileViewStack->setSilentMode( true );
 
702
        }
 
703
 
 
704
        // Make sure the window list actions are disabled if we are in view mode,
 
705
        // otherwise weird things happens when we go back to browse mode
 
706
        QPtrListIterator<KAction> it(mWindowListActions);
 
707
        for (;it.current(); ++it) {
 
708
                it.current()->setEnabled(mToggleBrowse->isChecked());
 
709
        }
 
710
        updateImageActions();
 
711
        updateLocationURL();
 
712
}
 
713
 
 
714
 
 
715
void MainWindow::resetDockWidgets() {
 
716
        mFolderDock->undock();
 
717
        mBookmarkDock->undock();
 
718
        mPixmapDock->undock();
 
719
        mMetaDock->undock();
 
720
 
 
721
        mFolderDock->manualDock(mFileDock, KDockWidget::DockLeft, 4000);
 
722
        mPixmapDock->manualDock(mFolderDock, KDockWidget::DockBottom, 3734);
 
723
        mMetaDock->manualDock(mPixmapDock, KDockWidget::DockBottom, 8560);
 
724
        mBookmarkDock->manualDock(mFolderDock, KDockWidget::DockCenter, 0);
 
725
}
 
726
 
 
727
 
 
728
/**
 
729
 * Display a hint as a temporary message in the status bar
 
730
 */
 
731
void MainWindow::showHint(const QString& hint) {
 
732
        mSBHintLabel->setText(hint);
 
733
 
 
734
        mSBHintLabel->show();
 
735
        mHintTimer->start(HINT_TIMEOUT, true);
 
736
}
 
737
 
 
738
 
 
739
//-----------------------------------------------------------------------
 
740
//
 
741
// GUI
 
742
//
 
743
//-----------------------------------------------------------------------
 
744
void MainWindow::updateStatusInfo() {
 
745
        int pos=mFileViewStack->shownFilePosition();
 
746
        uint count=mFileViewStack->fileCount();
 
747
        QString filename=mDocument->filename();
 
748
        QString txt;
 
749
        if (count==0) {
 
750
                txt=i18n("No Images");
 
751
        } else {
 
752
                txt=i18n("%1/%2 - %3 %4x%5 @ %6%")
 
753
                        .arg(pos+1)
 
754
                        .arg(count)
 
755
                        .arg(filename)
 
756
                        .arg(mDocument->width())
 
757
                        .arg(mDocument->height())
 
758
                        .arg(int(mImageView->zoom()*100) );
 
759
        }
 
760
        mSBDetailLabel->setText(txt);
 
761
        setCaption(filename);
 
762
}
 
763
 
 
764
 
 
765
void MainWindow::updateImageActions() {
 
766
        bool imageActionsEnabled = !mDocument->isNull();
 
767
        
 
768
        mStartSlideShow->setEnabled(imageActionsEnabled);
 
769
        mRotateLeft->setEnabled(imageActionsEnabled);
 
770
        mRotateRight->setEnabled(imageActionsEnabled);
 
771
        mMirror->setEnabled(imageActionsEnabled);
 
772
        mFlip->setEnabled(imageActionsEnabled);
 
773
        mSaveFile->setEnabled(imageActionsEnabled);
 
774
        mSaveFileAs->setEnabled(imageActionsEnabled);
 
775
        mFilePrint->setEnabled(imageActionsEnabled);
 
776
        mReload->setEnabled(imageActionsEnabled);
 
777
 
 
778
        bool fileActionsEnabled = 
 
779
                imageActionsEnabled
 
780
                || (mFileViewStack->isVisible() && mFileViewStack->selectionSize()>0);
 
781
 
 
782
        mRenameFile->setEnabled(fileActionsEnabled);
 
783
        mCopyFiles->setEnabled(fileActionsEnabled);
 
784
        mMoveFiles->setEnabled(fileActionsEnabled);
 
785
        mDeleteFiles->setEnabled(fileActionsEnabled);
 
786
        mShowFileProperties->setEnabled(fileActionsEnabled);
 
787
}
 
788
 
 
789
 
 
790
/**
 
791
 * This method creates all the widgets. Interactions between them and with
 
792
 * actions are created in createObjectInteractions
 
793
 */
 
794
void MainWindow::createWidgets() {
 
795
        KConfig* config=KGlobal::config();
 
796
 
 
797
        mCentralStack=new QWidgetStack(this);
 
798
        setCentralWidget(mCentralStack);
 
799
 
 
800
        mDockArea=new KDockArea(mCentralStack);
 
801
        mCentralStack->addWidget(mDockArea, StackIDBrowse);
 
802
        mDockArea->manager()->setSplitterHighResolution(true);
 
803
        mDockArea->manager()->setSplitterOpaqueResize(true);
 
804
        
 
805
        mViewModeWidget=new QWidget(mCentralStack);
 
806
        QVBoxLayout* layout=new QVBoxLayout(mViewModeWidget);
 
807
        layout->setAutoAdd(true);
 
808
        mCentralStack->addWidget(mViewModeWidget);
 
809
 
 
810
        // Status bar
 
811
        mSBDetailLabel=new QLabel("", statusBar());
 
812
        
 
813
        mSBHintLabel=new TruncatedTextLabel(statusBar());
 
814
        QFont font=mSBHintLabel->font();
 
815
        font.setItalic(true);
 
816
        mSBHintLabel->setFont(font);
 
817
        
 
818
        statusBar()->addWidget(mSBDetailLabel, 0);
 
819
        statusBar()->addWidget(mSBHintLabel, 1);
 
820
        mHintTimer=new QTimer(this);
 
821
        connect(mHintTimer, SIGNAL(timeout()),
 
822
                mSBHintLabel, SLOT(clear()) );
 
823
 
 
824
        // Pixmap widget
 
825
        mPixmapDock = mDockArea->createDockWidget("Image",SmallIcon("gwenview"),NULL,i18n("Image"));
 
826
        mImageView=new ImageView(mPixmapDock,mDocument,actionCollection());
 
827
        mPixmapDock->setWidget(mImageView);
 
828
        connect(mImageView, SIGNAL(requestHintDisplay(const QString&)),
 
829
                this, SLOT(showHint(const QString&)) );
 
830
 
 
831
        // Folder widget
 
832
        mFolderDock = mDockArea->createDockWidget("Folders",SmallIcon("folder_open"),NULL,i18n("Folders"));
 
833
        mDirView=new DirView(mFolderDock);
 
834
        mFolderDock->setWidget(mDirView);
 
835
        
 
836
        // Bookmark widget
 
837
        mBookmarkDock = mDockArea->createDockWidget("Bookmarks", SmallIcon("bookmark"),NULL,i18n("Bookmarks"));
 
838
        QVBox* bmBox=new QVBox(mBookmarkDock);
 
839
        mBookmarkView=new KListView(bmBox);
 
840
        mBookmarkToolBar=new KToolBar(bmBox, "", true);
 
841
        mBookmarkDock->setWidget(bmBox);
 
842
 
 
843
        // File widget
 
844
        mFileDock = mDockArea->createDockWidget("Files",SmallIcon("image"),NULL,i18n("Files"));
 
845
        QVBox* vbox=new QVBox(this);
 
846
        mFileViewToolBar=new KToolBar(vbox, "", true);
 
847
        mFileViewStack=new FileViewStack(vbox, actionCollection());
 
848
        mFileDock->setWidget(vbox);
 
849
        mFileDock->setEnableDocking(KDockWidget::DockNone);
 
850
        mDockArea->setMainDockWidget(mFileDock);
 
851
 
 
852
        // Meta info edit widget
 
853
        mMetaDock = mDockArea->createDockWidget("File Attributes", SmallIcon("info"),NULL,
 
854
                i18n("File Info"));
 
855
        mMetaEdit = new MetaEdit(mMetaDock, mDocument);
 
856
        mMetaDock->setWidget(mMetaEdit);
 
857
 
 
858
        // Slide show controller (not really a widget)
 
859
        mSlideShow=new SlideShow(mDocument);
 
860
        connect( mSlideShow, SIGNAL( nextURL( const KURL& )), SLOT( openURL( const KURL& )));
 
861
 
 
862
        // Default position on desktop
 
863
        setGeometry(20,20,720,520);
 
864
 
 
865
        // Default dock config
 
866
        // (The "magic numbers" were found by adjusting the layout from within the
 
867
        // app and looking at the result in the configuration file)
 
868
        mFolderDock->manualDock(mFileDock, KDockWidget::DockLeft, 4000);
 
869
        mPixmapDock->manualDock(mFolderDock, KDockWidget::DockBottom, 3734);
 
870
        mMetaDock->manualDock(mPixmapDock, KDockWidget::DockBottom, 8560);
 
871
        mBookmarkDock->manualDock(mFolderDock, KDockWidget::DockCenter, 0);
 
872
 
 
873
        // Load dock config if up to date
 
874
        if (config->hasGroup(CONFIG_DOCK_GROUP)) {
 
875
                config->setGroup(CONFIG_DOCK_GROUP);
 
876
                if (config->readNumEntry(CONFIG_GWENVIEW_DOCK_VERSION, 1)==GWENVIEW_DOCK_VERSION) {
 
877
                        mDockArea->readDockConfig(config,CONFIG_DOCK_GROUP);
 
878
                } else {
 
879
                        KMessageBox::sorry(this, i18n(
 
880
                                "<qt><b>Configuration update</b><br>"
 
881
                                "Due to some changes in the dock behavior, your old dock configuration has been discarded. "
 
882
                                "Please adjust your docks again.</qt>")
 
883
                                );
 
884
                        // Store the default dock config and create the
 
885
                        // GWENVIEW_DOCK_VERSION entry
 
886
                        mDockArea->writeDockConfig(config,CONFIG_DOCK_GROUP);
 
887
                        config->writeEntry(CONFIG_GWENVIEW_DOCK_VERSION, GWENVIEW_DOCK_VERSION);
 
888
                        config->sync();
 
889
                }
 
890
        } else {
 
891
                // There was no dock config, lets create the GWENVIEW_DOCK_VERSION entry
 
892
                config->setGroup(CONFIG_DOCK_GROUP);
 
893
                config->writeEntry(CONFIG_GWENVIEW_DOCK_VERSION, GWENVIEW_DOCK_VERSION);
 
894
                config->sync();
 
895
        }
 
896
        
 
897
        // Load config
 
898
        mFileViewStack->readConfig(config,CONFIG_FILEWIDGET_GROUP);
 
899
        mDirView->readConfig(config,CONFIG_DIRWIDGET_GROUP);
 
900
        mImageView->readConfig(config,CONFIG_PIXMAPWIDGET_GROUP);
 
901
        mSlideShow->readConfig(config,CONFIG_SLIDESHOW_GROUP);
 
902
        ThumbnailLoadJob::readConfig(config,CONFIG_THUMBNAILLOADJOB_GROUP);
 
903
        Cache::instance()->readConfig(config,CONFIG_CACHE_GROUP);
 
904
}
 
905
 
 
906
 
 
907
/**
 
908
 * This method creates all the actions Interactions between them and with
 
909
 * widgets are created in createObjectInteractions
 
910
 */
 
911
void MainWindow::createActions() {
 
912
        // Stack
 
913
        mToggleBrowse=new KToggleAction(i18n("Browse"), "folder", CTRL + Key_Return, this, SLOT(slotToggleCentralStack()), actionCollection(), "toggle_browse");
 
914
        mToggleBrowse->setChecked(true);
 
915
        mToggleBrowse->setShortcut(CTRL + Key_Return);
 
916
        
 
917
        // File
 
918
        KStdAction::open(this,SLOT(showFileDialog()),actionCollection() );
 
919
        mSaveFile=KStdAction::save(mDocument,SLOT(save()),actionCollection() );
 
920
        mSaveFileAs=KStdAction::saveAs(mDocument,SLOT(saveAs()),actionCollection() );
 
921
        mFilePrint = KStdAction::print(this, SLOT(printFile()), actionCollection());
 
922
        mRenameFile=new KAction(i18n("&Rename..."),Key_F2,this,SLOT(renameFile()),actionCollection(),"file_rename");
 
923
        mCopyFiles=new KAction(i18n("&Copy To..."),Key_F7,this,SLOT(copyFiles()),actionCollection(),"file_copy");
 
924
        mMoveFiles=new KAction(i18n("&Move To..."),Key_F8,this,SLOT(moveFiles()),actionCollection(),"file_move");
 
925
        mDeleteFiles=new KAction(i18n("&Delete"),"editdelete",Key_Delete,this,SLOT(deleteFiles()),actionCollection(),"file_delete");
 
926
        mShowFileProperties=new KAction(i18n("Properties"),0,this,SLOT(showFileProperties()),actionCollection(),"file_properties");
 
927
        KStdAction::quit( kapp, SLOT (closeAllWindows()), actionCollection() );
 
928
 
 
929
        // Edit
 
930
        mRotateLeft=new KAction(i18n("Rotate &Left"),"rotate_left",CTRL + Key_L, this, SLOT(rotateLeft()),actionCollection(),"rotate_left");
 
931
        mRotateRight=new KAction(i18n("Rotate &Right"),"rotate_right",CTRL + Key_R, this, SLOT(rotateRight()),actionCollection(),"rotate_right");
 
932
        mMirror=new KAction(i18n("&Mirror"),"mirror",0, this, SLOT(mirror()),actionCollection(),"mirror");
 
933
        mFlip=new KAction(i18n("&Flip"),"flip",0, this, SLOT(flip()),actionCollection(),"flip");
 
934
 
 
935
        // View
 
936
        mReload=new KAction(i18n("Reload"), "reload", Key_F5, mDocument, SLOT(reload()), actionCollection(), "reload");
 
937
        mReload->setEnabled(false);
 
938
 
 
939
        mToggleFullScreen= KStdAction::fullScreen(this,SLOT(toggleFullScreen()),actionCollection(),0);
 
940
        mStartSlideShow=new KAction(i18n("Slide Show..."),"slideshow",0,this,SLOT(startSlideShow()),actionCollection(),"slideshow");
 
941
 
 
942
        // Go
 
943
        mGoUp=new KToolBarPopupAction(i18n("Up"), "up", ALT + Key_Up, this, SLOT(goUp()), actionCollection(), "go_up");
 
944
        new KAction( i18n( "Home" ), "gohome", KStdAccel::shortcut(KStdAccel::Home), this, SLOT(goHome()), actionCollection(), "go_home");
 
945
 
 
946
        // Window
 
947
        mResetDockWidgets = new KAction(i18n("Reset"), 0, this, SLOT(resetDockWidgets()), actionCollection(), "reset_dock_widgets");
 
948
 
 
949
        // Settings
 
950
        mShowConfigDialog=
 
951
                KStdAction::preferences(this, SLOT(showConfigDialog()), actionCollection() );
 
952
        mShowKeyDialog=
 
953
                KStdAction::keyBindings(this, SLOT(showKeyDialog()), actionCollection() );
 
954
        (void)new KAction(i18n("Configure External Tools..."), "configure", 0,
 
955
                this, SLOT(showExternalToolDialog()), actionCollection(), "configure_tools");
 
956
        (void)KStdAction::configureToolbars(
 
957
                this, SLOT(showToolBarDialog()), actionCollection() );
 
958
 
 
959
        actionCollection()->readShortcutSettings();
 
960
}
 
961
 
 
962
 
 
963
/**
 
964
 * This method creates the interactions between objects, when it's called, all
 
965
 * widgets and actions have already been created
 
966
 */
 
967
void MainWindow::createObjectInteractions() {
 
968
        // File view toolbar
 
969
        mFileViewStack->listMode()->plug(mFileViewToolBar);
 
970
        mFileViewStack->sideThumbnailMode()->plug(mFileViewToolBar);
 
971
        mFileViewStack->bottomThumbnailMode()->plug(mFileViewToolBar);
 
972
        actionCollection()->action("thumbnails_slider")->plug(mFileViewToolBar);
 
973
        actionCollection()->action("thumbnail_details_dialog")->plug(mFileViewToolBar);
 
974
        
 
975
        // Pixmap view caption formatter
 
976
        mCaptionFormatter.reset( new CaptionFormatter(mFileViewStack, mDocument) );
 
977
        mImageView->setOSDFormatter(mCaptionFormatter.get());
 
978
        
 
979
        // Fullscreen actions in pixmap view
 
980
        KActionPtrList actions;
 
981
        actions.append(mFileViewStack->selectPrevious());
 
982
        actions.append(mFileViewStack->selectNext());
 
983
        actions.append(mToggleFullScreen);
 
984
        mImageView->setFullScreenActions(actions);
 
985
 
 
986
        // Make sure file actions are correctly updated
 
987
        connect(mFileViewStack, SIGNAL(selectionChanged()),
 
988
                this, SLOT(updateImageActions()) );
 
989
 
 
990
        // Bookmarks
 
991
        QString file = locate( "data", "kfile/bookmarks.xml" );
 
992
        if (file.isEmpty()) {
 
993
                file = locateLocal( "data", "kfile/bookmarks.xml" );
 
994
        }
 
995
 
 
996
        KBookmarkManager* manager=KBookmarkManager::managerForFile(file,false);
 
997
        manager->setUpdate(true);
 
998
        manager->setShowNSBookmarks(false);
 
999
 
 
1000
        BookmarkViewController* ctrl=new BookmarkViewController(mBookmarkView, mBookmarkToolBar, manager);
 
1001
        connect(ctrl, SIGNAL(openURL(const KURL&)),
 
1002
                mFileViewStack,SLOT(setDirURL(const KURL&)) );
 
1003
        connect(mFileViewStack, SIGNAL(directoryChanged(const KURL&)),
 
1004
                ctrl, SLOT(setURL(const KURL&)) );
 
1005
 
 
1006
        BookmarkOwner* bookmarkOwner=new BookmarkOwner(this);
 
1007
 
 
1008
        KActionMenu* bookmark=new KActionMenu(i18n( "&Bookmarks" ), "bookmark", actionCollection(), "bookmarks" );
 
1009
        new KBookmarkMenu(manager, bookmarkOwner, bookmark->popupMenu(), 0, true);
 
1010
 
 
1011
        connect(bookmarkOwner,SIGNAL(openURL(const KURL&)),
 
1012
                mFileViewStack,SLOT(setDirURL(const KURL&)) );
 
1013
 
 
1014
        connect(mFileViewStack,SIGNAL(directoryChanged(const KURL&)),
 
1015
                bookmarkOwner,SLOT(setURL(const KURL&)) );
 
1016
}
 
1017
 
 
1018
 
 
1019
void MainWindow::createHideShowAction(KDockWidget* dock) {
 
1020
        QString caption;
 
1021
        if (dock->mayBeHide()) {
 
1022
                caption=i18n("Hide %1").arg(dock->caption());
 
1023
        } else {
 
1024
                caption=i18n("Show %1").arg(dock->caption());
 
1025
        }
 
1026
 
 
1027
        KAction* action=new KAction(caption, 0, dock, SLOT(changeHideShowState()), (QObject*)0 );
 
1028
        if (dock->icon()) {
 
1029
                action->setIconSet( QIconSet(*dock->icon()) );
 
1030
        }
 
1031
        mWindowListActions.append(action);
 
1032
}
 
1033
 
 
1034
 
 
1035
void MainWindow::updateWindowActions() {
 
1036
        unplugActionList("winlist");
 
1037
        mWindowListActions.clear();
 
1038
        createHideShowAction(mFolderDock);
 
1039
        createHideShowAction(mBookmarkDock);
 
1040
        createHideShowAction(mPixmapDock);
 
1041
        createHideShowAction(mMetaDock);
 
1042
        plugActionList("winlist", mWindowListActions);
 
1043
}
 
1044
 
 
1045
 
 
1046
void MainWindow::createConnections() {
 
1047
        connect(mGoUp->popupMenu(), SIGNAL(activated(int)),
 
1048
                this,SLOT(goUpTo(int)));
 
1049
 
 
1050
        // Dir view connections
 
1051
        connect(mDirView,SIGNAL(dirURLChanged(const KURL&)),
 
1052
                mFileViewStack,SLOT(setDirURL(const KURL&)) );
 
1053
 
 
1054
        connect(mDirView, SIGNAL(dirRenamed(const KURL&, const KURL&)),
 
1055
                this, SLOT(slotDirRenamed(const KURL&, const KURL&)) );
 
1056
 
 
1057
        // Pixmap view connections
 
1058
        connect(mImageView,SIGNAL(selectPrevious()),
 
1059
                mFileViewStack,SLOT(slotSelectPrevious()) );
 
1060
        connect(mImageView,SIGNAL(selectNext()),
 
1061
                mFileViewStack,SLOT(slotSelectNext()) );
 
1062
        connect(mImageView,SIGNAL(zoomChanged(double)),
 
1063
                this,SLOT(updateStatusInfo()) );
 
1064
        connect(mImageView,SIGNAL(doubleClicked()),
 
1065
                mToggleFullScreen,SLOT(activate()) );
 
1066
 
 
1067
        // File view connections
 
1068
        connect(mFileViewStack,SIGNAL(urlChanged(const KURL&)),
 
1069
                mDocument,SLOT(setURL(const KURL&)) );
 
1070
        connect(mFileViewStack,SIGNAL(directoryChanged(const KURL&)),
 
1071
                this,SLOT(slotDirURLChanged(const KURL&)) );
 
1072
        connect(mFileViewStack,SIGNAL(directoryChanged(const KURL&)),
 
1073
                mDirView,SLOT(setURL(const KURL&)) );
 
1074
        connect(mFileViewStack,SIGNAL(directoryChanged(const KURL&)),
 
1075
                mHistory,SLOT(addURLToHistory(const KURL&)) );
 
1076
 
 
1077
        connect(mFileViewStack,SIGNAL(completed()),
 
1078
                this,SLOT(updateStatusInfo()) );
 
1079
        connect(mFileViewStack,SIGNAL(canceled()),
 
1080
                this,SLOT(updateStatusInfo()) );
 
1081
        connect(mFileViewStack,SIGNAL(imageDoubleClicked()),
 
1082
                mToggleFullScreen,SLOT(activate()) );
 
1083
        connect(mFileViewStack,SIGNAL(shownFileItemRefreshed(const KFileItem*)),
 
1084
                this,SLOT(slotShownFileItemRefreshed(const KFileItem*)) );
 
1085
        connect(mFileViewStack,SIGNAL(sortingChanged()),
 
1086
                this, SLOT(updateStatusInfo()) );
 
1087
 
 
1088
        // History connections
 
1089
        connect(mHistory, SIGNAL(urlChanged(const KURL&)),
 
1090
                mFileViewStack, SLOT(setDirURL(const KURL&)) );
 
1091
        
 
1092
        // Document connections
 
1093
        connect(mDocument,SIGNAL(loading()),
 
1094
                this,SLOT(slotImageLoading()) );
 
1095
        connect(mDocument,SIGNAL(loaded(const KURL&)),
 
1096
                this,SLOT(slotImageLoaded()) );
 
1097
        connect(mDocument,SIGNAL(saved(const KURL&)),
 
1098
                mFileViewStack,SLOT(updateThumbnail(const KURL&)) );
 
1099
        connect(mDocument,SIGNAL(reloaded(const KURL&)),
 
1100
                mFileViewStack,SLOT(updateThumbnail(const KURL&)) );
 
1101
 
 
1102
        // Slide show
 
1103
        connect(mSlideShow,SIGNAL(finished()),
 
1104
                mToggleFullScreen,SLOT(activate()) );
 
1105
 
 
1106
        // Location bar
 
1107
        connect(mURLEdit, SIGNAL(activated(const QString &)),
 
1108
                this,SLOT(slotGo()) );
 
1109
        connect(mURLEdit, SIGNAL(returnPressed()),
 
1110
                this,SLOT(slotGo()) );
 
1111
 
 
1112
        // Non configurable stop-fullscreen accel
 
1113
        QAccel* accel=new QAccel(this);
 
1114
        accel->connectItem(accel->insertItem(Key_Escape),this,SLOT(escapePressed()));
 
1115
 
 
1116
        // Dock related
 
1117
        connect(mDockArea->manager(), SIGNAL(change()),
 
1118
                this, SLOT(updateWindowActions()) );
 
1119
}
 
1120
 
 
1121
 
 
1122
void MainWindow::createLocationToolBar() {
 
1123
        // URL Combo
 
1124
        mURLEdit=new KHistoryCombo(this);
 
1125
        mURLEdit->setDuplicatesEnabled(false);
 
1126
        mURLEdit->setPixmapProvider(new KURLPixmapProvider);
 
1127
 
 
1128
        mURLEditCompletion=new KURLCompletion();
 
1129
        //mURLEditCompletion->setDir("/");
 
1130
 
 
1131
        mURLEdit->setCompletionObject(mURLEditCompletion);
 
1132
        mURLEdit->setAutoDeleteCompletionObject(true);
 
1133
 
 
1134
        KWidgetAction* comboAction=new KWidgetAction( mURLEdit, i18n("Location Bar"), 0,
 
1135
                0, 0, actionCollection(), "location_url");
 
1136
        comboAction->setShortcutConfigurable(false);
 
1137
        comboAction->setAutoSized(true);
 
1138
 
 
1139
        // Clear button
 
1140
        (void)new KAction( i18n("Clear Location Bar"),
 
1141
                QApplication::reverseLayout()?"clear_left" : "locationbar_erase",
 
1142
                0, this, SLOT(clearLocationLabel()), actionCollection(), "clear_location");
 
1143
 
 
1144
        // URL Label
 
1145
        /* we use "kde toolbar widget" to avoid the flat background (looks bad with
 
1146
         * styles like Keramik). See konq_misc.cc.
 
1147
         */
 
1148
        QLabel* urlLabel=new QLabel(i18n("L&ocation:"), this, "kde toolbar widget");
 
1149
        (void)new KWidgetAction( urlLabel, i18n("L&ocation: "), Key_F6, this, SLOT( activateLocationLabel()),
 
1150
                actionCollection(), "location_label");
 
1151
        urlLabel->setBuddy(mURLEdit);
 
1152
 
 
1153
        // Go button
 
1154
        (void)new KAction(i18n("Go"), "key_enter", 0, this, SLOT(slotGo()), actionCollection(), "location_go");
 
1155
 
 
1156
}
 
1157
 
 
1158
 
 
1159
void MainWindow::clearLocationLabel() {
 
1160
        mURLEdit->clearEdit();
 
1161
        mURLEdit->setFocus();
 
1162
}
 
1163
 
 
1164
 
 
1165
void MainWindow::activateLocationLabel() {
 
1166
        mURLEdit->setFocus();
 
1167
        mURLEdit->lineEdit()->selectAll();
 
1168
}
 
1169
 
 
1170
 
 
1171
#ifdef GV_HAVE_KIPI
 
1172
void MainWindow::loadPlugins() {
 
1173
        // Already done
 
1174
        Q_ASSERT(!mPluginLoader);
 
1175
        if (mPluginLoader) return;
 
1176
 
 
1177
        // Not yet, wait until we're less busy
 
1178
        if (BusyLevelManager::instance()->busyLevel() > BUSY_THUMBNAILS) {
 
1179
                LOG("Too busy, wait");
 
1180
                QTimer::singleShot(LOAD_PLUGIN_DELAY, this, SLOT(loadPlugins()) );
 
1181
                return;
 
1182
        }
 
1183
        
 
1184
        LOG("Load plugins");
 
1185
        // Sets up the plugin interface, and load the plugins
 
1186
        KIPIInterface* interface = new KIPIInterface(this, mFileViewStack);
 
1187
        mPluginLoader = new KIPI::PluginLoader(QStringList(), interface );
 
1188
        connect( mPluginLoader, SIGNAL( replug() ), this, SLOT( slotReplug() ) );
 
1189
        mPluginLoader->loadPlugins();
 
1190
}
 
1191
 
 
1192
 
 
1193
// Helper class for slotReplug(), gcc does not want to instantiate templates
 
1194
// with local classes, so this is declared outside of slotReplug()
 
1195
struct MenuInfo {
 
1196
        QString mName;
 
1197
        QPtrList<KAction> mActions;
 
1198
        MenuInfo() {}
 
1199
        MenuInfo(const QString& name) : mName(name) {}
 
1200
};
 
1201
 
 
1202
void MainWindow::slotReplug() {
 
1203
        typedef QMap<KIPI::Category, MenuInfo> CategoryMap;
 
1204
        CategoryMap categoryMap;
 
1205
        categoryMap[KIPI::IMAGESPLUGIN]=MenuInfo("image_actions");
 
1206
        categoryMap[KIPI::EFFECTSPLUGIN]=MenuInfo("effect_actions");
 
1207
        categoryMap[KIPI::TOOLSPLUGIN]=MenuInfo("tool_actions");
 
1208
        categoryMap[KIPI::IMPORTPLUGIN]=MenuInfo("import_actions");
 
1209
        categoryMap[KIPI::EXPORTPLUGIN]=MenuInfo("export_actions");
 
1210
        categoryMap[KIPI::BATCHPLUGIN]=MenuInfo("batch_actions");
 
1211
        categoryMap[KIPI::COLLECTIONSPLUGIN]=MenuInfo("collection_actions");
 
1212
        
 
1213
        // Fill the mActions
 
1214
        KIPI::PluginLoader::PluginList pluginList=mPluginLoader->pluginList();
 
1215
        KIPI::PluginLoader::PluginList::ConstIterator it(pluginList.begin());
 
1216
        KIPI::PluginLoader::PluginList::ConstIterator itEnd(pluginList.end());
 
1217
        for( ; it!=itEnd; ++it ) {
 
1218
                if (!(*it)->shouldLoad()) continue;
 
1219
                KIPI::Plugin* plugin = (*it)->plugin();
 
1220
                Q_ASSERT(plugin);
 
1221
                if (!plugin) continue;
 
1222
 
 
1223
                plugin->setup(this);
 
1224
                KActionPtrList actions = plugin->actions();
 
1225
                KActionPtrList::ConstIterator actionIt=actions.begin(), end=actions.end();
 
1226
                for (; actionIt!=end; ++actionIt) {
 
1227
                        KIPI::Category category = plugin->category(*actionIt);
 
1228
 
 
1229
                        if (!categoryMap.contains(category)) {
 
1230
                                kdWarning() << "Unknown category '" << category << "'\n";
 
1231
                                continue;
 
1232
                        }
 
1233
 
 
1234
                        categoryMap[category].mActions.append(*actionIt);
 
1235
                }
 
1236
                plugin->actionCollection()->readShortcutSettings();
 
1237
        }
 
1238
 
 
1239
        // Create a dummy "no plugin" action list
 
1240
        KAction* noPlugin=new KAction(i18n("No Plugin"), 0, 0, 0, actionCollection(), "no_plugin");
 
1241
        noPlugin->setShortcutConfigurable(false);
 
1242
        noPlugin->setEnabled(false);
 
1243
        QPtrList<KAction> noPluginList;
 
1244
        noPluginList.append(noPlugin);
 
1245
        
 
1246
        // Fill the menu
 
1247
        CategoryMap::ConstIterator catIt=categoryMap.begin(), catItEnd=categoryMap.end();
 
1248
        for (; catIt!=catItEnd; ++catIt) {
 
1249
                const MenuInfo& info=catIt.data();
 
1250
                unplugActionList(info.mName);
 
1251
                if (info.mActions.count()>0) {
 
1252
                        plugActionList(info.mName, info.mActions);
 
1253
                } else {
 
1254
                        plugActionList(info.mName, noPluginList);
 
1255
                }
 
1256
        }
 
1257
}
 
1258
#else
 
1259
void MainWindow::loadPlugins() {
 
1260
        QPopupMenu *popup = static_cast<QPopupMenu*>(
 
1261
                factory()->container( "plugins", this));
 
1262
        delete popup;
 
1263
}
 
1264
 
 
1265
 
 
1266
void MainWindow::slotReplug() {
 
1267
}
 
1268
#endif
 
1269
 
 
1270
 
 
1271
//-----------------------------------------------------------------------
 
1272
//
 
1273
// Properties
 
1274
//
 
1275
//-----------------------------------------------------------------------
 
1276
void MainWindow::setShowBusyPtrInFullScreen(bool value) {
 
1277
        mShowBusyPtrInFullScreen=value;
 
1278
}
 
1279
 
 
1280
void MainWindow::setAutoDeleteThumbnailCache(bool value){
 
1281
        mAutoDeleteThumbnailCache=value;
 
1282
}
 
1283
 
 
1284
 
 
1285
//-----------------------------------------------------------------------
 
1286
//
 
1287
// Configuration
 
1288
//
 
1289
//-----------------------------------------------------------------------
 
1290
void MainWindow::readConfig(KConfig* config,const QString& group) {
 
1291
        config->setGroup(group);
 
1292
        mShowBusyPtrInFullScreen=config->readBoolEntry(CONFIG_BUSYPTR_IN_FS, true);
 
1293
        mAutoDeleteThumbnailCache=config->readBoolEntry(CONFIG_AUTO_DELETE_THUMBNAIL_CACHE, false);     
 
1294
}
 
1295
 
 
1296
 
 
1297
void MainWindow::writeConfig(KConfig* config,const QString& group) const {
 
1298
        config->setGroup(group);
 
1299
        config->writeEntry(CONFIG_BUSYPTR_IN_FS, mShowBusyPtrInFullScreen);
 
1300
        config->writeEntry(CONFIG_AUTO_DELETE_THUMBNAIL_CACHE, mAutoDeleteThumbnailCache);
 
1301
}
 
1302
 
 
1303
} // namespace