[prev in list] [next in list] [prev in thread] [next in thread] 

List:       kde-devel
Subject:    [Fwd: please forward this mail to kde-devel]
From:       Stephan Kulow <coolo () itm ! mu-luebeck ! de>
Date:       1999-04-29 9:42:00
[Download RAW message or body]

-- 
As long as Linux remains a religion of freeware fanatics,
Microsoft have nothing to worry about.  
                       By Michael Surkan, PC Week Online
[Attachment #3 (message/rfc822)]



Hello, Stephan Kulow.

My name is Woohyun JANG. I wrote a mail to Martin Konold to gain write 
privilege of kde-devel@kde.org. but there isn't any response for two days.
I just wonder if I can write a mail to kde-devel@kde.org. I wrote one mail
to kde@kde.org. I don't know that it was transfered. I think,  not!

Would you forward the following mail and attached files to kde-devel@kde.org ?
If the same mail were transmitted, please ignore this message..  :)

Regards,

            from Woohyun JANG

---8K---
Seeing Korean character

I know that there are a lot of effort for i18n in KDE and QT 2.x
but I can't see Korean characters in KDE application without modifying
source codes.

It is problem that QString can't convert CJK(Chinese, Japanese, Korean)
encoding into unicode correctly.  It just works fine for Latin-1 encoding.
For CJK encoding, QT 2.x provides QTextCodec class.  To see Korean
character codes must be look like below.

 1 main(...)
 2 {
 3    QApplication a(...);
 4    QTextCodec *codec = QTextCodec::codecForLocale();
 5    a.setDefaultCodec( codec );
 6
 7    ...
 8
 9    QString tt = codec->toUnicode("CJK characters");
10
11    ...
12 }

It is good,I think,that 4 and 5 lines are included in either
KApplication::init() or QApplication::QApplication(...).
and QString::QString(...) is modified also to convert CJK characters
into unicode correctly.

I think it is good that QApplication::QApplication(...) contains
setDefaultCodec() to setup a default codec. and QString::QString(...)
uses codec->toUnicode() function. but a man working for troll said
that it isn't good method. he said that people are using QString to
deal with multimedia data like images. so inserting codec related functions
to QString isn't good idea.

For testing purpose, I modified the kdelibs/kdecore/kapp.cpp and
kdelibs/kdecore/klocale.cpp to use codec related functions. (I
inserted setDefaultCodec() in KApplication::init() and modified
KLocale::translate() to use codec->toUnicode(). I attached modified
klocale.cpp and kapp.cpp ) and I used a kedit's translated message 
file(kedit.mo). then I got a screen that Korean characters are appeared in 
menu well.  but I can't see Korean characters in file selection dialog 
because it doesn't use i18n().  If I change QString, It may work fine.

here's kedit screenshot that is displaying Korean characters.
<http://www.mizi.co.kr/~louis/temp/kedit.jpg>

How about you guys?

and I wonder if there is a team for CJK support or i18n.

Regards.

p.s. Sorry for my poor English :)
---8K---

-- 
Woohyun JANG, louis@mizi.co.kr                           MIZI Research, Inc.

["kapp.cpp" (text/plain)]

/* This file is part of the KDE libraries
    Copyright (C) 1997 Matthias Kalle Dalheimer (kalle@kde.org)

    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Library General Public
    License as published by the Free Software Foundation; either
    version 2 of the License, or (at your option) any later version.

    This library 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
    Library General Public License for more details.

    You should have received a copy of the GNU Library General Public License
    along with this library; see the file COPYING.LIB.  If not, write to
    the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
    Boston, MA 02111-1307, USA.
	*/

// $Id: kapp.cpp,v 1.134 1999/04/19 15:49:29 kulow Exp $

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

#include <qdir.h> // must be at the front
#include <qobjcoll.h>
#include <qstrlist.h>
#include <qfile.h>
#include <qmessagebox.h>
#include <qtextstream.h>
#include <qregexp.h>
#include <qkeycode.h>
#include <qwidcoll.h>
#include <qpopupmenu.h>
#include <drag.h>

#include <qtextcodec.h>

#include <kapp.h>
#include <kcharsets.h>
#include <kdebug.h>
#include <kdebugdialog.h>
#include <klocale.h>
#include <kiconloader.h>
#include "kwm.h"

#include <sys/types.h>
#ifdef HAVE_SYS_STAT_H
#include <sys/stat.h>
#endif
#include <sys/wait.h>

#include <fcntl.h>
#include <stdlib.h> // getenv()
#include <signal.h>
#include <unistd.h>

#include <X11/Xlib.h>
#include <X11/Xatom.h>

#include "kprocctrl.h"

#ifdef HAVE_PATHS_H
#include <paths.h>
#endif

#ifndef _PATH_TMP
#define _PATH_TMP "/tmp/"
#endif

// defined by X11 headers
#ifdef KeyPress
#undef KeyPress
#endif

#include "qplatinumstyle.h"
#include <kconfig.h>

KCharsets* KApplication::pCharsets = 0L;

KApplication* KApplication::KApp = 0L;
QStrList* KApplication::pSearchPaths;
//extern bool bAreaCalculated;

static int kde_xio_errhandler( Display * )
{
  return kapp->xioErrhandler();
}

KApplication::KApplication( int& argc, char** argv ) :
  QApplication( argc, argv )
{
  QString aArgv0 = argv[0];
  int nSlashPos = aArgv0.findRev( '/' );
  if( nSlashPos != -1 )
	aAppName = aArgv0.remove( 0, nSlashPos+1 );
  else
	aAppName = aArgv0;

  init();

  parseCommandLine( argc, argv );

}


KApplication::KApplication( int& argc, char** argv, const QString& rAppName ) :
  QApplication( argc, argv )
{
  aAppName = rAppName;

  init();

  parseCommandLine( argc, argv );

}

int KApplication::xioErrhandler()
{
  emit shutDown();
  exit( 1 );
  return 0;
}

