// vim: set tabstop=4 shiftwidth=4 noexpandtab:
// kate: indent-mode csands; indent-width 4; replace-tabs-save off; replace-tabs off; replace-trailing-space-save off; space-indent off; tabs-indents on; tab-width 4;
/*
Gwenview - A simple image viewer for TDE
Copyright 2000-2004 Aur�ien G�eau

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 "mainwindow.moc"

// TQt
#include <tqdir.h>
#include <tqdockarea.h>
#include <tqwidgetstack.h>

// KDE
#include <kaboutdata.h>
#include <kaccel.h>
#include <kaction.h>
#include <kapplication.h>
#include <kbookmarkmanager.h>
#include <kbookmarkmenu.h>
#include <kcombobox.h>
#include <kconfig.h>
#include <kcursor.h>
#include <kdebug.h>
#include <tdeversion.h>
#include <kdockwidget.h>
#include <kedittoolbar.h>
#include <kfiledialog.h>
#include <kglobal.h>
#include <khelpmenu.h>
#include <kiconloader.h>
#include <kio/netaccess.h>
#include <kkeydialog.h>
#include <klargefile.h>
#include <klistview.h>
#include <klocale.h>
#include <kmenubar.h>
#include <kmessagebox.h>
#include <kpopupmenu.h>
#include <kpropsdlg.h>
#include <kprotocolinfo.h>
#include <kstandarddirs.h>
#include <kstatusbar.h>
#include <kstdaccel.h>
#include <kstdaction.h>
#include <ktoolbarlabelaction.h>
#include <kurlcompletion.h>
#include <kurlpixmapprovider.h>
#include <kprinter.h>

#include <config.h>
// KIPI
#ifdef GV_HAVE_KIPI
#include <libkipi/plugin.h>
#include <libkipi/pluginloader.h>
#endif

// Local
#include "bookmarkowner.h"
#include "bookmarkviewcontroller.h"
#include "configdialog.h"
#include "dirviewcontroller.h"
#include "history.h"
#include "metaedit.h"
#include "truncatedtextlabel.h"
#include "vtabwidget.h"

#include "gvcore/externaltoolcontext.h"
#include "gvcore/externaltoolmanager.h"
#include "gvcore/fileoperation.h"
#include "gvcore/archive.h"
#include "gvcore/captionformatter.h"
#include "gvcore/document.h"
#include "gvcore/externaltooldialog.h"
#include "gvcore/fileviewbase.h"
#include "gvcore/fileviewcontroller.h"
#include "gvcore/imageview.h"
#include "gvcore/imageviewcontroller.h"
#include "gvcore/slideshow.h"
#include "gvcore/printdialog.h"
#include "gvcore/cache.h"
#include "gvcore/thumbnailloadjob.h"
#include <../gvcore/slideshowconfig.h>
#include <../gvcore/fullscreenconfig.h>
#include <../gvcore/fileviewconfig.h>
#include <../gvcore/miscconfig.h>

#include "config.h"

#ifdef GV_HAVE_KIPI
#include "kipiinterface.h"
#endif

namespace Gwenview {

const char CONFIG_DOCK_GROUP[]="dock";
const char CONFIG_DIRWIDGET_GROUP[]="dir widget";
const char CONFIG_PIXMAPWIDGET_GROUP[]="pixmap widget";
const char CONFIG_CACHE_GROUP[]="cache";

const char CONFIG_GWENVIEW_DOCK_VERSION[]="Gwenview version";

const char CONFIG_SESSION_URL[] = "url";

// This version is here to avoid configuration migration troubles when changes
// are made to the dock behavior
const int GWENVIEW_DOCK_VERSION=2;

// The timeout before an hint in the statusbar disappear (in msec)
const int HINT_TIMEOUT=10000;

// How many items should be stored in history
const int HISTORY_MAX_COUNT=20;

#undef ENABLE_LOG
#undef LOG
//#define ENABLE_LOG
#ifdef ENABLE_LOG
#define LOG(x) kdDebug() << k_funcinfo << x << endl
#else
#define LOG(x) ;
#endif

enum { StackIDBrowse, StackIDView };


static bool urlIsDirectory(TQWidget* parent, const KURL& url) {
	if( url.filename( false ).isEmpty()) return true; // file:/somewhere/<nothing here>
	// Do direct stat instead of using KIO if the file is local (faster)
	if( url.isLocalFile()
		&& !KIO::probably_slow_mounted( url.path())) {
		KDE_struct_stat buff;
		if ( KDE_stat( TQFile::encodeName(url.path()), &buff ) == 0 )  {
			return S_ISDIR( buff.st_mode );
		}
	}
	KIO::UDSEntry entry;
	if( KIO::NetAccess::stat( url, entry, parent)) {
		KIO::UDSEntry::ConstIterator it;
		for(it=entry.begin();it!=entry.end();++it) {
			if ((*it).m_uds==KIO::UDS_FILE_TYPE) {
				return S_ISDIR( (*it).m_long );
			}
		}
	}
	return false;
}


MainWindow::MainWindow()
: KMainWindow()
#ifdef GV_HAVE_KIPI
, mPluginLoader(0)
#endif
{
	// Backend
	mDocument=new Document(TQT_TQOBJECT(this));
	mHistory=new History(actionCollection());
	// GUI
	createActions();
	createWidgets();
	createLocationToolBar();
	createObjectInteractions();

	setStandardToolBarMenuEnabled(true);
	createGUI("gwenviewui.rc", false);

	createConnections();
	mWindowListActions.setAutoDelete(true);
	updateWindowActions();
	KMainWindow::applyMainWindowSettings(KGlobal::config(), "MainWindow");
}


void MainWindow::setFullScreen(bool value) {
	if (value != mToggleFullScreen->isChecked()) {
		mToggleFullScreen->activate();
	}
}


bool MainWindow::queryClose() {
	mDocument->saveBeforeClosing();

	KConfig* config=KGlobal::config();

	// Don't store dock layout if only the image dock is visible. This avoid
	// saving layout when in "fullscreen" or "image only" mode.
	if (mFileViewController->isVisible() || mDirViewController->widget()->isVisible()) {
		mDockArea->writeDockConfig(config,CONFIG_DOCK_GROUP);
	}

	if (FileViewConfig::deleteCacheOnExit()) {
		TQString dir=ThumbnailLoadJob::thumbnailBaseDir();

		if (TQFile::exists(dir)) {
			KURL url;
			url.setPath(dir);
			KIO::NetAccess::del(url, this);
		}
	}
	
	if (!mToggleFullScreen->isChecked()) {
		saveMainWindowSettings(KGlobal::config(), "MainWindow");
	}
	MiscConfig::setHistory( mURLEdit->historyItems() );
	MiscConfig::writeConfig();
	return true;
}

void MainWindow::saveProperties( KConfig* cfg ) {
	cfg->writeEntry( CONFIG_SESSION_URL, mFileViewController->url().url());
}

void MainWindow::readProperties( KConfig* cfg ) {
	KURL url(cfg->readEntry(CONFIG_SESSION_URL));
	openURL(url);
}

//-----------------------------------------------------------------------
//
// Public slots
//
//-----------------------------------------------------------------------
void MainWindow::openURL(const KURL& url) {
	bool isDir = urlIsDirectory(this, url);
	LOG("url=" << url.prettyURL() << ", isDir=" << isDir);

	if (isDir) {
		mFileViewController->setDirURL(url);
		mFileViewController->setFocus();
	} else {
		mDocument->setURL(url);
		mFileViewController->setDirURL(url.upURL());
		mFileViewController->setFileNameToSelect(url.filename());
		mImageViewController->setFocus();
	}
	
	if (!mToggleFullScreen->isChecked() && !isDir && !mSwitchToViewMode->isChecked()) {
		mSwitchToViewMode->activate();
	}
}

void MainWindow::slotRenamed(const TQString& fileName) {
	KURL url = mDocument->url();
	url.setFileName(fileName);
	mDocument->setURL(url);
}
	
void MainWindow::slotDirURLChanged(const KURL& dirURL) {
	LOG(dirURL.prettyURL(0,KURL::StripFileProtocol));
	
	mGoUp->setEnabled(dirURL.path()!="/");

	updateStatusInfo();
	updateImageActions();
	updateLocationURL();
}

void MainWindow::updateLocationURL() {
	LOG("");
	KURL url;
	if (mSwitchToBrowseMode->isChecked()) {
		url=mFileViewController->dirURL();
		if (!url.isValid()) {
			url=mDocument->url();
		}
	} else {
		url=mDocument->url();
	}
	LOG(url.prettyURL());
	mURLEdit->setEditText(url.pathOrURL());
	mURLEdit->addToHistory(url.pathOrURL());
}

void MainWindow::goUp() {
	KURL url = mFileViewController->dirURL();
	mFileViewController->setDirURL(url.upURL());
	mFileViewController->setFileNameToSelect(url.fileName());
}

void MainWindow::updateFullScreenLabel() {
	CaptionFormatter formatter;
	formatter.mPath=mDocument->url().path();
	formatter.mFileName=mDocument->url().fileName();
	formatter.mComment=mDocument->comment();
	formatter.mImageSize=mDocument->image().size();
	formatter.mPosition=mFileViewController->shownFilePosition()+1;
	formatter.mCount=mFileViewController->fileCount();
	formatter.mAperture=mDocument->aperture();
	formatter.mExposureTime=mDocument->exposureTime();
	formatter.mIso=mDocument->iso();
	formatter.mFocalLength=mDocument->focalLength();
	
	TQString txt=formatter.format( FullScreenConfig::osdFormat() );
	mFullScreenLabelAction->label()->setText(txt);
}

void MainWindow::goUpTo(int id) {
	KPopupMenu* menu=mGoUp->popupMenu();
	KURL url(menu->text(id));
	KURL childURL;
	int index=menu->indexOf(id);
	if (index>0) {
		childURL=KURL(menu->text(menu->idAt(index-1)));
	} else {
		childURL=mDocument->dirURL();
	}
	mFileViewController->setDirURL(url);
	mFileViewController->setFileNameToSelect(childURL.fileName());
}

void MainWindow::fillGoUpMenu() {
	TQPopupMenu* menu = mGoUp->popupMenu();
	menu->clear();
	int pos = 0;
	KURL url = mFileViewController->dirURL().upURL();
	for (; url.hasPath() && pos<10; url=url.upURL(), ++pos) {
		menu->insertItem(url.pathOrURL());
		if (url.path()=="/") break;
	}
}


//-----------------------------------------------------------------------
//
// File operations
//
//-----------------------------------------------------------------------
void MainWindow::goHome() {
	KURL url;
	url.setPath( TQDir::homeDirPath() );
	mFileViewController->setDirURL(url);
}


void MainWindow::renameFile() {
	KURL url;
	if (mFileViewController->isVisible()) {
		KURL::List list = mFileViewController->selectedURLs();
		Q_ASSERT(list.count()==1);
		if (list.count()!=1) return;
		url = list.first();
	} else {
		url = mDocument->url();
	}
	FileOperation::rename(url, this, TQT_TQOBJECT(this), TQT_SLOT(slotRenamed(const TQString &)));
}


void MainWindow::copyFiles() {
	KURL::List list;
	if (mFileViewController->isVisible()) {
		list = mFileViewController->selectedURLs();
	} else {
		list << mDocument->url();
	}
	FileOperation::copyTo(list, this);
}

void MainWindow::linkFiles() {
	KURL::List list;
	if (mFileViewController->isVisible()) {
		list = mFileViewController->selectedURLs();
	} else {
		list << mDocument->url();
	}
	FileOperation::linkTo(list, this);
}


void MainWindow::moveFiles() {
	KURL::List list;
	if (mFileViewController->isVisible()) {
		list = mFileViewController->selectedURLs();
	} else {
		list << mDocument->url();
	}
	FileOperation::moveTo(list, this);
}


void MainWindow::deleteFiles() {
	KURL::List list;
	if (mFileViewController->isVisible()) {
		list = mFileViewController->selectedURLs();
	} else {
		list << mDocument->url();
	}
	FileOperation::del(list, this);
}


void MainWindow::makeDir() {
	FileOperation::makeDir(mFileViewController->dirURL(), this);
}


void MainWindow::showFileProperties() {
	if (mFileViewController->isVisible()) {
		const KFileItemList* list = mFileViewController->currentFileView()->selectedItems();
		if (list->count() > 0) {
			(void)new KPropertiesDialog(*list, this);
		} else {
			(void)new KPropertiesDialog(mFileViewController->dirURL(), this);
		}
	} else {
		(void)new KPropertiesDialog(mDocument->url(), this);
	}
}


void MainWindow::rotateLeft() {
	mDocument->transform(ImageUtils::ROT_270);
}

void MainWindow::rotateRight() {
	mDocument->transform(ImageUtils::ROT_90);
}

void MainWindow::mirror() {
	mDocument->transform(ImageUtils::HFLIP);
}

void MainWindow::flip() {
	mDocument->transform(ImageUtils::VFLIP);
}

void MainWindow::showFileDialog() {
	KURL url=KFileDialog::getOpenURL();
	if (!url.isValid()) return;

	openURL(url);
}


void MainWindow::printFile() {
	KPrinter printer;

	printer.setDocName(mDocument->filename());
	const KAboutData* pAbout = KApplication::kApplication()->aboutData();
	TQString nm = pAbout->appName();
	nm += "-";
	nm += pAbout->version();
	printer.setCreator( nm );

	KPrinter::addDialogPage( new PrintDialogPage( mDocument, this, " page"));

	if (printer.setup(this, TQString(), true)) {
		mDocument->print(&printer);
	}
}


//-----------------------------------------------------------------------
//
// Private slots
//
//-----------------------------------------------------------------------
void MainWindow::openFileViewControllerContextMenu(const TQPoint& pos, bool onItem) {
	int selectionSize;
	ExternalToolContext* externalToolContext;

	if (onItem) {
		const KFileItemList* items = mFileViewController->currentFileView()->selectedItems();
		selectionSize = items->count();
		externalToolContext =
			ExternalToolManager::instance()->createContext(TQT_TQOBJECT(this), items);
	} else {
		selectionSize = 0;
		externalToolContext =
			ExternalToolManager::instance()->createContext(TQT_TQOBJECT(this), mFileViewController->dirURL());
	}

	TQPopupMenu menu(this);

	menu.insertItem(
		i18n("External Tools"), externalToolContext->popupMenu());

	actionCollection()->action("view_sort")->plug(&menu);
	mGoUp->plug(&menu);

	menu.insertItem(SmallIcon("folder_new"), i18n("New Folder..."), TQT_TQOBJECT(this), TQT_SLOT(makeDir()));

	menu.insertSeparator();

	if (selectionSize==1) {
		mRenameFile->plug(&menu);
	}

	if (selectionSize>=1) {
		mCopyFiles->plug(&menu);
		mMoveFiles->plug(&menu);
		mLinkFiles->plug(&menu);
		mDeleteFiles->plug(&menu);
		menu.insertSeparator();
	}

	mShowFileProperties->plug(&menu);
	menu.exec(pos);
}


void MainWindow::slotImageLoading() {
	if (FullScreenConfig::showBusyPtr() || !mToggleFullScreen->isChecked()) {
		kapp->setOverrideCursor(KCursor::workingCursor(), true /* replace */);
	}
}


