/*
 * kless.cpp. Part of the KDE project.
 *
 * Copyright (C) 1998 Matthias Ettrich
 *
 */
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

#include <kfiledialog.h>
#include "kless.h"
#include <qfile.h>
#include <qmsgbox.h>
#include <qkeycode.h>
#include <kiconloader.h>


#define USE_KACCEL 1
#ifdef USE_KACCEL
#include <kaccel.h>
#else
#include <kstdaccel.h>
#endif
#define UNIQUE	1

static KUniqueApplication *kuapp;

KLess::KLess(){

  // create the main widget of kless: a QMultiLineEdit
  edit = new QMultiLineEdit(this);

  // tell the KTMainWindow that this is indeed the main widget
  setView(edit);

  // create a DropZone over the entire window and connect it
  // to the slotDropEvent
  connect( new KDNDDropZone( this , DndURL),
	   SIGNAL( dropAction( KDNDDropZone *) ),
	   SLOT( slotDropEvent( KDNDDropZone *) ) );


  //---------------------------------------------------
  // build a menubar

  // a menubar consists of popup menus. So we need a
  // popup menu first
  QPopupMenu* p = new QPopupMenu;

#ifndef USE_KACCEL
  
  // the easy KDE-1.0 way. Simply use Qt's menus for acceleration.
  // KStdAccel gives you access to the user's current settings. You
  // could as well write "CTRL+Key_N" instead of a.openNew(), but that
  // would not be configurable, of course.
  
  KStdAccel a;
  p->insertItem(i18n("&New Window"), this, SLOT(slotNewWindow()), a.openNew());
  p->insertItem(i18n("&Load"), this, SLOT(slotLoadFile()), a.open() );
  p->insertSeparator();
  p->insertItem(i18n("&Quit"), kapp, SLOT(quit()), a.quit());

#else

  // the new way in KDE-1.1. KAccel is a very flexible class to handle
  // keyboard accelerations. These are completely configurable by the
  // user. Please see the kaccel documentation for further
  // details. The major advantage: With a single line of code calling
  // KKeyDialog::configureKeys(KAccel*) you can popup a keybinding
  // editor for your application.
  //
  // In kless we use KAccel only for some global defined standard
  // bindings.
  
  // create a kaccel object and bind the standard actions to our slots
  KAccel *a = new KAccel( this );
  a->connectItem(KAccel::New, this, SLOT( slotNewWindow() ) );
  a->connectItem(KAccel::Open, this, SLOT( slotLoadFile() ) );
  a->connectItem(KAccel::Quit, kapp, SLOT( quit() ) );
  
  // create the file menu. Tell kaccel to show the accelerators in the
  // menu as well. The advantage over doing that directly in Qt is,
  // that kaccels accelerators are internationalized.
  int id = p->insertItem(i18n("&New Window"),this, SLOT(slotNewWindow()));
  a->changeMenuAccel(p, id, KAccel::New );
  id = p->insertItem(i18n("&Open"),this, SLOT(slotLoadFile()));
  a->changeMenuAccel(p, id, KAccel::Open );
  p->insertSeparator();
  id = p->insertItem(i18n("&Quit"),kapp, SLOT(quit()));
  a->changeMenuAccel(p, id, KAccel::Quit );

#endif

  // put the popupmenu as File-menu into the menu bar
  menuBar()->insertItem(i18n("&File"), p);
  menuBar()->insertSeparator();

  // we let KDE generate a nifty help menu
  p = kapp->getHelpMenu(true,
			i18n("kless --- the KDE text viewer :-) \n\n"
			     "(c) 1998 Matthias Ettrich\n"
			     "Demo Application for the K Desktop Environment."));
  menuBar()->insertItem(i18n("&Help"), p);

  //---------------------------------------------------
  // build a small toolbar

  // insert some buttons, the icons are from the standard KDE toolbar.
  toolBar()->insertButton(Icon("exit.xpm"),TOOLBAR_EXIT, true,i18n("Exit"));
  toolBar()->insertButton(Icon("fileopen.xpm"),TOOLBAR_OPEN, true,i18n("Open File"));
  // Hint: toolBar() returns toolBar(0). If you want another toolbar, simply
  //       use toolBar(1), toolBar(2) and so on.

  // we connect the entire toolbar to one single slot. We could also
  // connect the single toolbar buttons to special slots in the
  // insertButton call above, for example:
  //   insertButton(Icon("exit.xpm"),TOOLBAR_EXIT,
  //                SIGNAL(clicked()), kapp, SLOT(quit()),
  //                true,"Exit")
  // This would be even better for this simple toolbar. We have chosen
  // the other design --- which is more flexible for bigger toolbars ---
  // for demonstration purposes in kless.
  connect(toolBar(), SIGNAL(clicked(int)), SLOT(slotToolbarClicked(int)));
#ifdef UNIQUE
  connect(kuapp, SIGNAL(uniqueCalled(char *)), this, SLOT(slotUnique(char *)));
#endif

}


void KLess::slotUnique(char *message){
	QString s;
	s.sprintf("unique message = '%s'", message);
  	edit->setText(s);
	
}
void KLess::slotToolbarClicked(int item){
  switch (item) {
  case TOOLBAR_OPEN:
    slotLoadFile();
    break;
  case TOOLBAR_EXIT:
    kapp->quit();
    break;
  }
}


void KLess::loadFile(const char* filename){
  // load a file from a filename
  QFile f(filename);
  QString s;
  if ( f.open(IO_ReadOnly) ) {
    QTextStream t( &f );
    while ( !t.eof() ) {
      s += t.readLine() + "\n";
    }
    f.close();
  }
  // put the loaded text into the multiline edit
  edit->setText(s);
}

void KLess::slotDropEvent( KDNDDropZone *zone){
  // the user dropped something on our window.
  // So we simply use KFM to download the stuff wherever it is.
  QString u = zone->getURLList().first(),s;
  if (KFM::download(u, s)){
    setCaption(u);
    loadFile(s);
    KFM::removeTempFile(s);
  }
}

void KLess::slotNewWindow(){
  // this slot is invoked from File->New_Winodw
  (new KLess)->show();
}

void KLess::slotLoadFile(){
  // this slot is invoked from File->Open
  QString s = KFileDialog::getOpenFileName();
  if (!s.isEmpty()){
    setCaption(s);
    loadFile(s);
  }
}


bool KLess::queryExit(){
  // this slot is invoked when the last window is going to be destroyed
  return QMessageBox::critical(this, i18n("Really?"),
			       i18n("Do you really want to close the last window?"),
			       QMessageBox::Ok,
			       QMessageBox::Cancel) == QMessageBox::Ok;
}


// Session management: save data
void KLess::saveProperties(KConfig* config){
  config->writeEntry("text", edit->text());
};

// Session management: read data again
void KLess::readProperties(KConfig* config){
  edit->setText(config->readEntry("text"));
};

int main(int argc, char* argv[]) {

#ifdef UNIQUE
  char **cpp;
  char *message = "";
  for (cpp = argv; *cpp; cpp++) {
	if (strcmp(*cpp, "-U") == 0) {
			message = cpp[1];
	}
  }
  KUniqueApplication a(message, argc,argv);
  kuapp = &a;
  
#else
  KApplication a(argc,argv);
#endif
  if (a.isRestored())
    RESTORE(KLess)
  else {
    // no session management: just create one window
    KLess* kless = new KLess;
    if (argc > 1)
      kless->loadFile(argv[1]);
    kless->show();
  }
  a.exec();
}