void KApplication::init()
{
  QApplication::useXResourceManager( FALSE );
  // this is important since we fork() to launch the help (Matthias)
  fcntl(ConnectionNumber(qt_xdisplay()), F_SETFD, 1);
  // set up the fance KDE xio error handler (Matthias)
  XSetIOErrorHandler( kde_xio_errhandler );

  rootDropZone = 0L;

  // CC: install KProcess' signal handler
  // by creating the KProcController instance (if its not already existing)
  // This is handled be KProcess (stefh)
  /*
  if ( theKProcessController == 0L)
    theKProcessController = new KProcessController();
  */
  KApp = this;
  bLocaleConstructed = false; // no work around mutual dependencies

  pIconLoader = 0L;

  // create the config directory ~/.kde/share/config
  QString configPath = KApplication::localkdedir();
  // We should check if  mkdir() succeeds, but since we cannot do much anyway...
  // But we'll check at least for access permissions (for SUID case)
  if ( checkAccess(configPath, W_OK) ) {
    if ( mkdir (configPath.data(), 0755) == 0) {  // make it public(?)
      chown(configPath.data(), getuid(), getgid());
      configPath += "/share";
      if ( checkAccess(configPath, W_OK) ) {
        if ( mkdir (configPath.data(), 0755) == 0 ) { // make it public
          chown(configPath.data(), getuid(), getgid());
          configPath += "/config";
          if ( checkAccess(configPath, W_OK) ) {
            if ( mkdir (configPath.data(), 0700) == 0 ) // make it private
              chown(configPath.data(), getuid(), getgid());
          }
        }
      }
    }
  }

  // try to read a global application file
  QString aGlobalAppConfigName = kde_configdir() + "/" + aAppName + "rc";
  QFile aGlobalAppConfigFile( aGlobalAppConfigName );
  // try to open read-only
  bool bSuccess = aGlobalAppConfigFile.open( IO_ReadOnly );
  if( !bSuccess )
	// there is no global app config file
	aGlobalAppConfigName = "";
  aGlobalAppConfigFile.close();


  // now for the local app config file
  QString aConfigName = KApplication::localkdedir();
  aConfigName += "/share/config/";
  aConfigName += aAppName;
  aConfigName += "rc";

  QFile aConfigFile( aConfigName );

  // We may write to the file
  if ( ! checkAccess(aConfigName.data(), W_OK ) )
    bSuccess = false;
  else {
  // Open the application-specific config file. It will be created if
  // it does not exist yet.
    bSuccess = aConfigFile.open( IO_ReadWrite );
    // Set uid/gid (neccesary for SUID programs)
    if ( bSuccess )
      chown(aConfigFile.name(), getuid(), getgid());
  }
  if( !bSuccess )
	{
	  // try to open at least read-only
	  bSuccess = aConfigFile.open( IO_ReadOnly );
	  if( !bSuccess )
		{
		  // we didn't succeed to open an app-config file
		  pConfig = new KConfig( aGlobalAppConfigName );
		  eConfigState = APPCONFIG_NONE;
		}
	  else
		{
		  // we succeeded to open an app-config file read-only
		  pConfig = new KConfig( aGlobalAppConfigName, aConfigName );
		  eConfigState = APPCONFIG_READONLY;
		}
	}
  else
	{
	  // we succeeded to open an app-config file read-write
	  pConfig = new KConfig( aGlobalAppConfigName, aConfigName );
	  eConfigState = APPCONFIG_READWRITE;
	}

  pCharsets = new KCharsets();

  pLocale = new KLocale(aAppName);
  bLocaleConstructed = true;

  // Drag 'n drop stuff taken from kfm
  display = desktop()->x11Display();
  DndSelection = XInternAtom( display, "DndSelection", False );
  DndProtocol = XInternAtom( display, "DndProtocol", False );
  DndEnterProtocol = XInternAtom( display, "DndEnterProtocol", False );
  DndLeaveProtocol = XInternAtom( display, "DndLeaveProtocol", False );
  DndRootProtocol = XInternAtom( display, "DndRootProtocol", False );
  lastEnteredDropZone = 0L;
  dropZones.setAutoDelete( FALSE );

  // initialize file search paths
  pSearchPaths = new QStrList();
  buildSearchPaths();

  WM_SAVE_YOURSELF = XInternAtom( display, "WM_SAVE_YOURSELF", False );
  WM_PROTOCOLS = XInternAtom( display, "WM_PROTOCOLS", False );
  KDEChangePalette = XInternAtom( display, "KDEChangePalette", False );
  KDEChangeGeneral = XInternAtom( display, "KDEChangeGeneral", False );
  KDEChangeStyle = XInternAtom( display, "KDEChangeStyle", False);

  readSettings();
  kdisplaySetPalette();
  kdisplaySetStyleAndFont();

  setStyle(new QPlatinumStyle());
  // install an event filter for KDebug
  installEventFilter( this );

  pSessionConfig = 0L;
  bIsRestored = False;
  bSessionManagement = False;
  bSessionManagementUserDefined = False;
  pTopWidget = 0L;

  // register a communication window for desktop changes (Matthias)
  {
    Atom a = XInternAtom(qt_xdisplay(), "KDE_DESKTOP_WINDOW", False);
    QWidget* w = new QWidget(0,0);
    long data = 1;
    XChangeProperty(qt_xdisplay(), w->winId(), a, a, 32,
					PropModeReplace, (unsigned char *)&data, 1);
  }
  aWmCommand = argv()[0];

  // to support CJK encoding
  setDefaultCodec( QTextCodec::codecForLocale() );
}

KConfig* KApplication::getSessionConfig() {
  if (pSessionConfig)
    return pSessionConfig;
  // create a instance specific config object
  QString aConfigName = KApplication::localkdedir();
  aConfigName += "/share/config/";
  aConfigName += aAppName;
  aConfigName += "rc";

  QString aSessionConfigName;
  QString num;
  int i = 0;
  do {
    i++;
    num.setNum(i);
    aSessionConfigName = aConfigName + "." + num;
  } while (QFile::exists(aSessionConfigName));
  QFile aConfigFile(aSessionConfigName);

  bool bSuccess;
  if ( ! checkAccess( aConfigFile.name(), W_OK ) )
    bSuccess = false;
  else {
    bSuccess = aConfigFile.open( IO_ReadWrite );
  }
  if( bSuccess ){
    chown(aConfigFile.name(), getuid(), getgid());
    aConfigFile.close();
    pSessionConfig = new KConfig(QString::null, aSessionConfigName);
    aSessionName = aAppName.copy();
    aSessionName += "rc.";
    aSessionName += num;
  }
  return pSessionConfig;
}

void KApplication::enableSessionManagement(bool userdefined){
  bSessionManagement = True;
  bSessionManagementUserDefined = userdefined;
  if (topWidget()){
    KWM::enableSessionManagement(topWidget()->winId());
  }
}

void KApplication::setWmCommand(const QString& s){
  aWmCommand = s;
  if (topWidget() && !bSessionManagement)
    KWM::setWmCommand( topWidget()->winId(), aWmCommand);
}




KIconLoader* KApplication::getIconLoader()
{
  if( !pIconLoader )
    pIconLoader = new KIconLoader();

  return pIconLoader;
}


QPopupMenu* KApplication::getHelpMenu( bool /*bAboutQtMenu*/,
	   const QString& aboutAppText )
{
  int id = 0;
  QPopupMenu* pMenu = new QPopupMenu();

  id = pMenu->insertItem( i18n( "&Contents" ) );
  pMenu->connectItem( id, this, SLOT( appHelpActivated() ) );
  pMenu->setAccel( Key_F1, id );

  pMenu->insertSeparator();

  id = pMenu->insertItem( QString(i18n( "&About" )) + " " + aAppName + "...");
  if( aboutAppText )
	{
	  pMenu->connectItem( id, this, SLOT( aboutApp() ) );
	  aAppAboutString = aboutAppText;
	}

  id = pMenu->insertItem( i18n( "About &KDE..." ) );
  pMenu->connectItem( id, this, SLOT( aboutKDE() ) );
  /*
	if( bAboutQtMenu )
	{
	id = pMenu->insertItem( i18n( "About Qt" ) );
	pMenu->connectItem( id, this, SLOT( aboutQt() ) );
	}
  */
  return pMenu;
}


void KApplication::appHelpActivated()
{
  invokeHTMLHelp( aAppName + "/" + "index.html", "" );
}


void KApplication::aboutKDE()
{
  QMessageBox::about( 0L, i18n( "About KDE" ),
					  i18n(
"\nThe KDE Desktop Environment was written by the KDE Team,\n"
"a world-wide network of software engineers committed to\n"
"free software development.\n\n"
"Visit http://www.kde.org for more information on the KDE\n"
"Project. Please consider joining and supporting KDE.\n\n"
"Please report bugs at http://bugs.kde.org.\n"
));
}

void KApplication::aboutApp()
{
  QMessageBox::about( 0L, getCaption(), aAppAboutString );
}