void MainWindow::slotImageLoaded() {
	// Reciproc of slotImageLoading
	if (FullScreenConfig::showBusyPtr() || !mToggleFullScreen->isChecked()) {
		kapp->restoreOverrideCursor();
	}
	updateStatusInfo();
	updateImageActions();
	updateLocationURL();
	if (mToggleFullScreen->isChecked()) {
		updateFullScreenLabel();
	}
}


void MainWindow::hideToolBars() {
	TQPtrListIterator<KToolBar> it=toolBarIterator();
	KToolBar* bar;

	for(;it.current()!=0L; ++it) {
		bar=it.current();
		if (bar->area()) {
			bar->area()->hide();
		} else {
			bar->hide();
		}
	}
}


void MainWindow::showToolBars() {
	TQPtrListIterator<KToolBar> it=toolBarIterator();

	KToolBar* bar;

	for(;it.current()!=0L; ++it) {
		bar=it.current();
		if (bar->area()) {
			bar->area()->show();
		} else {
			bar->show();
		}
	}
}


void MainWindow::toggleFullScreen() {
	if (mToggleFullScreen->isChecked()) {
		saveMainWindowSettings(KGlobal::config(), "MainWindow");

		showFullScreen();
		menuBar()->hide();
		statusBar()->hide();
		
		/* Hide toolbar
		 * If the toolbar is docked we hide the DockArea to avoid
		 * having a one pixel band remaining
		 * For the same reason, we hide all the empty DockAreas
		 *
		 * NOTE: This does not work really well if the toolbar is in
		 * the left or right dock area.
		 */
		hideToolBars();
		if (leftDock()->isEmpty())	 leftDock()->hide();
		if (rightDock()->isEmpty())  rightDock()->hide();
		if (topDock()->isEmpty())	 topDock()->hide();
		if (bottomDock()->isEmpty()) bottomDock()->hide();
		
		if (mSwitchToBrowseMode->isChecked()) {
			mImageViewController->widget()->reparent(mViewModeWidget, TQPoint(0,0));
			mCentralStack->raiseWidget(StackIDView);
		}
		updateFullScreenLabel();
		mImageViewController->setFullScreen(true);
		mImageViewController->setFocus();
	} else {
		// Stop the slideshow if it's running
		if (mSlideShow->isRunning()) {
			mToggleSlideShow->activate();
		}

		// Make sure the file view points to the right URL, it might not be the
		// case if we are getting out of a slideshow
		mFileViewController->setDirURL(mDocument->url().upURL());
		mFileViewController->setFileNameToSelect(mDocument->url().fileName());

		showNormal();
		menuBar()->show();
		
		showToolBars();
		leftDock()->show();
		rightDock()->show();
		topDock()->show();
		bottomDock()->show();
		
		statusBar()->show();
		mImageViewController->setFullScreen(false);
		
		if (mSwitchToBrowseMode->isChecked()) {
			mImageDock->setWidget(mImageViewController->widget());
			mCentralStack->raiseWidget(StackIDBrowse);
			mFileViewController->setFocus();
		}
	}
}