void KApplication::aboutQt()
{
  //  QMessageBox::aboutQt( NULL, getCaption() );
}


KLocale* KApplication::getLocale()
{
  if( !pLocale )
    pLocale = new KLocale();

  return pLocale;
}


bool KApplication::eventFilter ( QObject*, QEvent* e )
{
  if ( e->type() == QEvent::KeyPress )
	{
	  QKeyEvent *k = (QKeyEvent*)e;
	  if( ( k->key() == Key_F12 ) &&
		  ( k->state() & ControlButton ) &&
		  ( k->state() & ShiftButton ) )
		{
		  KDebugDialog* pDialog = new KDebugDialog();
		  /* Fill dialog fields with values from config data */
		  KConfig* pConfig = getConfig();
		  QString aOldGroup = pConfig->getGroup();
		  pConfig->setGroup( "KDebug" );
		  pDialog->setInfoOutput( pConfig->readNumEntry( "InfoOutput", 4 ) );
		  pDialog->setInfoFile( pConfig->readEntry( "InfoFilename",
													"kdebug.dbg" ) );
		  pDialog->setInfoShow( pConfig->readEntry( "InfoShow", "" ) );
		  pDialog->setWarnOutput( pConfig->readNumEntry( "WarnOutput", 4 ) );
		  pDialog->setWarnFile( pConfig->readEntry( "WarnFilename",
													"kdebug.dbg" ) );
		  pDialog->setWarnShow( pConfig->readEntry( "WarnShow", "" ) );
		  pDialog->setErrorOutput( pConfig->readNumEntry( "ErrorOutput", 4 ) );
		  pDialog->setErrorFile( pConfig->readEntry( "ErrorFilename",
													 "kdebug.dbg" ) );
		  pDialog->setErrorShow( pConfig->readEntry( "ErrorShow", "" ) );
		  pDialog->setFatalOutput( pConfig->readNumEntry( "FatalOutput", 4 ) );
		  pDialog->setFatalFile( pConfig->readEntry( "FatalFilename",
													 "kdebug.dbg" ) );
		  pDialog->setFatalShow( pConfig->readEntry( "FatalShow", "" ) );
		  pDialog->setAbortFatal( pConfig->readNumEntry( "AbortFatal", 0 ) );
								
		  /* Show dialog */
		  int nRet = pDialog->exec();

		  if( nRet == QDialog::Accepted )
			{
			  /* User pressed OK, retrieve values */
			  pConfig->writeEntry( "InfoOutput", pDialog->infoOutput() );
			  pConfig->writeEntry( "InfoFilename", pDialog->infoFile() );
			  pConfig->writeEntry( "InfoShow", pDialog->infoShow() );
			  pConfig->writeEntry( "WarnOutput", pDialog->warnOutput() );
			  pConfig->writeEntry( "WarnFilename", pDialog->warnFile() );
			  pConfig->writeEntry( "WarnShow", pDialog->warnShow() );
			  pConfig->writeEntry( "ErrorOutput", pDialog->errorOutput() );
			  pConfig->writeEntry( "ErrorFilename", pDialog->errorFile() );
			  pConfig->writeEntry( "ErrorShow", pDialog->errorShow() );
			  pConfig->writeEntry( "FatalOutput", pDialog->fatalOutput() );
			  pConfig->writeEntry( "FatalFilename", pDialog->fatalFile() );
			  pConfig->writeEntry( "FatalShow", pDialog->fatalShow() );
			  pConfig->writeEntry( "AbortFatal", pDialog->abortFatal() );

			  //bAreaCalculated = false;
			}
		  else
			{
			  /* User pressed Cancel, do nothing */
			}
		
		  /* restore old group */
		  pConfig->setGroup( aOldGroup );

		  return TRUE; // do not process event further
		}
	}
  return FALSE; // process event further
}


void KApplication::parseCommandLine( int& argc, char** argv )
{
  enum parameter_code { unknown = 0, caption, icon, miniicon, restore };
  const char* parameter_strings[] = { "-caption", "-icon", "-miniicon", "-restore" , \
0 };

  aDummyString2 = " ";
  int i = 1;
  parameter_code parameter;
  while( i < argc ) {
    parameter = unknown;

    for ( int p = 0 ; parameter_strings[p]; p++)
      if ( !strcmp( argv[i], parameter_strings[p]) ) {
        parameter = static_cast<parameter_code>(p + 1);
        break;
      }

    if ( parameter != unknown && argc < i +2 ) { // last argument without parameters
      argc -= 1;
      break; // jump out of the while loop
    }

    switch (parameter) {
    case caption:
      aCaption = argv[i+1];
      aDummyString2 += parameter_strings[caption-1];
      aDummyString2 += " \"";
      aDummyString2 += argv[i+1];
      aDummyString2 += "\" ";
      break;
    case icon:
      if (argv[i+1][0] == '/')
        aIconPixmap = QPixmap(argv[i+1]);
      else
        aIconPixmap = getIconLoader()->loadApplicationIcon( argv[i+1] );
      if (aMiniIconPixmap.isNull()){
		if (argv[i+1][0] == '/')
		  aMiniIconPixmap = aIconPixmap;
		else
		  aMiniIconPixmap = getIconLoader()->loadApplicationMiniIcon( argv[i+1] );
      }
      aDummyString2 += parameter_strings[icon-1];
      aDummyString2 += " ";
      aDummyString2 += argv[i+1];
      aDummyString2 += " ";
      break;
    case miniicon:
      if (argv[i+1][0] == '/')
        aMiniIconPixmap = QPixmap(argv[i+1]);
      else
        aMiniIconPixmap = getIconLoader()->loadApplicationMiniIcon( argv[i+1] );
      aDummyString2 += parameter_strings[miniicon-1];
      aDummyString2 += " ";
      aDummyString2 += argv[i+1];
      aDummyString2 += " ";
      break;
    case restore:
      {
		aSessionName = argv[i+1];
		QString aSessionConfigName;
		if (argv[i+1][0] == '/')
		  aSessionConfigName = argv[i+1];
		else {
		  aSessionConfigName = KApplication::localkdedir();
		  aSessionConfigName += "/share/config/";
		  aSessionConfigName += argv[i+1];
		}
		if (QFile::exists(aSessionConfigName)){
		  QFile aConfigFile(aSessionConfigName);
		  bool bSuccess;
		  if ( ! checkAccess( aConfigFile.name(), W_OK ) )
		    bSuccess = false;
		  else
		    bSuccess = aConfigFile.open( IO_ReadWrite );
		  if( bSuccess ){
                        // Set uid/gid (neccesary for SUID programs)
                        chown(aConfigFile.name(), getuid(), getgid());

			aConfigFile.close();
			pSessionConfig = new KConfig(QString::null, aSessionConfigName);
			
			// do not write back. the application will get
			// a new one if demanded.
			pSessionConfig->rollback();
			
			if (pSessionConfig){
			  bIsRestored = True;
			}
			aConfigFile.remove();
		  }
		}
      }
      break;
    case unknown:
      i++;
    }

    if ( parameter != unknown ) { // remove arguments

      for( int j = i;  j < argc-2; j++ )
        argv[j] = argv[j+2];

      argc -=2 ;
    }

  }

  if (aIconPixmap.isNull()){
    aIconPixmap = getIconLoader()->loadApplicationIcon( aAppName + ".xpm");
  }
  if (aMiniIconPixmap.isNull()){
    aMiniIconPixmap = getIconLoader()->loadApplicationMiniIcon( aAppName + ".xpm");
  }

}