void MainWindow::toggleSlideShow() {
	if (mSlideShow->isRunning()) {
		mSlideShow->stop();
		return;
	}
	
	KURL::List list;
	KFileItemListIterator it( *mFileViewController->currentFileView()->items() );
	for ( ; it.current(); ++it ) {
		KFileItem* item=it.current();
		if (!item->isDir() && !Archive::fileItemIsArchive(item)) {
			list.append(item->url());
		}
	}
	if (list.count()==0) {
		return;
	}

	if (SlideShowConfig::fullscreen() && !mToggleFullScreen->isChecked()) {
		mToggleFullScreen->activate();
	}
	mSlideShow->start(list);
	}


void MainWindow::slotSlideShowChanged(bool running) {
 	mToggleSlideShow->setIcon(running ? "slideshow_pause" : "slideshow_play");
}


void MainWindow::showConfigDialog() {
#ifdef GV_HAVE_KIPI
	if (!mPluginLoader) loadPlugins();
	ConfigDialog dialog(this, mPluginLoader);
#else
	ConfigDialog dialog(this, 0);
#endif
	connect(&dialog, TQT_SIGNAL(settingsChanged()),
		mSlideShow, TQT_SLOT(slotSettingsChanged()) );
	connect(&dialog, TQT_SIGNAL(settingsChanged()),
		mImageViewController, TQT_SLOT(updateFromSettings()) );
	connect(&dialog, TQT_SIGNAL(settingsChanged()),
		mFileViewController, TQT_SLOT(updateFromSettings()) );
	dialog.exec();
}


void MainWindow::showExternalToolDialog() {
	ExternalToolDialog* dialog=new ExternalToolDialog(this);
	dialog->show();
}


void MainWindow::showKeyDialog() {
	KKeyDialog dialog(true, this);
	dialog.insert(actionCollection());
	dialog.configure(true);
}


void MainWindow::showToolBarDialog() {
	saveMainWindowSettings(KGlobal::config(), "MainWindow");
	KEditToolbar dlg(actionCollection());
	connect(&dlg,TQT_SIGNAL(newToolbarConfig()),TQT_TQOBJECT(this),TQT_SLOT(applyMainWindowSettings()));
	dlg.exec();
}

void MainWindow::applyMainWindowSettings() {
	createGUI();
	KMainWindow::applyMainWindowSettings(KGlobal::config(), "MainWindow");
}



void MainWindow::escapePressed() {
	if (mToggleFullScreen->isChecked()) {
		mToggleFullScreen->activate();
	}
}


void MainWindow::slotDirRenamed(const KURL& oldURL, const KURL& newURL) {
	LOG(oldURL.prettyURL(0,KURL::StripFileProtocol) << " to " << newURL.prettyURL(0,KURL::StripFileProtocol));

	KURL url(mFileViewController->dirURL());
	if (!oldURL.isParentOf(url) ) {
		LOG(oldURL.prettyURL() << " is not a parent of " << url.prettyURL());
		return;
	}

	TQString oldPath=oldURL.path();
	LOG("current path: " << url.path() );
	TQString path=newURL.path() + url.path().mid(oldPath.length());
	LOG("new path: " << path);
	url.setPath(path);
	mFileViewController->setDirURL(url);
}


void MainWindow::slotGo() {
	KURL url(mURLEditCompletion->replacedPath(mURLEdit->currentText()));
	LOG(url.prettyURL());
	openURL(url);
	mFileViewController->setFocus();
}

void MainWindow::slotShownFileItemRefreshed(const KFileItem*) {
	LOG("");
	mDocument->reload();
}
	

void MainWindow::slotToggleCentralStack() {
	LOG("");
	if (mSwitchToBrowseMode->isChecked()) {
		mImageDock->setWidget(mImageViewController->widget());
		mCentralStack->raiseWidget(StackIDBrowse);
		mFileViewController->setSilentMode( false );
		// force re-reading the directory to show the error
		if( mFileViewController->lastURLError()) mFileViewController->retryURL();
	} else {
		mImageViewController->widget()->reparent(mViewModeWidget, TQPoint(0,0));
		mCentralStack->raiseWidget(StackIDView);
		mFileViewController->setSilentMode( true );
	}

	// Make sure the window list actions are disabled if we are in view mode,
	// otherwise weird things happens when we go back to browse mode
	TQPtrListIterator<KAction> it(mWindowListActions);
	for (;it.current(); ++it) {
		it.current()->setEnabled(mSwitchToBrowseMode->isChecked());
	}
	updateImageActions();
	updateLocationURL();
}


void MainWindow::resetDockWidgets() {
	int answer=KMessageBox::warningContinueCancel(this,
		i18n("You are about to revert the window setup to factory defaults, are you sure?"),
		TQString() /* caption */,
		i18n("Reset"));
	if (answer==KMessageBox::Cancel) return;
	
	mFolderDock->undock();
	mImageDock->undock();
	mMetaDock->undock();

	mFolderDock->manualDock(mFileDock, KDockWidget::DockLeft, 4000);
	mImageDock->manualDock(mFolderDock, KDockWidget::DockBottom, 3734);
	mMetaDock->manualDock(mImageDock, KDockWidget::DockBottom, 8560);
}


/**
 * Display a hint as a temporary message in the status bar
 */
void MainWindow::showHint(const TQString& hint) {
	mSBHintLabel->setText(hint);

	mSBHintLabel->show();
	mHintTimer->start(HINT_TIMEOUT, true);
}


//-----------------------------------------------------------------------
//
// GUI
//
//-----------------------------------------------------------------------
void MainWindow::updateStatusInfo() {
	TQStringList tokens;

	if ( KProtocolInfo::supportsListing(mFileViewController->url()) ) {
		int pos = mFileViewController->shownFilePosition();
		uint count = mFileViewController->fileCount();
		if (count > 0) {
			tokens << i18n("%1/%2").arg(pos+1).arg(count);
		} else {
			tokens << i18n("No images");
		}
	}

	TQString filename = mDocument->filename();

	TQSize size = mDocument->image().size();
	if (!size.isEmpty()) {
		tokens << i18n("%1 x %2 pixels").arg(size.width()).arg(size.height());
	}
	
	mSBDetailLabel->setText(tokens.join(" - "));
	setCaption(filename);
}


void MainWindow::updateImageActions() {
	mToggleSlideShow->setEnabled(mDocument->urlKind()!=MimeTypeUtils::KIND_UNKNOWN);
	
	bool imageActionsEnabled = !mDocument->isNull();
	
	mRotateLeft->setEnabled(imageActionsEnabled);
	mRotateRight->setEnabled(imageActionsEnabled);
	mMirror->setEnabled(imageActionsEnabled);
	mFlip->setEnabled(imageActionsEnabled);
	mSaveFile->setEnabled(imageActionsEnabled);
	mSaveFileAs->setEnabled(imageActionsEnabled);
	mFilePrint->setEnabled(imageActionsEnabled);
	mReload->setEnabled(imageActionsEnabled);

	bool fileActionsEnabled = 
		imageActionsEnabled
		|| (mFileViewController->isVisible() && mFileViewController->selectionSize()>0);

	mRenameFile->setEnabled(fileActionsEnabled);
	mCopyFiles->setEnabled(fileActionsEnabled);
	mMoveFiles->setEnabled(fileActionsEnabled);
	mLinkFiles->setEnabled(fileActionsEnabled);
	mDeleteFiles->setEnabled(fileActionsEnabled);
	mShowFileProperties->setEnabled(fileActionsEnabled);
}