KApplication::~KApplication()
{
  removeEventFilter( this );

  if( pIconLoader )
    delete pIconLoader;

  if( pLocale )
    delete pLocale;

  delete pCharsets;

  delete pSearchPaths;

  delete pConfig;

  // Carefully shut down the process controller: It is very likely
  // that we receive a SIGCHLD while the destructor is running
  // (since we are in the process of shutting down, an opportunity
  // at which child process are being killed). So we first mark
  // the controller deleted (so that the SIGCHLD handler thinks it
  // is already gone) before we actually delete it.
  KProcessController* ctrl = theKProcessController;
  theKProcessController = 0;
  delete ctrl; // Stephan: "there can be only one" ;)

  KApp = 0;
}

bool KApplication::x11EventFilter( XEvent *_event )
{
  // You can get root drop events twice.
  // This is to avoid this.
  static int rootDropEventID = -1;

  if ( _event->type == ClientMessage )
    {
	  XClientMessageEvent *cme = ( XClientMessageEvent * ) _event;
	  // session management
	  if( cme->message_type == WM_PROTOCOLS )
		{
		  if( (Atom)(cme->data.l[0]) == WM_SAVE_YOURSELF )
			{
			    //we want a new session config!
			    if (bIsRestored && pSessionConfig) {
				delete pSessionConfig;
				pSessionConfig = 0;
				bIsRestored = false;
			    }
				
			
			  if (!topWidget() ||
			      cme->window != topWidget()->winId()){
			    KWM::setWmCommand(cme->window, "");
			    return true;
			  }
			
			  emit saveYourself(); // give applications a chance to
			  // save their data
			  if (bSessionManagementUserDefined)
			    KWM::setWmCommand( topWidget()->winId(), aWmCommand);
			  else {
			
			    if (pSessionConfig && !aSessionName.isEmpty()){
			      QString aCommand = aAppName.copy();
			      if (aAppName != argv()[0]){
					if (argv()[0][0]=='/')
					  aCommand = argv()[0];
					else {
					  char* s = new char[1024];
					  aCommand=(getcwd(s, 1024));
					  aCommand+="/";
					  delete [] s;
					  aCommand+=aAppName;
					}
			      }
			      aCommand+=" -restore ";
			      aCommand+=aSessionName;
			      aCommand+=aDummyString2;
			      KWM::setWmCommand( topWidget()->winId(),
									 aCommand);
			      pSessionConfig->sync();
			    } else {
			      QString aCommand = argv()[0];
			      aCommand+=aDummyString2;
			      KWM::setWmCommand( topWidget()->winId(),
									 aCommand);
			    }
			  }
			
			  return true;
			}
		}

	  // stuff for reconfiguring
	  if ( cme->message_type == KDEChangeStyle )
		{
		  QString str;
		
		  getConfig()->setGroup("KDE");
		  str = getConfig()->readEntry("widgetStyle");
		  if(!str.isNull())
		    if(str == "Motif")
		      applyGUIStyle(MotifStyle);
		    else
		      if(str == "Windows 95")
			applyGUIStyle(WindowsStyle);
		  return TRUE;
		}

	  if ( cme->message_type == KDEChangePalette )
		{
		  readSettings();
		  kdisplaySetPalette();
		
		  return True;
		}
	  if ( cme->message_type == KDEChangeGeneral )
		{
		  readSettings();
		  kdisplaySetStyleAndFont();
		  kdisplaySetPalette();
		
		  return True;
		}
	
	  if ( cme->message_type == DndLeaveProtocol )
		{
		  if ( lastEnteredDropZone != 0L )
			lastEnteredDropZone->leave();
	
		  lastEnteredDropZone = 0L;

		  return TRUE;
		}
	  else if ( cme->message_type != DndProtocol && cme->message_type != \
DndEnterProtocol &&  cme->message_type != DndRootProtocol )
	    return FALSE;
	
	  Window root = DefaultRootWindow(display);
	
	  unsigned char *Data;
	  unsigned long Size;
	  Atom    ActualType;
	  int     ActualFormat;
	  unsigned long RemainingBytes;

	  XGetWindowProperty(display,root,DndSelection,
						 0L,1000000L,
						 FALSE,AnyPropertyType,
						 &ActualType,&ActualFormat,
						 &Size,&RemainingBytes,
						 &Data);

	  QPoint p( (int)cme->data.l[3], (int)cme->data.l[4] );

	  if ( cme->message_type == DndRootProtocol )
		{
		  if ( rootDropEventID == (int)cme->data.l[1] )
			return FALSE;
	
		  rootDropEventID = (int)cme->data.l[1];

		  if ( rootDropZone != 0L )
			rootDropZone->drop( (char*)Data, Size, (int)cme->data.l[0], p.x(), p.y() );
		  return TRUE;
		}
	
	  KDNDDropZone *dz;
	  KDNDDropZone *result = 0L;
	
	  /*
		for ( dz = dropZones.first(); dz != 0L; dz = dropZones.next() )
		{
		QPoint p2 = dz->getWidget()->mapFromGlobal( p );
		if ( dz->getWidget()->rect().contains( p2 ) )
		result = dz;
		}
	  */

	  QWidget *w = widgetAt( p.x(), p.y(), TRUE );

	  while ( result == 0L && w != 0L )
		{
	      for ( dz = dropZones.first(); dz != 0L; dz = dropZones.next() )
			{
			  if ( dz->getWidget() == w )
				result = dz;
			}
	
	      if ( result == 0L )
			w = w->parentWidget();
		}

	  // KFM hack. Find not decorated windows ( root icons )
	  if ( result == 0L )
		for ( dz = dropZones.first(); dz != 0L; dz = dropZones.next() )
	      {
			QPoint p2 = dz->getWidget()->mapFromGlobal( p );
			if ( dz->getWidget()->rect().contains( p2 ) )
		      result = dz;
	      }
	
	  if ( result != 0L )
		{
	      if ( cme->message_type == DndProtocol )
			{
			  result->drop( (char*)Data, Size, (int)cme->data.l[0], p.x(), p.y() );
			}
	      else if ( cme->message_type == DndEnterProtocol )
			{
			  // If we entered another drop zone, tell the drop zone we left about it
			  if ( lastEnteredDropZone != 0L && lastEnteredDropZone != result )
				lastEnteredDropZone->leave();
		
			  // Notify the drop zone over which the pointer is right now.
			  result->enter( (char*)Data, Size, (int)cme->data.l[0], p.x(), p.y() );
			  lastEnteredDropZone = result;
			}
		}
	  else
		{
		  // Notify the last DropZone that the pointer has left the drop zone.
		  if ( lastEnteredDropZone != 0L )
			lastEnteredDropZone->leave();
		  lastEnteredDropZone = 0L;
		}

	  return TRUE;
    }

  return FALSE;
}

void KApplication::applyGUIStyle(GUIStyle /* newstyle */) {
/*
  QApplication::setStyle( applicationStyle );

  // get list of toplevels
  QWidgetList *wl = QApplication::topLevelWidgets();
  QWidgetListIt wl_it( *wl );

  // foreach toplevel ...
  while(wl_it.current()) {
    QWidget *w = wl_it.current();

    // set new style
    w->setStyle(newstyle);
    QObjectList *ol = w->queryList("QWidget", 0, 0, TRUE);
    QObjectListIt ol_it( *ol );

    // set style to child widgets
    while ( ol_it.current() ) {
      QWidget *child = (QWidget *)(ol_it.current());
      child->setStyle(newstyle);
      ++ol_it;
    }
    delete ol;
    ++wl_it;
  }

  delete wl;
*/
}