/**
 * This method creates all the widgets. Interactions between them and with
 * actions are created in createObjectInteractions
 */
void MainWindow::createWidgets() {
	KConfig* config=KGlobal::config();

	mCentralStack=new TQWidgetStack(this);
	setCentralWidget(mCentralStack);

	mDockArea=new KDockArea(mCentralStack);
	mCentralStack->addWidget(mDockArea, StackIDBrowse);
	mDockArea->manager()->setSplitterHighResolution(true);
	mDockArea->manager()->setSplitterOpaqueResize(true);
	
	mViewModeWidget=new TQWidget(mCentralStack);
	TQVBoxLayout* layout=new TQVBoxLayout(mViewModeWidget);
	layout->setAutoAdd(true);
	mCentralStack->addWidget(mViewModeWidget);

	// Status bar
	mSBDetailLabel=new TQLabel("", statusBar());
	
	mSBHintLabel=new TruncatedTextLabel(statusBar());
	TQFont font=mSBHintLabel->font();
	font.setItalic(true);
	mSBHintLabel->setFont(font);
	
	statusBar()->addWidget(mSBDetailLabel, 0);
	statusBar()->addWidget(mSBHintLabel, 1);
	mHintTimer=new TQTimer(this);
	connect(mHintTimer, TQT_SIGNAL(timeout()),
		mSBHintLabel, TQT_SLOT(clear()) );

	// Pixmap widget
	mImageDock = mDockArea->createDockWidget("Image",SmallIcon("gwenview"),NULL,i18n("Image"));
	mImageViewController=new ImageViewController(mImageDock, mDocument, actionCollection());
	mImageDock->setWidget(mImageViewController->widget());
	connect(mImageViewController, TQT_SIGNAL(requestHintDisplay(const TQString&)),
		TQT_TQOBJECT(this), TQT_SLOT(showHint(const TQString&)) );

	// Folder widget
	mFolderDock = mDockArea->createDockWidget("Folders",SmallIcon("folder_open"),NULL,i18n("Folders"));
	VTabWidget* vtabWidget=new VTabWidget(mFolderDock);
	mFolderDock->setWidget(vtabWidget);
	
	mDirViewController=new DirViewController(vtabWidget);
	vtabWidget->addTab(mDirViewController->widget(), SmallIcon("folder"), i18n("Folders"));

	mBookmarkViewController=new BookmarkViewController(vtabWidget);
	vtabWidget->addTab(mBookmarkViewController->widget(), SmallIcon("bookmark"), i18n("Bookmarks"));

	// File widget
	mFileDock = mDockArea->createDockWidget("Files",SmallIcon("image"),NULL,i18n("Files"));
	mFileViewController=new FileViewController(this, actionCollection());
	mFileDock->setWidget(mFileViewController);
	mFileDock->setEnableDocking(KDockWidget::DockNone);
	mDockArea->setMainDockWidget(mFileDock);

	// Meta info edit widget
	mMetaDock = mDockArea->createDockWidget("File Attributes", SmallIcon("info"),NULL,
		i18n("Image Comment"));
	mMetaEdit = new MetaEdit(mMetaDock, mDocument);
	mMetaDock->setWidget(mMetaEdit);

	// Slide show controller (not really a widget)
	mSlideShow=new SlideShow(mDocument);

	// Default position on desktop
	setGeometry(20,20,720,520);

	// Default dock config
	// (The "magic numbers" were found by adjusting the layout from within the
	// app and looking at the result in the configuration file)
	mFolderDock->manualDock(mFileDock, KDockWidget::DockLeft, 4000);
	mImageDock->manualDock(mFolderDock, KDockWidget::DockBottom, 3734);
	mMetaDock->manualDock(mImageDock, KDockWidget::DockBottom, 8560);

	// Load dock config if up to date
	if (config->hasGroup(CONFIG_DOCK_GROUP)) {
		config->setGroup(CONFIG_DOCK_GROUP);
		if (config->readNumEntry(CONFIG_GWENVIEW_DOCK_VERSION, 1)==GWENVIEW_DOCK_VERSION) {
			mDockArea->readDockConfig(config,CONFIG_DOCK_GROUP);
		} else {
			KMessageBox::sorry(this, i18n(
				"<qt><b>Configuration update</b><br>"
				"Due to some changes in the dock behavior, your old dock configuration has been discarded. "
				"Please adjust your docks again.</qt>")
				);
			// Store the default dock config and create the
			// GWENVIEW_DOCK_VERSION entry
			mDockArea->writeDockConfig(config,CONFIG_DOCK_GROUP);
			config->writeEntry(CONFIG_GWENVIEW_DOCK_VERSION, GWENVIEW_DOCK_VERSION);
			config->sync();
		}
	} else {
		// There was no dock config, lets create the GWENVIEW_DOCK_VERSION entry
		config->setGroup(CONFIG_DOCK_GROUP);
		config->writeEntry(CONFIG_GWENVIEW_DOCK_VERSION, GWENVIEW_DOCK_VERSION);
		config->sync();
	}
	
	// Load config
	Cache::instance()->readConfig(config,CONFIG_CACHE_GROUP);
}


/**
 * This method creates all the actions Interactions between them and with
 * widgets are created in createObjectInteractions
 */