QString KApplication::findFile( const QString& file )
{
  QString fullPath;
  QStrListIterator it( *pSearchPaths );

  while ( it.current() )
    {
	  fullPath = it.current();
	  fullPath += '/';
	  fullPath += file;
	  if ( !access( fullPath, 0 ) )
		return fullPath;
	  ++it;
    }

  return QString::null;
}


const QString KApplication::getCaption() const
{
  if( !aCaption.isNull() )
	return aCaption;
  else
	return aAppName;
}


void KApplication::buildSearchPaths()
{
  // Torben
  // We want to search the local files with highest priority
  QString tmp = KApplication::localkdedir();
  appendSearchPath( tmp );

  // add paths from "[KDE Setup]:Path=" config file entry
  getConfig()->setGroup( "KDE Setup" );
  QString kdePathRc = getConfig()->readEntry( "Path" );

  if ( !kdePathRc.isNull() )
    {
      char *start, *end, *workPath = new char [ kdePathRc.length() + 1 ];
	  strcpy( workPath, kdePathRc );
	  start = workPath;
	  while ( start )
		{
	  	  end = strchr( start, ':' );
		  if ( end )
		    *end = '\0';
		  appendSearchPath( start );
		  start = end ? end + 1 : end;
		}
	  delete [] workPath;
    }

  // add paths in the KDEPATH environment variable
  QString kdePathEnv = getenv( "KDEPATH" );
  if ( !kdePathEnv.isEmpty() )
    {
	  char *start, *end, *workPath = new char [ strlen( kdePathEnv ) + 1 ];
	  strcpy( workPath, kdePathEnv );
	  start = workPath;
	  while ( start )
		{
	  	  end = strchr( start, ':' );
		  if ( end )
		    *end = '\0';
		  appendSearchPath( start );
		  start = end ? end + 1 : end;
		}
	  delete [] workPath;
    }

  appendSearchPath( kdedir().data() );
}

void KApplication::appendSearchPath( const QString& path )
{
  QStrListIterator it( *pSearchPaths );

  // return if this path has already been added
  while ( it.current() )
    {
	  if ( !strcmp( it.current(), path ) )
		return;
	  ++it;
    }

  pSearchPaths->append( path );
}

void KApplication::readSettings()
{
  // use the global config files
  KConfig* config = getConfig();
  config->reparseConfiguration();

  QString str;
	
  config->setGroup( "WM");
  // this default is Qt lightGray
  inactiveTitleColor_ = config->readColorEntry( "inactiveBackground", &lightGray );

  // this default is Qt darkGrey
  inactiveTextColor_ = config->readColorEntry( "inactiveForeground", &darkGray );

  // this default is Qt darkBlue
  activeTitleColor_ = config->readColorEntry( "activeBackground", &darkBlue );

  // this default is Qt white
  activeTextColor_ = config->readColorEntry( "activeForeground", &white );

  config->setGroup( "KDE");
  contrast_ = config->readNumEntry( "contrast", 7 );

  //  Read the font specification from config.
  //  Initialize fonts to default first or it won't work !!
		
  pCharsets->setDefault(klocale->charset());
  generalFont_ = QFont("helvetica", 12, QFont::Normal);
  pCharsets->setQFont(generalFont_);
  fixedFont_ = QFont("fixed", 12, QFont::Normal);
  pCharsets->setQFont(fixedFont_);

  config->setGroup( "General" );
  generalFont_ = config->readFontEntry( "font", &generalFont_ );
  fixedFont_ = config->readFontEntry( "fixedFont", &fixedFont_ );

  // Finally, read GUI style from config.
	
  config->setGroup( "KDE" );
  if ( config->readEntry( "widgetStyle", "Windows 95" ) == "Windows 95" )
    applicationStyle_=WindowsStyle;
  else
    applicationStyle_=MotifStyle;
	
}



void KApplication::kdisplaySetPalette()
{
    emit kdisplayPaletteChanged();
    emit appearanceChanged();

    /*
  // WARNING : QApplication::setPalette() produces inconsistent results.
  // There are 3 problems :-
  // 1) You can't change select colors
  // 2) You need different palettes to apply the same color scheme to
  //		different widgets !!
  // 3) Motif style needs a different palette to Windows style.
	
  int highlightVal, lowlightVal;
	
  highlightVal=100+(2*contrast+4)*16/10;
  lowlightVal=100+(2*contrast+4)*10;
	
  // printf("contrast = %d\n", contrast);
	
  if ( applicationStyle==MotifStyle ) {
	QColorGroup disabledgrp( textColor, backgroundColor,
							 backgroundColor.light(highlightVal),
							 backgroundColor.dark(lowlightVal),
							 backgroundColor.dark(120),
							 backgroundColor.dark(120), windowColor );

	QColorGroup colgrp( textColor, backgroundColor,
						backgroundColor.light(highlightVal),
						backgroundColor.dark(lowlightVal),
						backgroundColor.dark(120),
						textColor, windowColor );

	QApplication::setPalette( QPalette(colgrp,disabledgrp,colgrp), TRUE );

	emit kdisplayPaletteChanged();
	emit appearanceChanged();

  } else {
	QColorGroup disabledgrp( textColor, backgroundColor,
							 backgroundColor.light(150),
							 backgroundColor.dark(),
							 backgroundColor.dark(120),
							 backgroundColor.dark(120), windowColor );

	QColorGroup colgrp( textColor, backgroundColor,
						backgroundColor.light(150),
						backgroundColor.dark(),
						backgroundColor.dark(120),
						textColor, windowColor );

	QApplication::setWinStyleHighlightColor( selectColor );
	QApplication::setPalette( QPalette(colgrp,disabledgrp,colgrp), TRUE );

	emit kdisplayPaletteChanged();
	emit appearanceChanged();

  }
    */
}

void KApplication::kdisplaySetFont()
{
//     QApplication::setFont( generalFont_, TRUE );
  // setFont() works every time for me !

  emit kdisplayFontChanged();
  emit appearanceChanged();

  resizeAll();
}	


void KApplication::kdisplaySetStyle()
{
  // QApplication::setStyle( applicationStyle );
  applyGUIStyle( applicationStyle_ );

  emit kdisplayStyleChanged();
  emit appearanceChanged();
  resizeAll();
}	


void KApplication::kdisplaySetStyleAndFont()
{
  //  QApplication::setStyle( applicationStyle );
  // 	setStyle() works pretty well but may not change the style of combo
  //	boxes.
    if ( *font() != generalFont_)
	QApplication::setFont( generalFont_, TRUE );
  applyGUIStyle(applicationStyle_);

  emit kdisplayStyleChanged();
  emit kdisplayFontChanged();
  emit appearanceChanged();

  resizeAll();
}	


void KApplication::resizeAll()
{
  // send a resize event to all windows so that they can resize children
  QWidgetList *widgetList = QApplication::topLevelWidgets();
  QWidgetListIt it( *widgetList );

  while ( it.current() )
	{
	  it.current()->resize( it.current()->size() );
	  ++it;
	}
  delete widgetList;
}