void MainWindow::createActions() {
	// Stack
	mSwitchToBrowseMode=new KRadioAction(i18n("Browse"), "folder_image", CTRL + Key_Return, TQT_TQOBJECT(this), TQT_SLOT(slotToggleCentralStack()), actionCollection(), "switch_to_browse_mode");
	mSwitchToBrowseMode->setExclusiveGroup("centralStackMode");
	mSwitchToBrowseMode->setChecked(true);
	mSwitchToViewMode=new KRadioAction(i18n("View Image"), "image", 0, TQT_TQOBJECT(this), TQT_SLOT(slotToggleCentralStack()), actionCollection(), "switch_to_view_mode");
	mSwitchToViewMode->setExclusiveGroup("centralStackMode");
	
	// File
	KStdAction::open(TQT_TQOBJECT(this),TQT_SLOT(showFileDialog()),actionCollection() );
	mSaveFile=KStdAction::save(mDocument,TQT_SLOT(save()),actionCollection() );
	mSaveFileAs=KStdAction::saveAs(mDocument,TQT_SLOT(saveAs()),actionCollection() );
	mFilePrint = KStdAction::print(TQT_TQOBJECT(this), TQT_SLOT(printFile()), actionCollection());
	mRenameFile=new KAction(i18n("&Rename..."),Key_F2,TQT_TQOBJECT(this),TQT_SLOT(renameFile()),actionCollection(),"file_rename");
	mCopyFiles=new KAction(i18n("&Copy To..."),Key_F7,TQT_TQOBJECT(this),TQT_SLOT(copyFiles()),actionCollection(),"file_copy");
	mMoveFiles=new KAction(i18n("&Move To..."),Key_F8,TQT_TQOBJECT(this),TQT_SLOT(moveFiles()),actionCollection(),"file_move");
	mLinkFiles=new KAction(i18n("&Link To..."),Key_F9,TQT_TQOBJECT(this),TQT_SLOT(linkFiles()),actionCollection(),"file_link");
	mDeleteFiles=new KAction(i18n("&Delete"),"editdelete",Key_Delete,TQT_TQOBJECT(this),TQT_SLOT(deleteFiles()),actionCollection(),"file_delete");
	mShowFileProperties=new KAction(i18n("Properties"),0,TQT_TQOBJECT(this),TQT_SLOT(showFileProperties()),actionCollection(),"file_properties");
	KStdAction::quit( TQT_TQOBJECT(kapp), TQT_SLOT (closeAllWindows()), actionCollection() );

	// Edit
	mRotateLeft=new KAction(i18n("Rotate &Left"),"rotate_left",CTRL + Key_L, TQT_TQOBJECT(this), TQT_SLOT(rotateLeft()),actionCollection(),"rotate_left");
	mRotateRight=new KAction(i18n("Rotate &Right"),"rotate_right",CTRL + Key_R, TQT_TQOBJECT(this), TQT_SLOT(rotateRight()),actionCollection(),"rotate_right");
	mMirror=new KAction(i18n("&Mirror"),"mirror",0, TQT_TQOBJECT(this), TQT_SLOT(mirror()),actionCollection(),"mirror");
	mFlip=new KAction(i18n("&Flip"),"flip",0, TQT_TQOBJECT(this), TQT_SLOT(flip()),actionCollection(),"flip");

	// View
	mReload=new KAction(i18n("Reload"), "reload", Key_F5, mDocument, TQT_SLOT(reload()), actionCollection(), "reload");
	mReload->setEnabled(false);

	mToggleFullScreen= KStdAction::fullScreen(TQT_TQOBJECT(this),TQT_SLOT(toggleFullScreen()),actionCollection(),0);
	mToggleSlideShow=new KAction(i18n("Slide Show"),"slideshow_play",0,TQT_TQOBJECT(this),TQT_SLOT(toggleSlideShow()),actionCollection(),"slideshow");
	mFullScreenLabelAction=new KToolBarLabelAction("", 0, 0, 0, actionCollection(), "fullscreen_label");
  
	// Go
	mGoUp=new KToolBarPopupAction(i18n("Up"), "up", ALT + Key_Up, TQT_TQOBJECT(this), TQT_SLOT(goUp()), actionCollection(), "go_up");
	new KAction( i18n( "Home" ), "gohome", KStdAccel::shortcut(KStdAccel::Home), TQT_TQOBJECT(this), TQT_SLOT(goHome()), actionCollection(), "go_home");

	// Window
	mResetDockWidgets = new KAction(i18n("Reset"), 0, TQT_TQOBJECT(this), TQT_SLOT(resetDockWidgets()), actionCollection(), "reset_dock_widgets");

	// Settings
	mShowConfigDialog=
		KStdAction::preferences(TQT_TQOBJECT(this), TQT_SLOT(showConfigDialog()), actionCollection() );
	mShowKeyDialog=
		KStdAction::keyBindings(TQT_TQOBJECT(this), TQT_SLOT(showKeyDialog()), actionCollection() );
	(void)new KAction(i18n("Configure External Tools..."), "configure", 0,
		TQT_TQOBJECT(this), TQT_SLOT(showExternalToolDialog()), actionCollection(), "configure_tools");
	(void)KStdAction::configureToolbars(
		TQT_TQOBJECT(this), TQT_SLOT(showToolBarDialog()), actionCollection() );

	actionCollection()->readShortcutSettings();
}


/**
 * This method creates the interactions between objects, when it's called, all
 * widgets and actions have already been created
 */
void MainWindow::createObjectInteractions() {
	// Actions in image view
	{
		KActionPtrList actions;
		actions
			<< mToggleFullScreen
			<< mToggleSlideShow
			<< mFileViewController->selectPrevious()
			<< mFileViewController->selectNext()
			<< mRotateLeft
			<< mRotateRight
			<< mFullScreenLabelAction
			;
		mImageViewController->setFullScreenCommonActions(actions);
	}
	
	{
		KActionPtrList actions;
		actions
			<< mFileViewController->selectPrevious()
			<< mFileViewController->selectNext()
			<< mReload
			;
		mImageViewController->setNormalCommonActions(actions);
	}

	{
		KActionPtrList actions;
		actions
			<< actionCollection()->action("view_zoom_in")
			<< actionCollection()->action("view_zoom_to")
			<< actionCollection()->action("view_zoom_out")
			<< mRotateLeft
			<< mRotateRight
			;
		mImageViewController->setImageViewActions(actions);
	}

	// Make sure file actions are correctly updated
	connect(mFileViewController, TQT_SIGNAL(selectionChanged()),
		TQT_TQOBJECT(this), TQT_SLOT(updateImageActions()) );

	connect(mFileViewController, TQT_SIGNAL(requestContextMenu(const TQPoint&, bool)),
		TQT_TQOBJECT(this), TQT_SLOT(openFileViewControllerContextMenu(const TQPoint&, bool)) );

	// Bookmarks
	TQString file = locate( "data", "kfile/bookmarks.xml" );
	if (file.isEmpty()) {
		file = locateLocal( "data", "kfile/bookmarks.xml" );
	}

	KBookmarkManager* manager=KBookmarkManager::managerForFile(file,false);
	manager->setUpdate(true);
	manager->setShowNSBookmarks(false);
	mBookmarkViewController->init(manager);

	BookmarkOwner* bookmarkOwner=new BookmarkOwner(this);

	KActionMenu* bookmark=new KActionMenu(i18n( "&Bookmarks" ), "bookmark", actionCollection(), "bookmarks" );
	new KBookmarkMenu(manager, bookmarkOwner, bookmark->popupMenu(), 0, true);

	connect(bookmarkOwner,TQT_SIGNAL(openURL(const KURL&)),
		mFileViewController,TQT_SLOT(setDirURL(const KURL&)) );

	connect(mFileViewController,TQT_SIGNAL(directoryChanged(const KURL&)),
		bookmarkOwner,TQT_SLOT(setURL(const KURL&)) );
}