void KApplication::invokeHTMLHelp( QString filename, QString topic ) const
{
  if ( fork() == 0 )	
    {		
	  if( filename.isEmpty() )
	    filename = aAppName + "/index.html";

	 QString path = KApplication::kde_htmldir().copy() + "/";

         // first try the locale setting
         QString file = path + klocale->language() + '/' + filename;
         if( !QFileInfo( file ).exists() )
               // not found: use the default
               file = path + "default/" + filename;

	  if( !topic.isEmpty() )
		{
                 file.append( "#" );
                 file.append(topic);
		}
	
	  /* Since this is a library, we must conside the possibilty that
	   * we are being used by a suid root program. These next two
	   * lines drop all privileges.
	   */
	  setuid( getuid() );
	  setgid( getgid() );
	  char* shell = "/bin/sh";
	  if (getenv("SHELL"))
		shell = getenv("SHELL");
         file.prepend("kdehelp ");
         execl(shell, shell, "-c", file.data(), 0L);
	  exit( 1 );
    }
}

QString KApplication::kdedir()
{
  static QString kdedir;

  if (kdedir.isEmpty()) {
	kdedir = getenv("KDEDIR");
	if (kdedir.isEmpty()) {

#ifdef KDEDIR
	  kdedir = KDEDIR;
#else
	  kdedir = "/usr/local/kde";
#endif
	}
  }

  return kdedir;
}


/* maybe we could read it out of a config file, but
   this can be added later */
const QString KApplication::kde_htmldir()
{
  static QString dir;
  if (dir.isNull()) {
      dir = KDE_HTMLDIR;
      if (!strncmp(dir.data(), "KDEDIR", 6))
	  dir = kdedir() + dir.right(dir.length() - 6);
  }
  return dir;
}

const QString KApplication::kde_appsdir()
{
  static QString dir;
  if (dir.isNull()) {
      dir = KDE_APPSDIR;
      if (!strncmp(dir.data(), "KDEDIR", 6))
	  dir = kdedir() + dir.right(dir.length() - 6);
  }
  return dir;
}

const QString KApplication::kde_icondir()
{
  static QString dir;
  if (dir.isNull()) {
      dir = KDE_ICONDIR;
      if (!strncmp(dir.data(), "KDEDIR", 6))
	  dir = kdedir() + dir.right(dir.length() - 6);
  }
  return dir;
}

const QString KApplication::kde_datadir()
{
  static QString dir;
  if (dir.isNull()) {
      dir = KDE_DATADIR;
      if (!strncmp(dir.data(), "KDEDIR", 6))
	  dir = kdedir() + dir.right(dir.length() - 6);
  }
  return dir;
}

const QString KApplication::kde_localedir()
{
  static QString dir;
  if (dir.isNull()) {
	dir = KDE_LOCALE;
	if (!strncmp(dir.data(), "KDEDIR", 6))
	    dir = kdedir() + dir.right(dir.length() - 6);
  }
  return dir;
}

const QString KApplication::kde_cgidir()
{
  static QString dir;
  if (dir.isNull()) {
      dir = KDE_CGIDIR;
      if (!strncmp(dir.data(), "KDEDIR", 6))
	  dir = kdedir() + dir.right(dir.length() - 6);
  }
  return dir;
}

const QString KApplication::kde_sounddir()
{
  static QString dir;
  if (dir.isNull()) {
      dir = KDE_SOUNDDIR;
      if (!strncmp(dir.data(), "KDEDIR", 6))
	  dir = kdedir() + dir.right(dir.length() - 6);
  }
  return dir;
}

const QString KApplication::kde_toolbardir()
{
  static QString dir;
  if (dir.isNull()) {
      dir = KDE_TOOLBARDIR;
      if (!strncmp(dir.data(), "KDEDIR", 6))
	  dir = kdedir() + dir.right(dir.length() - 6);
  }
  return dir;
}

const QString KApplication::kde_wallpaperdir()
{
  static QString dir;
  if (dir.isNull()) {
      dir = KDE_WALLPAPERDIR;
      if (!strncmp(dir.data(), "KDEDIR", 6))
	  dir = kdedir() + dir.right(dir.length() - 6);
  }
  return dir;
}

const QString KApplication::kde_bindir()
{
  static QString dir;
  if (dir.isNull()) {
      dir = KDE_BINDIR;
      if (!strncmp(dir.data(), "KDEDIR", 6))
	  dir = kdedir() + dir.right(dir.length() - 6);
  }
  return dir;
}

const QString KApplication::kde_partsdir()
{
  static QString dir;
  if (dir.isNull()) {
      dir = KDE_PARTSDIR;
      if (!strncmp(dir.data(), "KDEDIR", 6))
	  dir = kdedir() + dir.right(dir.length() - 6);
  }
  return dir;
}

const QString KApplication::kde_configdir()
{
  static QString dir;
  if (dir.isNull()) {
      dir = KDE_CONFIGDIR;
      if (!strncmp(dir.data(), "KDEDIR", 6))
	  dir = kdedir() + dir.right(dir.length() - 6);
  }
  return dir;
}

const QString KApplication::kde_mimedir()
{
  static QString dir;
  if (dir.isNull()) {
      dir = KDE_MIMEDIR;
      if (!strncmp(dir.data(), "KDEDIR", 6))
	  dir = kdedir() + dir.right(dir.length() - 6);
  }
  return dir;
}


QString KApplication::localkdedir()
{
  return ( QDir::homeDirPath() + "/.kde" );
}


QString KApplication::localconfigdir()
{
  return ( localkdedir() + "/share/config" );
}


bool KApplication::getKDEFonts(QStrList *fontlist)
{
  QString fontfilename;

  if(fontlist == 0L)
    return false;

  fontfilename = KApplication::localkdedir();

  if(fontfilename.isEmpty()){
    return false;
  }

  fontfilename = fontfilename + "/share/config/kdefonts";

  QFile fontfile(fontfilename);

  if (!fontfile.exists())
    return false;

  if(!fontfile.open(IO_ReadOnly)){
    return false;
  }

  if (!fontfile.isReadable())
    return false;

  QTextStream t(&fontfile);


  while ( !t.eof() ) {
    QString s = t.readLine();
    if(!s.isEmpty())
      fontlist->append( s );
  }

  fontfile.close();

  return true;
}


const QString KApplication::tempSaveName( const QString& pFilename )
{
  QString aFilename;

  if( pFilename[0] != '/' )
	{
	  kdebug( KDEBUG_WARN, 101, "Relative filename passed to KApplication::tempSaveName" \
);  aFilename = QFileInfo( QDir( "." ), pFilename ).absFilePath();
	}
  else
	aFilename = pFilename;

  QDir aAutosaveDir( QDir::homeDirPath() + "/autosave/" );
  if( !aAutosaveDir.exists() )
	{
	  if( !aAutosaveDir.mkdir( aAutosaveDir.absPath() ) )
		{
		  // Last chance: use _PATH_TMP
		  aAutosaveDir.setPath( _PATH_TMP );
		}
	}

  aFilename.replace( QRegExp( "/" ), "\\!" ).prepend( "#" ).append( "#" ).prepend( \
"/" ).prepend( aAutosaveDir.absPath() );

  return qstrdup( aFilename.data() );
}