void MainWindow::createHideShowAction(KDockWidget* dock) {
	TQString caption;
	if (dock->mayBeHide()) {
		caption=i18n("Hide %1").arg(dock->caption());
	} else {
		caption=i18n("Show %1").arg(dock->caption());
	}

	KAction* action=new KAction(caption, 0, TQT_TQOBJECT(dock), TQT_SLOT(changeHideShowState()), (TQObject*)0 );
	if (dock->icon()) {
		action->setIconSet( TQIconSet(*dock->icon()) );
	}
	mWindowListActions.append(action);
}


void MainWindow::updateWindowActions() {
	unplugActionList("winlist");
	mWindowListActions.clear();
	createHideShowAction(mFolderDock);
	createHideShowAction(mImageDock);
	createHideShowAction(mMetaDock);
	plugActionList("winlist", mWindowListActions);
}


void MainWindow::createConnections() {
	connect(mGoUp->popupMenu(), TQT_SIGNAL(aboutToShow()),
		this,TQT_SLOT(fillGoUpMenu()));
	
	connect(mGoUp->popupMenu(), TQT_SIGNAL(activated(int)),
		this,TQT_SLOT(goUpTo(int)));
	
	// Slideshow connections
	connect( mSlideShow, TQT_SIGNAL(nextURL(const KURL&)),
		TQT_SLOT( openURL(const KURL&)) );
	connect( mSlideShow, TQT_SIGNAL( stateChanged(bool)),
		TQT_SLOT( slotSlideShowChanged(bool)) );

	// Dir view connections
	connect(mDirViewController, TQT_SIGNAL(urlChanged(const KURL&)),
		mFileViewController, TQT_SLOT(setDirURL(const KURL&)) );
	connect(mDirViewController, TQT_SIGNAL(urlRenamed(const KURL&, const KURL&)),
		TQT_TQOBJECT(this), TQT_SLOT(slotDirRenamed(const KURL&, const KURL&)) );

	// Bookmark view connections
	connect(mBookmarkViewController, TQT_SIGNAL(openURL(const KURL&)),
		mFileViewController,TQT_SLOT(setDirURL(const KURL&)) );
	connect(mFileViewController, TQT_SIGNAL(directoryChanged(const KURL&)),
		mBookmarkViewController, TQT_SLOT(setURL(const KURL&)) );

	// Pixmap view connections
	connect(mImageViewController, TQT_SIGNAL(selectPrevious()),
		mFileViewController, TQT_SLOT(slotSelectPrevious()) );
	connect(mImageViewController, TQT_SIGNAL(selectNext()),
		mFileViewController, TQT_SLOT(slotSelectNext()) );
	connect(mImageViewController, TQT_SIGNAL(doubleClicked()),
		mToggleFullScreen, TQT_SLOT(activate()) );

	// File view connections
	connect(mFileViewController,TQT_SIGNAL(urlChanged(const KURL&)),
		mDocument,TQT_SLOT(setURL(const KURL&)) );
	connect(mFileViewController,TQT_SIGNAL(directoryChanged(const KURL&)),
		this,TQT_SLOT(slotDirURLChanged(const KURL&)) );
	connect(mFileViewController,TQT_SIGNAL(directoryChanged(const KURL&)),
		mDirViewController,TQT_SLOT(setURL(const KURL&)) );
	connect(mFileViewController,TQT_SIGNAL(directoryChanged(const KURL&)),
		mHistory,TQT_SLOT(addURLToHistory(const KURL&)) );

	connect(mFileViewController,TQT_SIGNAL(completed()),
		this,TQT_SLOT(updateStatusInfo()) );
	connect(mFileViewController,TQT_SIGNAL(canceled()),
		this,TQT_SLOT(updateStatusInfo()) );
	connect(mFileViewController,TQT_SIGNAL(imageDoubleClicked()),
		mToggleFullScreen,TQT_SLOT(activate()) );
	connect(mFileViewController,TQT_SIGNAL(shownFileItemRefreshed(const KFileItem*)),
		this,TQT_SLOT(slotShownFileItemRefreshed(const KFileItem*)) );
	connect(mFileViewController,TQT_SIGNAL(sortingChanged()),
		TQT_TQOBJECT(this), TQT_SLOT(updateStatusInfo()) );

	// History connections
	connect(mHistory, TQT_SIGNAL(urlChanged(const KURL&)),
		mFileViewController, TQT_SLOT(setDirURL(const KURL&)) );
	
	// Document connections
	connect(mDocument,TQT_SIGNAL(loading()),
		this,TQT_SLOT(slotImageLoading()) );
	connect(mDocument,TQT_SIGNAL(loaded(const KURL&)),
		this,TQT_SLOT(slotImageLoaded()) );
	connect(mDocument,TQT_SIGNAL(saved(const KURL&)),
		mFileViewController,TQT_SLOT(updateThumbnail(const KURL&)) );
	connect(mDocument,TQT_SIGNAL(reloaded(const KURL&)),
		mFileViewController,TQT_SLOT(updateThumbnail(const KURL&)) );

	// Location bar
	connect(mURLEdit, TQT_SIGNAL(activated(const TQString &)),
		this,TQT_SLOT(slotGo()) );
	connect(mURLEdit, TQT_SIGNAL(returnPressed()),
		this,TQT_SLOT(slotGo()) );

	// Non configurable stop-fullscreen accel
	TQAccel* accel=new TQAccel(this);
	accel->connectItem(accel->insertItem(Key_Escape),TQT_TQOBJECT(this),TQT_SLOT(escapePressed()));

	// Dock related
	connect(mDockArea->manager(), TQT_SIGNAL(change()),
		TQT_TQOBJECT(this), TQT_SLOT(updateWindowActions()) );

	// Plugin menu
	TQPopupMenu *popup = static_cast<TQPopupMenu*>(
		factory()->container( "plugins", this));
    connect(popup, TQT_SIGNAL(aboutToShow()), TQT_TQOBJECT(this), TQT_SLOT(loadPlugins()) );
}


void MainWindow::createLocationToolBar() {
	// URL Combo
	mURLEdit=new KHistoryCombo();
	mURLEdit->setDuplicatesEnabled(false);
	mURLEdit->setPixmapProvider(new KURLPixmapProvider);
	mURLEdit->setMaxCount(HISTORY_MAX_COUNT);
	mURLEdit->setHistoryItems(MiscConfig::history());

	// Do not let the combobox get wider than available space, as this would
	// hide the toolbuttons after it
	mURLEdit->setSizePolicy(TQSizePolicy::Expanding, TQSizePolicy::Fixed);
	
	// Avoid stealing focus
	mURLEdit->setFocusPolicy(TQ_ClickFocus);

	mURLEditCompletion=new KURLCompletion();

	mURLEdit->setCompletionObject(mURLEditCompletion);
	mURLEdit->setAutoDeleteCompletionObject(true);

	KWidgetAction* comboAction=new KWidgetAction( mURLEdit, i18n("Location Bar"), 0,
		0, 0, actionCollection(), "location_url");
	comboAction->setShortcutConfigurable(false);
	comboAction->setAutoSized(true);

	// Clear button
	(void)new KAction( i18n("Clear Location Bar"),
		TQApplication::reverseLayout()?"clear_left" : "locationbar_erase",
		0, TQT_TQOBJECT(this), TQT_SLOT(clearLocationLabel()), actionCollection(), "clear_location");

	// URL Label
	KToolBarLabelAction* locationAction = new KToolBarLabelAction(i18n("L&ocation:"), 
		Key_F6, TQT_TQOBJECT(this), TQT_SLOT( activateLocationLabel()), actionCollection(), "location_label");
	locationAction->setBuddy(mURLEdit);

	// Go button
	(void)new KAction(i18n("Go"), "key_enter", 0, TQT_TQOBJECT(this), TQT_SLOT(slotGo()), actionCollection(), "location_go");

}


void MainWindow::clearLocationLabel() {
	mURLEdit->clearEdit();
	mURLEdit->setFocus();
}


void MainWindow::activateLocationLabel() {
	mURLEdit->setFocus();
	mURLEdit->lineEdit()->selectAll();
}


#ifdef GV_HAVE_KIPI
void MainWindow::loadPlugins() {
	// Already done
	if (mPluginLoader) return;

	LOG("Load plugins");
	// Sets up the plugin interface, and load the plugins
	KIPIInterface* interface = new KIPIInterface(this, mFileViewController);
	mPluginLoader = new KIPI::PluginLoader(TQStringList(), interface );
	connect( mPluginLoader, TQT_SIGNAL( replug() ), TQT_TQOBJECT(this), TQT_SLOT( slotReplug() ) );
	mPluginLoader->loadPlugins();
}


// Helper class for slotReplug(), gcc does not want to instantiate templates
// with local classes, so this is declared outside of slotReplug()
struct MenuInfo {
	TQString mName;
	TQPtrList<KAction> mActions;
	MenuInfo() {}
	MenuInfo(const TQString& name) : mName(name) {}
};

void MainWindow::slotReplug() {
	typedef TQMap<KIPI::Category, MenuInfo> CategoryMap;
	CategoryMap categoryMap;
	categoryMap[KIPI::IMAGESPLUGIN]=MenuInfo("image_actions");
	categoryMap[KIPI::EFFECTSPLUGIN]=MenuInfo("effect_actions");
	categoryMap[KIPI::TOOLSPLUGIN]=MenuInfo("tool_actions");
	categoryMap[KIPI::IMPORTPLUGIN]=MenuInfo("import_actions");
	categoryMap[KIPI::EXPORTPLUGIN]=MenuInfo("export_actions");
	categoryMap[KIPI::BATCHPLUGIN]=MenuInfo("batch_actions");
	categoryMap[KIPI::COLLECTIONSPLUGIN]=MenuInfo("collection_actions");
	
	// Fill the mActions
	KIPI::PluginLoader::PluginList pluginList=mPluginLoader->pluginList();
	KIPI::PluginLoader::PluginList::ConstIterator it(pluginList.begin());
	KIPI::PluginLoader::PluginList::ConstIterator itEnd(pluginList.end());
	for( ; it!=itEnd; ++it ) {
		if (!(*it)->shouldLoad()) continue;
		KIPI::Plugin* plugin = (*it)->plugin();
		Q_ASSERT(plugin);
		if (!plugin) continue;

		plugin->setup(this);
		KActionPtrList actions = plugin->actions();
		KActionPtrList::ConstIterator actionIt=actions.begin(), end=actions.end();
		for (; actionIt!=end; ++actionIt) {
			KIPI::Category category = plugin->category(*actionIt);

			if (!categoryMap.contains(category)) {
				kdWarning() << "Unknown category '" << category << "'\n";
				continue;
			}

			categoryMap[category].mActions.append(*actionIt);
		}
		plugin->actionCollection()->readShortcutSettings();
	}

	// Create a dummy "no plugin" action list
	KAction* noPlugin=new KAction(i18n("No Plugin"), 0, 0, 0, actionCollection(), "no_plugin");
	noPlugin->setShortcutConfigurable(false);
	noPlugin->setEnabled(false);
	TQPtrList<KAction> noPluginList;
	noPluginList.append(noPlugin);
	
	// Fill the menu
	CategoryMap::ConstIterator catIt=categoryMap.begin(), catItEnd=categoryMap.end();
	for (; catIt!=catItEnd; ++catIt) {
		const MenuInfo& info=catIt.data();
		unplugActionList(info.mName);
		if (info.mActions.count()>0) {
			plugActionList(info.mName, info.mActions);
		} else {
			plugActionList(info.mName, noPluginList);
		}
	}
}
#else
void MainWindow::loadPlugins() {
	// Create a dummy "no KIPI" action list
	KAction* noPlugin=new KAction(i18n("No KIPI support"), 0, 0, 0, actionCollection(), "no_plugin");
	noPlugin->setShortcutConfigurable(false);
	noPlugin->setEnabled(false);
	TQPtrList<KAction> noPluginList;
	noPluginList.append(noPlugin);

	TQStringList lst;
	lst	<< "image_actions"
		<< "effect_actions"
		<< "tool_actions"
		<< "import_actions"
		<< "export_actions"
		<< "batch_actions"
		<< "collection_actions";
	
	// Fill the menu
	TQStringList::ConstIterator catIt=lst.begin(), catItEnd=lst.end();
	for (; catIt!=catItEnd; ++catIt) {
		plugActionList(*catIt, noPluginList);
	}
}

void MainWindow::slotReplug() {
}
#endif


} // namespace