const QString KApplication::checkRecoverFile( const QString& pFilename,
        bool& bRecover )
{
  QString aFilename;

  if( pFilename[0] != '/' )
	{
	  kdebug( KDEBUG_WARN, 101, "Relative filename passed to KApplication::tempSaveName" \
);  aFilename = QFileInfo( QDir( "." ), pFilename ).absFilePath();
	}
  else
	aFilename = pFilename;

  QDir aAutosaveDir( QDir::homeDirPath() + "/autosave/" );
  if( !aAutosaveDir.exists() )
	{
	  if( !aAutosaveDir.mkdir( aAutosaveDir.absPath() ) )
		{
		  // Last chance: use _PATH_TMP
		  aAutosaveDir.setPath( _PATH_TMP );
		}
	}

  aFilename.replace( QRegExp( "/" ), "\\!" ).prepend( "#" ).append( "#" ).prepend( \
"/" ).prepend( aAutosaveDir.absPath() );

  if( QFile( aFilename ).exists() )
	{
	  bRecover = true;
	  return qstrdup( aFilename.data() );
	}
  else
	{
	  bRecover = false;
	  return qstrdup( pFilename );
	}
}


bool checkAccess(const QString& pathname, int mode)
{
  int accessOK = access( pathname, mode );
  if ( accessOK == 0 )
    return true;  // OK, I can really access the file

  // else
  // if we want to write the file would be created. Check, if the
  // user may write to the directory to create the file.
  if ( mode & W_OK == 0 )
    return false;   // Check for write access is not part of mode => bail out


  //strip the filename (everything until '/' from the end
  QString dirName(pathname);
  int pos = dirName.findRev('/');
  if ( pos == -1 )
    return false;   // No path in argument. This is evil, we won't allow this

  dirName.truncate(pos); // strip everything starting from the last '/'

  accessOK = access( dirName, W_OK );
  // -?- Can I write to the accessed diretory
  if ( accessOK == 0 )
    return true;  // Yes
  else
    return false; // No
}


void KApplication::setTopWidget( QWidget *topWidget )
{
  pTopWidget = topWidget;
  if (topWidget){
    // set the specified icons
    KWM::setIcon(topWidget->winId(), getIcon());
    KWM::setMiniIcon(topWidget->winId(), getMiniIcon());
    // set a short icon text
    XSetIconName( qt_xdisplay(), topWidget->winId(), getCaption() );
    if (bSessionManagement)
      enableSessionManagement(bSessionManagementUserDefined);

    if (!bSessionManagement)
	KWM::setWmCommand( topWidget->winId(), aWmCommand);
  }
}

void KApplication::registerTopWidget()
{
}

void KApplication::unregisterTopWidget()
{
}


QColor KApplication::inactiveTitleColor()
{
    return inactiveTitleColor_;
}


QColor KApplication::inactiveTextColor()
{
    return inactiveTextColor_;
}


QColor KApplication::activeTitleColor()
{
    return activeTitleColor_;
}


QColor KApplication::activeTextColor()
{
    return activeTextColor_;
}

int KApplication::contrast()
{
    return contrast_;
}

QFont KApplication::generalFont()
{
    return generalFont_;
}

QFont KApplication::fixedFont()
{
    return fixedFont_;
}


Qt::GUIStyle KApplication::applicationStyle()
{
    return applicationStyle_;
}



#include "kapp.moc"


["klocale.cpp" (text/plain)]

/* This file is part of the KDE libraries
    Copyright (C) 1997 Stephan Kulow (coolo@kde.org)

    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Library General Public
    License as published by the Free Software Foundation; either
    version 2 of the License, or (at your option) any later version.

    This library 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
    Library General Public License for more details.

    You should have received a copy of the GNU Library General Public License
    along with this library; see the file COPYING.LIB.  If not, write to
    the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
    Boston, MA 02111-1307, USA.
*/

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

// Overloading of all standard locale functions makes no sense
// Let application use them
#ifdef HAVE_LOCALE_H 
#include <locale.h>
#endif

#include <stdlib.h>

#include <qdir.h>
/**
  * Stephan: I don't want to put this in an extra header file, since
  * this would let people think, they can use it within C files, but
  * this is not the case.
  **/

/* Look up MSGID in the DOMAINNAME message catalog for the current CATEGORY
   locale.  */
char *k_dcgettext (const char* __domainname, const char* __msgid,
		   const char* _language);

/* Set the current default message catalog to DOMAINNAME.
   If DOMAINNAME is null, return the current default.
   If DOMAINNAME is "", reset to the default of "messages".  */
char *k_textdomain (const QString& __domainname);

/* Specify that the DOMAINNAME message catalog will be found
   in DIRNAME rather than in the system locale data base.  */
char *k_bindtextdomain (const char* __domainname,
			const char* __dirname);  


#include "klocale.h"
#include <kapp.h>
#include <kconfig.h>
#include <kcharsets.h>

#if !HAVE_LC_MESSAGES
/* This value determines the behaviour of the gettext() and dgettext()
   function.  But some system does not have this defined.  Define it
   to a default value.  */
# define LC_MESSAGES (-1)
#endif
 
#define SYSTEM_MESSAGES "kdelibs"

static char *_categories[]={"LC_MESSAGES","LC_CTYPE","LC_COLLATE",
                            "LC_TIME","LC_NUMERIC","LC_MONETARY",0};

const QString KLocale::mergeLocale(const QString& lang,const QString& country,
				   const QString& charset)
{
    if (lang.isEmpty()) 
	return "C";
    QString ret = lang;
    if (!country.isEmpty()) 
	ret += "_" + country;
    if (!charset.isEmpty()) 
	ret+= "." +charset;
    return ret;
}

void KLocale::splitLocale(const QString& aStr,
			  QString& lang,
			  QString& country,
			  QString& chset){
   
    QString str = aStr.copy();

    // just in case, there is another language appended
    int f = str.find(':');
    if (f >= 0) {
	str = str.left(f);
    }

    country="";
    chset="";
    lang="";
    
    f = str.find('.');
    if (f >= 0) {
	chset = str.right(str.length() - f - 1);
	str = str.left(f);
    }
    
    f = str.find('_');
    if (f >= 0) { 
	country = str.right(str.length() - f - 1);
	str = str.left(f);
    }
    
    lang = str;
    
    if (chset.isEmpty() && kapp != 0){
	QString directory = KApplication::kde_localedir();
	QString dir=directory+"/"+lang+"_"+country;
	QDir d(dir);
	if (!d.exists("charset")){
	    dir=directory+"/"+lang;
	    d=QDir(dir);
	}  
	if (d.exists("charset")){
	    QFile f(dir+"/charset");   
	    if (f.exists() && f.open(IO_ReadOnly)){
		char *buf=new char[256];
		int l=f.readLine(buf,256);
		if (l>0){
		    if (buf[l-1]=='\n') buf[l-1]=0;
		    if (KCharset(buf).ok()) chset=buf;
		}
		delete [] buf;
		f.close();
	    }
	}    
    }  
}

#ifdef ENABLE_NLS

KLocale::KLocale( const char *catalogue )
{
#ifdef HAVE_SETLOCALE
    /* Set locale via LC_ALL according to environment variables  */
    setlocale (LC_ALL, "");
#endif
    chset="us-ascii";
    if (! catalogue)
        catalogue = kapp->appName().data();
    
    catalogues = new QStrList(true);
    
    const char *g_lang = getenv("KDE_LANG");
    QString languages(g_lang);

    bool set_locale_vars=false;

    if (kapp) {
	QString setting;
	KConfig* config = kapp->getConfig();
	config->setGroup("Locale");
	if (!g_lang) {
	    languages = config->readEntry("Language", "default");
	    printf("languages = %s\n", languages.ascii() );
	}
#ifdef HAVE_SETLOCALE

	setting = config->readEntry("Collate", "default");
	if (setting!="default") 
	    setlocale (LC_COLLATE, setting);
	setting = config->readEntry("Time", "default");
	if (setting!="default") 
	    setlocale (LC_TIME, setting);
	setting = config->readEntry("Monetary", "default");
	if (setting!="default") 
	    setlocale (LC_MONETARY, setting);
	setting = config->readEntry("CType", "default");
	if (setting!="default") 
	    setlocale (LC_CTYPE, setting);
	setting = config->readEntry("Numeric", "default");
	if (setting!="default") 
	    setlocale (LC_NUMERIC, setting);
#endif
	set_locale_vars  = config->readBoolEntry("SetLocaleVariables"
						 , false);
    }
    else 
	if (!g_lang) languages = "default";
    
#ifdef HAVE_SETLOCALE
    // setlocale reads variables LC_* and LANG, and it may use aliases,
    // so we don't have to do it

    // xxxxxxxxxxxx
    //    g_lang = setlocale(LC_MESSAGES,0);
    g_lang = setlocale(LC_MESSAGES,"");
#else   
    g_lang = getenv("LANG");
#endif
    
    if (languages.isEmpty() || (languages == "default")) {
	if (g_lang && g_lang[0]!=0) // LANG value is set and is not ""
	    languages = g_lang;
	else
	    languages = "C";
    }
    else 
	languages = languages + ":C";

    QString directory(KApplication::kde_localedir());
    QString ln,ct,chrset;
   
    // save languages list requested by user
    langs=languages;    
    
    while (1) {
      int f = languages.find(':');
	if (f > 0) {
	    lang = languages.left(f);
	    languages = languages.right(languages.length() - 
					lang.length() - 1);
	} else {
	    lang = languages;
	    languages = "";
	}
	
	if (lang.isEmpty() || lang == "C")
	    break;

        splitLocale(lang,ln,ct,chrset);	

	QString lng[3];
	lng[0]=ln+"_"+ct+"."+chrset;
	lng[1]=ln+"_"+ct;
	lng[2]=ln;
	int i;
	for(i=0; i<3; i++) {
	  QDir d(directory + "/" + lng[i] + "/LC_MESSAGES");

	  if (d.exists(QString(catalogue) + ".mo") &&
	      d.exists(QString(SYSTEM_MESSAGES) + ".mo")) 
	      {
		  lang = lng[i];
		  break;
	      }
        }

	if (i != 3)
	    break;

    }

    chset=chrset;
#ifdef HAVE_SETLOCALE
    lc_numeric=setlocale(LC_NUMERIC,0);
    setlocale(LC_NUMERIC,"C");          // by default disable LC_NUMERIC
    setlocale(LC_MESSAGES,lang);       
    if (set_locale_vars){
        // set environment variables for all categories
	// maybe we should treat LC_NUMERIC differently (netscape problem)
	QString stmp;
        for(int i=0;_categories[i]!=0;i++) {
	  stmp = QString(_categories[i])+ "=" + getLocale(_categories[i]);
 	  putenv( stmp.data() );
	}
    }
    // we should use LC_CTYPE, not LC_MESSAGES for charset
    // however in most cases it should be the same for messages
    // to be readable (there is no i18n messages charset conversion yet)
    // So when LC_CTYPE is not set (is set to "C") better stay
    // with LC_MESSAGES
    QString lc_ctype=getLocale("LC_CTYPE");
    if ( !lc_ctype.isEmpty() && lc_ctype!="C"){
      splitLocale(getLocale("LC_CTYPE"),ln,ct,chrset);
      if (!chrset.isEmpty()) chset=chrset;
    }  
#else
    lc_numeric="C";
#endif
    numeric_enabled=false;

    insertCatalogue( catalogue );
    insertCatalogue( SYSTEM_MESSAGES );
    if (chset.isEmpty() || !KCharset(chset).ok()) chset="us-ascii";
}

void KLocale::insertCatalogue( const char* catalogue )
{
    k_bindtextdomain ( catalogue , KApplication::kde_localedir() );
    catalogues->append(catalogue);
}

KLocale::~KLocale()
{
    delete catalogues;
}

const QString KLocale::translate(const char* msgid)
{
    const char *text = msgid;
    for (const char* catalogue = catalogues->first(); catalogue; 
	 catalogue = catalogues->next()) 
    {
	text = k_dcgettext( catalogue, msgid, lang);
	if ( text != msgid) // we found it
	    break;
    }

    // to convert CJK encoding to unicode
    // return text;
    return kapp->translate("KLocale", text);
}

QString KLocale::directory() 
{
    return KApplication::kde_localedir() +  "/" + lang;
}

void KLocale::aliasLocale( const char* text, long int index)
{
    aliases.insert(index, translate(text));
}

// Using strings seems to be more portable (for systems without locale.h
const QString KLocale::getLocale(const QString& cat){

    cat.upper();
    if (cat=="LC_NUMERIC") return lc_numeric;
#ifdef HAVE_SETLOCALE        
    else if (cat=="LC_MESSAGES") return setlocale(LC_MESSAGES,0);
    else if (cat=="LC_COLLATE") return setlocale(LC_COLLATE,0);
    else if (cat=="LC_TIME") return setlocale(LC_TIME,0);
    else if (cat=="LC_CTYPE") return setlocale(LC_CTYPE,0);
    else if (cat=="LC_MONETARY") return setlocale(LC_MONETARY,0);
#endif	
    else return "C";
}

void KLocale::enableNumericLocale(bool on){
#ifdef HAVE_SETLOCALE
    if (on) 
	setlocale(LC_NUMERIC,lc_numeric);
    else 
	setlocale(LC_NUMERIC,"C");  
    numeric_enabled=on;
#else  
    numeric_enabled=false;
#endif
}

bool KLocale::numericLocaleEnabled()const{
    return numeric_enabled;
}
 
QStrList KLocale::languageList()const{

// a list to be returned
    QStrList list;
// temporary copy of language list
    QString str(langs);
    
    while(!str.isEmpty()){
      int f = str.find(':');
      if (f >= 0) {
  	list.append(str.left(f));
        str=str.right(str.length()-f-1);
      }
      else{
        list.append(str);
        str="";
      }
    }   
    return list;
}

#else /* ENABLE_NLS */

KLocale::KLocale( const char * ) 
{
}

KLocale::~KLocale() 
{
}

const QString KLocale::translate(const char* msgid)
{
    return msgid;
}

QString KLocale::directory() 
{
    return KApplication::kde_localedir();
}

void KLocale::aliasLocale(const char *text, long int index)
{
    aliases.insert(index, text);
}

const QString KLocale::getLocale(const QString& ){
    return "C";
}

void  KLocale::enableNumericLocale(bool){
}

bool  KLocale::numericLocaleEnabled()const{
    return false;
}
 
QStrList KLocale::languageList()const{
    return QStrList();
}

void KLocale::insertCatalogue( const char *catalogue) {
}

#endif /* ENABLE_NLS */


const QString KLocale::getAlias(long key) const
{
    return aliases[key];
}

QString i18n(const char* text) {
#ifdef ENABLE_NLS

  static KLocale *instance = 0;
  if (!instance) {
    KApplication *app = KApplication::getKApplication();
    if (app) {
      instance = app->getLocale();
    }
    else
      return text;
  }
  return instance->translate(text); 
#else
  return text;
#endif
}



[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic