summaryrefslogtreecommitdiff
Side-by-side diff
Diffstat (more/less context) (show whitespace changes)
-rw-r--r--libopie2/opieui/big-screen/osplitter.cpp2
-rw-r--r--library/qpeapplication.cpp6
-rw-r--r--noncore/applets/pcmcia/pcmcia.cpp6
-rw-r--r--noncore/apps/checkbook/mainwindow.cpp3
-rw-r--r--noncore/apps/opie-console/procctl.cpp3
-rw-r--r--noncore/apps/tinykate/libkate/document/katedocument.cpp63
-rw-r--r--noncore/settings/sysinfo/devicesinfo.cpp2
-rw-r--r--noncore/todayplugins/stockticker/libstocks/http.c2
8 files changed, 48 insertions, 39 deletions
diff --git a/libopie2/opieui/big-screen/osplitter.cpp b/libopie2/opieui/big-screen/osplitter.cpp
index 78e919a..5d1e2cf 100644
--- a/libopie2/opieui/big-screen/osplitter.cpp
+++ b/libopie2/opieui/big-screen/osplitter.cpp
@@ -1,625 +1,625 @@
/*
               =. This file is part of the OPIE Project
             .=l. Copyright (c) 2003 hOlgAr <zecke@handhelds.org>
           .>+-=
 _;:,     .>    :=|. This library is free software; you can
.> <`_,   >  .   <= redistribute it and/or modify it under
:`=1 )Y*s>-.--   : the terms of the GNU Library General Public
.="- .-=="i,     .._ License as published by the Free Software
 - .   .-<_>     .<> Foundation; either version 2 of the License,
     ._= =}       : or (at your option) any later version.
    .%`+i>       _;_.
    .i_,=:_.      -<s. 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.
*/
#include "osplitter.h"
/* OPIE */
#include <opie2/otabwidget.h>
#include <opie2/odebug.h>
/* QT */
#include <qvaluelist.h>
#include <qvbox.h>
using namespace Opie::Ui;
using namespace Opie::Ui::Internal;
/**
*
* This is the constructor of OSplitter
* You might want to call setSizeChange to tell
* OSplitter to change its layout when a specefic
* mark was crossed. OSplitter sets a default value.
*
* You cann add widget with addWidget to the OSplitter.
* OSplitter supports also grouping of Splitters where they
* can share one OTabBar in small screen mode. This can be used
* for email clients like vies but see the example.
*
* @param orient The orientation wether to layout horizontal or vertical
* @param parent The parent of this widget
* @param name The name passed on to QObject
* @param fl Additional widgets flags passed to QWidget
*
* @short single c'tor of the OSplitter
*/
OSplitter::OSplitter( Orientation orient, QWidget* parent, const char* name, WFlags fl )
: QFrame( parent, name, fl )
{
m_orient = orient;
m_hbox = 0;
m_size_policy = 330;
setFontPropagation( AllChildren );
setPalettePropagation( AllChildren );
/* start by default with the tab widget */
m_tabWidget = 0;
m_parentTab = 0;
changeTab();
}
/**
* Destructor destructs this object and cleans up. All child
* widgets will be deleted
* @see addWidget
*/
OSplitter::~OSplitter()
{
m_splitter.setAutoDelete( true );
m_splitter.clear();
delete m_hbox;
delete m_tabWidget;
}
/**
* Sets the label for the Splitter. This label will be used
* if a parent splitter is arranged as TabWidget but
* this splitter is in fullscreen mode. Then a tab with OSplitter::label()
* and iconName() gets added.
*
* @param name The name of the Label
*/
void OSplitter::setLabel( const QString& name )
{
m_name = name;
}
/**
* @see setLabel but this is for the icon retrieved by Resource
*
* @param name The name of the icon in example ( "zoom" )
*/
void OSplitter::setIconName( const QString& name )
{
m_icon = name;
}
/**
* returns the iconName
* @see setIconName
*/
QString OSplitter::iconName()const
{
return m_icon;
}
/**
* returns the label set with setLabel
* @see setLabel
*/
QString OSplitter::label()const
{
return m_name;
}
/**
* This function sets the size change policy of the splitter.
* If this size marked is crossed the splitter will relayout.
* Note: that depending on the set Orientation it'll either look
* at the width or height.
* Note: If you want to from side to side view to tabbed view you need
* to make sure that the size you supply is not smaller than the minimum
* size of your added widgets. Note that if you use widgets like QComboBoxes
* you need to teach them to accept smaller sizes as well @see QWidget::setSizePolicy
*
* @param width_height The mark that will be watched. Interpreted depending on the Orientation of the Splitter.
* @return void
*/
void OSplitter::setSizeChange( int width_height )
{
m_size_policy = width_height;
QSize sz(width(), height() );
QResizeEvent ev(sz, sz );
resizeEvent(&ev);
}
/**
* This functions allows to add another OSplitter and to share
* the OTabBar in small screen mode. The ownerships gets transfered.
* OSplitters are always added after normal widget items
*/
void OSplitter::addWidget( OSplitter* split )
{
m_splitter.append( split );
/*
* set tab widget
*/
if (m_tabWidget )
setTabWidget( m_parentTab );
else
{
OSplitterContainer con;
con.widget =split;
addToBox( con );
}
}
/*
* If in a tab it should be removed
* and if in a hbox the reparent kills it too
*/
/**
* This removes the splitter again. You currently need to call this
* before you delete or otherwise you can get mem corruption
* or other weird behaviour.
* Owner ship gets transfered back to you it's current parent
* is 0
*/
void OSplitter::removeWidget( OSplitter* split)
{
split->setTabWidget( 0 );
split->reparent( 0, 0, QPoint(0, 0) );
}
/**
* Adds a widget to the Splitter. The widgets gets inserted
* at the end of either the Box or TabWidget.
* Ownership gets transfered and the widgets gets reparented.
* Note: icon and label is only available on small screensizes
* if size is smaller than the mark
* Warning: No null checking of the widget is done. Only on debug
* a message will be outputtet
*
* @param wid The widget which will be added
* @param icon The icon of the possible Tab
* @param label The label of the possible Tab
*/
void OSplitter::addWidget( QWidget* wid, const QString& icon, const QString& label )
{
#ifdef DEBUG
if (!wid )
return;
#endif
OSplitterContainer cont;
cont.widget = wid;
cont.icon =icon;
cont.name = label;
m_container.append( cont );
/*
*
*/
if (!m_splitter.isEmpty() && (m_tabWidget || m_parentTab ) )
setTabWidget( m_parentTab );
else
{
if (m_hbox )
addToBox( cont );
- else
+ else if (m_tabWidget)
addToTab( cont );
}
}
/**
* Removes the widget from the tab widgets if necessary.
* OSplitter drops ownership of this widget and the widget
* will be reparented i tto 0.
* The widget will not be deleted.
*
* @param w The widget to be removed
*/
void OSplitter::removeWidget( QWidget* w)
{
ContainerList::Iterator it;
for ( it = m_container.begin(); it != m_container.end(); ++it )
if ( (*it).widget == w )
break;
if (it == m_container.end() )
return;
/* only tab needs to be removed.. box recognizes it */
if ( !m_hbox )
removeFromTab( w );
/* Find reparent it and remove it from our list */
w->reparent( 0, 0, QPoint(0, 0));
it = m_container.remove( it );
}
/**
* This method will give focus to the widget. If in a tabwidget
* the tabbar will be changed
*
* @param w The widget which will be set the current one
*/
void OSplitter::setCurrentWidget( QWidget* w)
{
if (m_tabWidget )
m_tabWidget->setCurrentTab( w );
// else
// m_hbox->setFocus( w );
}
/**
* This is an overloaded member function and only differs in the
* argument it takes.
* Searches list of widgets for label. It'll pick the first label it finds
*
* @param label Label to look for. First match will be taken
*/
void OSplitter::setCurrentWidget( const QString& label )
{
ContainerList::Iterator it;
for (it = m_container.begin(); it != m_container.end(); ++it )
{
if ( (*it).name == label )
{
setCurrentWidget( (*it).widget );
break;
}
}
}
/**
* This will only work when the TabWidget is active
* If everything is visible this signal is kindly ignored
* @see OTabWidget::setCurrentTab(int)
*
* @param tab The tab to make current
*/
void OSplitter::setCurrentWidget( int tab )
{
if (m_tabWidget )
m_tabWidget->setCurrentTab( tab );
}
/**
* return the currently activated widget if in tab widget mode
* or null because all widgets are visible
*/
QWidget* OSplitter::currentWidget() const
{
if (m_tabWidget)
return m_tabWidget->currentWidget();
else if (m_parentTab )
return m_parentTab->currentWidget();
return 0l;
}
/* wrong */
#if 0
/**
* @reimplented for internal reasons
* returns the sizeHint of one of its sub widgets
*/
QSize OSplitter::sizeHint()const
{
if (m_parentTab )
return QFrame::sizeHint();
if (m_hbox )
return m_hbox->sizeHint();
else
return m_tabWidget->sizeHint();
}
QSize OSplitter::minimumSizeHint()const
{
if (m_parentTab )
return QFrame::minimumSizeHint();
if (m_hbox)
return m_hbox->sizeHint();
else
return m_tabWidget->sizeHint();
}
#endif
/**
* @reimplemented for internal reasons
*/
void OSplitter::resizeEvent( QResizeEvent* res )
{
QFrame::resizeEvent( res );
/*
*
*/
bool mode = true;
if ( res->size().width() > m_size_policy &&
m_orient == Horizontal )
{
changeHBox();
mode = false;
}
else if ( (res->size().width() <= m_size_policy &&
m_orient == Horizontal ) ||
(res->size().height() <= m_size_policy &&
m_orient == Vertical ) )
{
changeTab();
}
else if ( res->size().height() > m_size_policy &&
m_orient == Vertical )
{
changeVBox();
mode = false;
}
emit sizeChanged(mode, m_orient );
}
/*
* Adds a container to a tab either the parent tab
* or our own
*/
void OSplitter::addToTab( const Opie::Ui::Internal::OSplitterContainer& con )
{
QWidget *wid = con.widget;
// not needed widgetstack will reparent as well wid.reparent(m_tabWidget, wid->getWFlags(), QPoint(0, 0) );
if (m_parentTab )
m_parentTab->addTab( wid, con.icon, con.name );
else
m_tabWidget->addTab( wid, con.icon, con.name );
}
/*
* adds a container to the box
*/
void OSplitter::addToBox( const Opie::Ui::Internal::OSplitterContainer& con )
{
QWidget* wid = con.widget;
wid->reparent(m_hbox, 0, QPoint(0, 0) );
}
/*
* Removes a widget from the tab
*/
void OSplitter::removeFromTab( QWidget* wid )
{
if (m_parentTab )
m_parentTab->removePage( wid );
else
m_tabWidget->removePage( wid );
}
/*
* switches over to a OTabWidget layout
* it is recursive
*/
void OSplitter::changeTab()
{
/* if we're the owner of the tab widget */
if (m_tabWidget )
{
raise();
show();
m_tabWidget->setGeometry( frameRect() );
return;
}
/*
* and add all widgets this will reparent them
* delete m_hbox set it to 0
*
*/
OTabWidget *tab;
if ( m_parentTab )
{
hide();
tab = m_parentTab;
/* expensive but needed cause we're called from setTabWidget and resizeEvent*/
if (!m_container.isEmpty() )
{
ContainerList::Iterator it = m_container.begin();
for (; it != m_container.end(); ++it )
m_parentTab->removePage( (*it).widget );
}
}
else
tab = m_tabWidget = new OTabWidget( this );
connect(tab, SIGNAL(currentChanged(QWidget*) ),
this, SIGNAL(currentChanged(QWidget*) ) );
for ( ContainerList::Iterator it = m_container.begin(); it != m_container.end(); ++it )
{
addToTab( (*it) );
}
for ( OSplitter* split = m_splitter.first(); split; split = m_splitter.next() )
{
split->reparent(this, 0, QPoint(0, 0) );
split->setTabWidget( tab );
}
delete m_hbox;
m_hbox = 0;
if (!m_tabWidget )
return;
m_tabWidget->setGeometry( frameRect() );
m_tabWidget->show();
}
/*
* changes over to a box
* this is recursive as well
*/
void OSplitter::changeHBox()
{
if (m_hbox )
{
m_hbox->setGeometry( frameRect() );
return;
}
m_hbox = new QHBox( this );
commonChangeBox();
}
void OSplitter::changeVBox()
{
if (m_hbox )
{
m_hbox->setGeometry( frameRect() );
return;
}
m_hbox = new QVBox( this );
commonChangeBox();
}
/*
* common box code
* first remove and add children
* the other splitters
* it is recursive as well due the call to setTabWidget
*/
void OSplitter::commonChangeBox()
{
for (ContainerList::Iterator it = m_container.begin(); it != m_container.end(); ++it )
{
/* only if parent tab.. m_tabWidgets gets deleted and would do that as well */
if (m_parentTab )
removeFromTab( (*it).widget );
addToBox( (*it) );
}
for ( OSplitter* split = m_splitter.first(); split; split = m_splitter.next() )
{
/* tell them the world had changed */
split->setTabWidget( 0 );
OSplitterContainer con;
con.widget = split;
// con.widget = split->m_tabWidget ? static_cast<QWidget*>(split->m_tabWidget)
// : static_cast<QWidget*>(split->m_hbox);
addToBox( con );
}
if (m_parentTab )
m_parentTab->addTab(m_hbox, iconName(), label() );
else
{
m_hbox->setGeometry( frameRect() );
m_hbox->show();
delete m_tabWidget;
m_tabWidget = 0;
show(); // also show this widget
}
}
/*
* sets the tabwidget, removes tabs, and relayouts the widget
*/
void OSplitter::setTabWidget( OTabWidget* wid)
{
/* clean up cause m_parentTab will not be available for us */
if ( m_parentTab )
{
if (m_hbox )
m_parentTab->removePage( m_hbox );
else if (!m_container.isEmpty() )
{
ContainerList::Iterator it = m_container.begin();
for ( ; it != m_container.end(); ++it )
m_parentTab->removePage( (*it).widget );
}
}
/* the parent Splitter changed so either make us indepent or dep */
m_parentTab = wid;
QWidget *tab = m_tabWidget;
QWidget *box = m_hbox;
m_hbox = 0; m_tabWidget = 0;
if ( layoutMode() )
changeTab();
else if (m_orient == Horizontal )
changeHBox();
else
changeVBox();
/* our own crap is added and children from change* */
delete tab;
delete box;
}
#if 0
void OSplitter::reparentAll()
{
if (m_container.isEmpty() )
return;
ContainerList::Iterator it = m_container.begin();
for ( ; it != m_container.end(); ++it )
(*it).wid->reparent(0, 0, QPoint(0, 0) );
}
#endif
/**
* @internal
*/
bool OSplitter::layoutMode()const
{
if ( size().width() > m_size_policy &&
m_orient == Horizontal )
{
return false;
}
else if ( size().height() > m_size_policy &&
m_orient == Vertical )
{
return false;
}
return true;
}
diff --git a/library/qpeapplication.cpp b/library/qpeapplication.cpp
index 34f5e6a..d959c7a 100644
--- a/library/qpeapplication.cpp
+++ b/library/qpeapplication.cpp
@@ -1,2296 +1,2296 @@
/**********************************************************************
** Copyright (C) 2000-2002 Trolltech AS. All rights reserved.
**
** This file is part of the Qtopia Environment.
**
** This file may be distributed and/or modified under the terms of the
** GNU General Public License version 2 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the
** packaging of this file.
**
** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
**
** See http://www.trolltech.com/gpl/ for GPL licensing information.
**
** Contact info@trolltech.com if any conditions of this licensing are
** not clear to you.
**
*/
#define QTOPIA_INTERNAL_LANGLIST
#include <stdlib.h>
#include <unistd.h>
#ifndef Q_OS_MACX
#include <linux/limits.h> // needed for some toolchains (PATH_MAX)
#endif
#include <qfile.h>
#include <qqueue.h>
#ifdef Q_WS_QWS
#ifndef QT_NO_COP
#if QT_VERSION <= 231
#define private public
#define sendLocally processEvent
#include "qcopenvelope_qws.h"
#undef private
#else
#include "qcopenvelope_qws.h"
#endif
#endif
#include <qwindowsystem_qws.h>
#endif
#include <qtextstream.h>
#include <qpalette.h>
#include <qbuffer.h>
#include <qptrdict.h>
#include <qregexp.h>
#include <qdir.h>
#include <qlabel.h>
#include <qdialog.h>
#include <qdragobject.h>
#include <qtextcodec.h>
#include <qevent.h>
#include <qtooltip.h>
#include <qsignal.h>
#include <qmainwindow.h>
#include <qwidgetlist.h>
#include <qpixmapcache.h>
#if defined(Q_WS_QWS) && !defined(QT_NO_COP)
#define QTOPIA_INTERNAL_INITAPP
#include "qpeapplication.h"
#include "qpestyle.h"
#include "styleinterface.h"
#if QT_VERSION >= 0x030000
#include <qstylefactory.h>
#else
#include <qplatinumstyle.h>
#include <qwindowsstyle.h>
#include <qmotifstyle.h>
#include <qmotifplusstyle.h>
#include "lightstyle.h"
#include <qpe/qlibrary.h>
#endif
#include "global.h"
#include "resource.h"
#if QT_VERSION <= 230 && defined(QT_NO_CODECS)
#include "qutfcodec.h"
#endif
#include "config.h"
#include "network.h"
#ifdef QWS
#include "fontmanager.h"
#include "fontdatabase.h"
#endif
#include "alarmserver.h"
#include "applnk.h"
#include "qpemenubar.h"
#include "textcodecinterface.h"
#include "imagecodecinterface.h"
#include <qtopia/qpeglobal.h>
#include <unistd.h>
#include <sys/file.h>
#include <sys/ioctl.h>
#ifndef QT_NO_SOUND
#include <sys/soundcard.h>
#endif
#include <backend/rohfeedback.h>
static bool useBigPixmaps = 0;
static bool saveWindowsPos = 0;
class HackWidget : public QWidget
{
public:
bool needsOk()
{ return (getWState() & WState_Reserved1 ); }
QRect normalGeometry()
{ return topData()->normalGeometry; };
};
class QPEApplicationData
{
public:
QPEApplicationData ( ) :
presstimer( 0 ), presswidget( 0 ), rightpressed( false ), kbgrabbed( false ),
notbusysent( false ), preloaded( false ), forceshow( false ), nomaximize( false ),
keep_running( true ), qcopQok( false ),
fontFamily( "Vera" ), fontSize( 10 ), smallIconSize( 14 ),
bigIconSize( 32 ), qpe_main_widget( 0 )
{
Config cfg( "qpe" );
cfg.setGroup( "Appearance" );
useBigPixmaps = cfg.readBoolEntry( "useBigPixmaps", false );
fontFamily = cfg.readEntry( "FontFamily", "Vera" );
fontSize = cfg.readNumEntry( "FontSize", 10 );
smallIconSize = cfg.readNumEntry( "SmallIconSize", 14 );
bigIconSize = cfg.readNumEntry( "BigIconSize", 32 );
saveWindowsPos = cfg.readBoolEntry( "AllowWindowed", false );
#ifdef OPIE_WITHROHFEEDBACK
RoH = 0;
#endif
}
int presstimer;
QWidget* presswidget;
QPoint presspos;
#ifdef OPIE_WITHROHFEEDBACK
Opie::Internal::RoHFeedback *RoH;
#endif
bool rightpressed : 1;
bool kbgrabbed : 1;
bool notbusysent : 1;
bool preloaded : 1;
bool forceshow : 1;
bool nomaximize : 1;
bool keep_running : 1;
bool qcopQok : 1;
QCString fontFamily;
int fontSize;
int smallIconSize;
int bigIconSize;
QString appName;
struct QCopRec
{
QCopRec( const QCString &ch, const QCString &msg,
const QByteArray &d ) :
channel( ch ), message( msg ), data( d )
{ }
QCString channel;
QCString message;
QByteArray data;
};
QGuardedPtr<QWidget> qpe_main_widget;
QGuardedPtr<QWidget> lastraised;
QQueue<QCopRec> qcopq;
QString styleName;
QString decorationName;
void enqueueQCop( const QCString &ch, const QCString &msg,
const QByteArray &data )
{
qcopq.enqueue( new QCopRec( ch, msg, data ) );
}
void sendQCopQ()
{
if (!qcopQok )
return;
QCopRec * r;
while((r=qcopq.dequeue())) {
// remove from queue before sending...
// event loop can come around again before getting
// back from sendLocally
#ifndef QT_NO_COP
QCopChannel::sendLocally( r->channel, r->message, r->data );
#endif
delete r;
}
}
static void show_mx(QWidget* mw, bool nomaximize, QString &strName) {
if ( mw->inherits("QMainWindow") || mw->isA("QMainWindow") )
{
( ( QMainWindow* ) mw )->setUsesBigPixmaps( useBigPixmaps );
}
QPoint p;
QSize s;
bool max;
if ( mw->isVisible() ) {
if ( read_widget_rect(strName, max, p, s) && validate_widget_size(mw, p, s) ) {
mw->resize(s);
mw->move(p);
}
mw->raise();
} else {
if ( mw->layout() && mw->inherits("QDialog") ) {
if ( read_widget_rect(strName, max, p, s) && validate_widget_size(mw, p, s) ) {
mw->resize(s);
mw->move(p);
if ( max && !nomaximize ) {
mw->showMaximized();
} else {
mw->show();
}
} else {
QPEApplication::showDialog((QDialog*)mw,nomaximize);
}
} else {
if ( read_widget_rect(strName, max, p, s) && validate_widget_size(mw, p, s) ) {
mw->resize(s);
mw->move(p);
} else { //no stored rectangle, make an estimation
int x = (qApp->desktop()->width()-mw->frameGeometry().width())/2;
int y = (qApp->desktop()->height()-mw->frameGeometry().height())/2;
mw->move( QMAX(x,0), QMAX(y,0) );
#ifdef Q_WS_QWS
if ( !nomaximize )
mw->showMaximized();
#endif
}
if ( max && !nomaximize )
mw->showMaximized();
else
mw->show();
}
}
}
static bool read_widget_rect(const QString &app, bool &maximized, QPoint &p, QSize &s)
{
if (!saveWindowsPos)
return FALSE;
maximized = TRUE;
// 350 is the trigger in qwsdefaultdecoration for providing a resize button
if ( qApp->desktop()->width() <= 350 )
return FALSE;
Config cfg( "qpe" );
cfg.setGroup("ApplicationPositions");
QString str = cfg.readEntry( app, QString::null );
QStringList l = QStringList::split(",", str);
if ( l.count() == 5) {
p.setX( l[0].toInt() );
p.setY( l[1].toInt() );
s.setWidth( l[2].toInt() );
s.setHeight( l[3].toInt() );
maximized = l[4].toInt();
return TRUE;
}
}
static bool validate_widget_size(const QWidget *w, QPoint &p, QSize &s)
{
#ifndef Q_WS_QWS
QRect qt_maxWindowRect = qApp->desktop()->geometry();
#endif
int maxX = qt_maxWindowRect.width();
int maxY = qt_maxWindowRect.height();
int wWidth = s.width() + ( w->frameGeometry().width() - w->geometry().width() );
int wHeight = s.height() + ( w->frameGeometry().height() - w->geometry().height() );
// total window size is not allowed to be larger than desktop window size
if ( ( wWidth >= maxX ) && ( wHeight >= maxY ) )
return FALSE;
if ( wWidth > maxX ) {
s.setWidth( maxX - (w->frameGeometry().width() - w->geometry().width() ) );
wWidth = maxX;
}
if ( wHeight > maxY ) {
s.setHeight( maxY - (w->frameGeometry().height() - w->geometry().height() ) );
wHeight = maxY;
}
// any smaller than this and the maximize/close/help buttons will be overlapping
if ( wWidth < 80 || wHeight < 60 )
return FALSE;
if ( p.x() < 0 )
p.setX(0);
if ( p.y() < 0 )
p.setY(0);
if ( p.x() + wWidth > maxX )
p.setX( maxX - wWidth );
if ( p.y() + wHeight > maxY )
p.setY( maxY - wHeight );
return TRUE;
}
static void store_widget_rect(QWidget *w, QString &app)
{
if( !w )
return;
if (!saveWindowsPos)
return;
// 350 is the trigger in qwsdefaultdecoration for providing a resize button
if ( qApp->desktop()->width() <= 350 )
return;
// we use these to map the offset of geometry and pos. ( we can only use normalGeometry to
// get the non-maximized version, so we have to do it the hard way )
int offsetX = w->x() - w->geometry().left();
int offsetY = w->y() - w->geometry().top();
QRect r;
if ( w->isMaximized() )
r = ( (HackWidget *) w)->normalGeometry();
else
r = w->geometry();
// Stores the window placement as pos(), size() (due to the offset mapping)
Config cfg( "qpe" );
cfg.setGroup("ApplicationPositions");
QString s;
s.sprintf("%d,%d,%d,%d,%d", r.left() + offsetX, r.top() + offsetY, r.width(), r.height(), w->isMaximized() );
cfg.writeEntry( app, s );
}
static bool setWidgetCaptionFromAppName( QWidget* /*mw*/, const QString& /*appName*/, const QString& /*appsPath*/ )
{
/*
// This works but disable it for now until it is safe to apply
// What is does is scan the .desktop files of all the apps for
// the applnk that has the corresponding argv[0] as this program
// then it uses the name stored in the .desktop file as the caption
// for the main widget. This saves duplicating translations for
// the app name in the program and in the .desktop files.
AppLnkSet apps( appsPath );
QList<AppLnk> appsList = apps.children();
for ( QListIterator<AppLnk> it(appsList); it.current(); ++it ) {
if ( (*it)->exec() == appName ) {
mw->setCaption( (*it)->name() );
return TRUE;
}
}
*/
return FALSE;
}
void show(QWidget* mw, bool nomax)
{
setWidgetCaptionFromAppName( mw, appName, QPEApplication::qpeDir() + "apps" );
nomaximize = nomax;
qpe_main_widget = mw;
qcopQok = TRUE;
#ifndef QT_NO_COP
sendQCopQ();
#endif
if ( preloaded ) {
if (forceshow)
show_mx(mw, nomax, appName);
}
else if ( keep_running ) {
show_mx(mw, nomax, appName);
}
}
void loadTextCodecs()
{
QString path = QPEApplication::qpeDir() + "plugins/textcodecs";
#ifdef Q_OS_MACX
QDir dir( path, "lib*.dylib" );
#else
QDir dir( path, "lib*.so" );
#endif
QStringList list;
if ( dir. exists ( ))
list = dir.entryList();
QStringList::Iterator it;
for ( it = list.begin(); it != list.end(); ++it ) {
TextCodecInterface *iface = 0;
QLibrary *lib = new QLibrary( path + "/" + *it );
if ( lib->queryInterface( IID_QtopiaTextCodec, (QUnknownInterface**)&iface ) == QS_OK && iface ) {
QValueList<int> mibs = iface->mibEnums();
for (QValueList<int>::ConstIterator i = mibs.begin(); i != mibs.end(); ++i) {
(void)iface->createForMib(*i);
// ### it exists now; need to remember if we can delete it
}
}
else {
lib->unload();
delete lib;
}
}
}
void loadImageCodecs()
{
QString path = QPEApplication::qpeDir() + "plugins/imagecodecs";
#ifdef Q_OS_MACX
QDir dir( path, "lib*.dylib" );
#else
QDir dir( path, "lib*.so" );
#endif
QStringList list;
if ( dir. exists ( ))
list = dir.entryList();
QStringList::Iterator it;
for ( it = list.begin(); it != list.end(); ++it ) {
ImageCodecInterface *iface = 0;
QLibrary *lib = new QLibrary( path + "/" + *it );
if ( lib->queryInterface( IID_QtopiaImageCodec, (QUnknownInterface**)&iface ) == QS_OK && iface ) {
QStringList formats = iface->keys();
for (QStringList::ConstIterator i = formats.begin(); i != formats.end(); ++i) {
(void)iface->installIOHandler(*i);
// ### it exists now; need to remember if we can delete it
}
}
else {
lib->unload();
delete lib;
}
}
}
};
class ResourceMimeFactory : public QMimeSourceFactory
{
public:
ResourceMimeFactory() : resImage( 0 )
{
setFilePath( Global::helpPath() );
setExtensionType( "html", "text/html;charset=UTF-8" );
}
~ResourceMimeFactory() {
delete resImage;
}
const QMimeSource* data( const QString& abs_name ) const
{
const QMimeSource * r = QMimeSourceFactory::data( abs_name );
if ( !r ) {
int sl = abs_name.length();
do {
sl = abs_name.findRev( '/', sl - 1 );
QString name = sl >= 0 ? abs_name.mid( sl + 1 ) : abs_name;
int dot = name.findRev( '.' );
if ( dot >= 0 )
name = name.left( dot );
QImage img = Resource::loadImage( name );
if ( !img.isNull() ) {
delete resImage;
resImage = new QImageDrag( img );
r = resImage;
}
}
while ( !r && sl > 0 );
}
return r;
}
private:
mutable QImageDrag *resImage;
};
static int& hack(int& i)
{
#if QT_VERSION <= 230 && defined(QT_NO_CODECS)
// These should be created, but aren't in Qt 2.3.0
(void)new QUtf8Codec;
(void)new QUtf16Codec;
#endif
return i;
}
static int muted = 0;
static int micMuted = 0;
static void setVolume( int t = 0, int percent = -1 )
{
switch ( t ) {
case 0: {
Config cfg( "qpe" );
cfg.setGroup( "Volume" );
if ( percent < 0 )
percent = cfg.readNumEntry( "VolumePercent", 50 );
#ifndef QT_NO_SOUND
int fd = 0;
#ifdef QT_QWS_DEVFS
if ( ( fd = open( "/dev/sound/mixer", O_RDWR ) ) >= 0 ) {
#else
if ( ( fd = open( "/dev/mixer", O_RDWR ) ) >= 0 ) {
#endif
int vol = muted ? 0 : percent;
// set both channels to same volume
vol |= vol << 8;
ioctl( fd, MIXER_WRITE( SOUND_MIXER_VOLUME ), &vol );
::close( fd );
}
#endif
}
break;
}
}
static void setMic( int t = 0, int percent = -1 )
{
switch ( t ) {
case 0: {
Config cfg( "qpe" );
cfg.setGroup( "Volume" );
if ( percent < 0 )
percent = cfg.readNumEntry( "Mic", 50 );
#ifndef QT_NO_SOUND
int fd = 0;
int mic = micMuted ? 0 : percent;
#ifdef QT_QWS_DEVFS
if ( ( fd = open( "/dev/sound/mixer", O_RDWR ) ) >= 0 ) {
#else
if ( ( fd = open( "/dev/mixer", O_RDWR ) ) >= 0 ) {
#endif
ioctl( fd, MIXER_WRITE( SOUND_MIXER_MIC ), &mic );
::close( fd );
}
#endif
}
break;
}
}
static void setBass( int t = 0, int percent = -1 )
{
switch ( t ) {
case 0: {
Config cfg( "qpe" );
cfg.setGroup( "Volume" );
if ( percent < 0 )
percent = cfg.readNumEntry( "BassPercent", 50 );
#ifndef QT_NO_SOUND
int fd = 0;
int bass = percent;
#ifdef QT_QWS_DEVFS
if ( ( fd = open( "/dev/sound/mixer", O_RDWR ) ) >= 0 ) {
#else
if ( ( fd = open( "/dev/mixer", O_RDWR ) ) >= 0 ) {
#endif
ioctl( fd, MIXER_WRITE( SOUND_MIXER_BASS ), &bass );
::close( fd );
}
#endif
}
break;
}
}
static void setTreble( int t = 0, int percent = -1 )
{
switch ( t ) {
case 0: {
Config cfg( "qpe" );
cfg.setGroup( "Volume" );
if ( percent < 0 )
percent = cfg.readNumEntry( "TreblePercent", 50 );
#ifndef QT_NO_SOUND
int fd = 0;
int treble = percent;
#ifdef QT_QWS_DEVFS
if ( ( fd = open( "/dev/sound/mixer", O_RDWR ) ) >= 0 ) {
#else
if ( ( fd = open( "/dev/mixer", O_RDWR ) ) >= 0 ) {
#endif
ioctl( fd, MIXER_WRITE( SOUND_MIXER_TREBLE ), &treble );
::close( fd );
}
#endif
}
break;
}
}
/**
\class QPEApplication
\brief The QPEApplication class implements various system services
that are available to all Qtopia applications.
Simply by using QPEApplication instead of QApplication, a standard Qt
application becomes a Qtopia application. It automatically follows
style changes, quits and raises, and in the
case of \link docwidget.html document-oriented\endlink applications,
changes the currently displayed document in response to the environment.
To create a \link docwidget.html document-oriented\endlink
application use showMainDocumentWidget(); to create a
non-document-oriented application use showMainWidget(). The
keepRunning() function indicates whether the application will
continue running after it's processed the last \link qcop.html
QCop\endlink message. This can be changed using setKeepRunning().
A variety of signals are emitted when certain events occur, for
example, timeChanged(), clockChanged(), weekChanged(),
dateFormatChanged() and volumeChanged(). If the application receives
a \link qcop.html QCop\endlink message on the application's
QPE/Application/\e{appname} channel, the appMessage() signal is
emitted. There are also flush() and reload() signals, which
are emitted when synching begins and ends respectively - upon these
signals, the application should save and reload any data
files that are involved in synching. Most of these signals will initially
be received and unfiltered through the appMessage() signal.
This class also provides a set of useful static functions. The
qpeDir() and documentDir() functions return the respective paths.
The grabKeyboard() and ungrabKeyboard() functions are used to
control whether the application takes control of the device's
physical buttons (e.g. application launch keys). The stylus' mode of
operation is set with setStylusOperation() and retrieved with
stylusOperation(). There are also setInputMethodHint() and
inputMethodHint() functions.
\ingroup qtopiaemb
*/
/*!
\fn void QPEApplication::clientMoused()
\internal
*/
/*!
\fn void QPEApplication::timeChanged();
This signal is emitted when the time changes outside the normal
passage of time, i.e. if the time is set backwards or forwards.
*/
/*!
\fn void QPEApplication::clockChanged( bool ampm );
This signal is emitted when the user changes the clock's style. If
\a ampm is TRUE, the user wants a 12-hour AM/PM clock, otherwise,
they want a 24-hour clock.
*/
/*!
\fn void QPEApplication::volumeChanged( bool muted )
This signal is emitted whenever the mute state is changed. If \a
muted is TRUE, then sound output has been muted.
*/
/*!
\fn void QPEApplication::weekChanged( bool startOnMonday )
This signal is emitted if the week start day is changed. If \a
startOnMonday is TRUE then the first day of the week is Monday; if
\a startOnMonday is FALSE then the first day of the week is
Sunday.
*/
/*!
\fn void QPEApplication::dateFormatChanged(DateFormat)
This signal is emitted whenever the date format is changed.
*/
/*!
\fn void QPEApplication::flush()
###
*/
/*!
\fn void QPEApplication::reload()
*/
void QPEApplication::processQCopFile()
{
QString qcopfn("/tmp/qcop-msg-");
qcopfn += d->appName; // append command name
QFile f(qcopfn);
if ( f.open(IO_ReadWrite) ) {
#ifndef Q_OS_WIN32
flock(f.handle(), LOCK_EX);
#endif
QDataStream ds(&f);
QCString channel, message;
QByteArray data;
while(!ds.atEnd()) {
ds >> channel >> message >> data;
d->enqueueQCop(channel,message,data);
}
::ftruncate(f.handle(), 0);
#ifndef Q_OS_WIN32
f.flush();
flock(f.handle(), LOCK_UN);
#endif
}
#endif
}
/*!
\fn void QPEApplication::appMessage( const QCString& msg, const QByteArray& data )
This signal is emitted when a message is received on this
application's QPE/Application/<i>appname</i> \link qcop.html
QCop\endlink channel.
The slot to which you connect this signal uses \a msg and \a data
in the following way:
\code
void MyWidget::receive( const QCString& msg, const QByteArray& data )
{
QDataStream stream( data, IO_ReadOnly );
if ( msg == "someMessage(int,int,int)" ) {
int a,b,c;
stream >> a >> b >> c;
...
} else if ( msg == "otherMessage(QString)" ) {
...
}
}
\endcode
\sa qcop.html
Note that messages received here may be processed by qpe application
and emitted as signals, such as flush() and reload().
*/
#ifndef QT_NO_TRANSLATION
static void qtopia_loadTranslations( const QStringList& qms )
{
QStringList langs = Global::languageList();
for (QStringList::ConstIterator it = langs.begin(); it!=langs.end(); ++it) {
QString lang = *it;
QTranslator * trans;
QString tfn;
for (QStringList::ConstIterator qmit = qms.begin(); qmit!=qms.end(); ++qmit) {
trans = new QTranslator(qApp);
tfn = QPEApplication::qpeDir() + "i18n/" + lang + "/" + *qmit + ".qm";
if ( trans->load( tfn ))
qApp->installTranslator( trans );
else
delete trans;
}
}
}
#endif
/*
Turn off qDebug in release mode
*/
static void qtopiaMsgHandler(QtMsgType type, const char* msg)
{
switch ( type ) {
case QtDebugMsg:
#ifdef QT_DEBUG
fprintf( stderr, "Debug: %s\n", msg );
#endif
break;
case QtWarningMsg:
#ifdef QT_DEBUG
fprintf( stderr, "Warning: %s\n", msg );
#endif
break;
case QtFatalMsg:
fprintf( stderr, "Fatal: %s\n", msg );
abort();
}
}
/*!
Constructs a QPEApplication just as you would construct
a QApplication, passing \a argc, \a argv, and \a t.
For applications, \a t should be the default, GuiClient. Only
the Qtopia server passes GuiServer.
*/
QPEApplication::QPEApplication( int & argc, char **argv, Type t )
: QApplication( hack(argc), argv, t ), pidChannel( 0 )
{
QPixmapCache::setCacheLimit(256); // sensible default for smaller devices.
qInstallMsgHandler(qtopiaMsgHandler);
d = new QPEApplicationData;
d->loadTextCodecs();
d->loadImageCodecs();
setFont( QFont( d->fontFamily, d->fontSize ) );
AppLnk::setSmallIconSize( d->smallIconSize );
AppLnk::setBigIconSize( d->bigIconSize );
QMimeSourceFactory::setDefaultFactory( new ResourceMimeFactory );
connect( this, SIGNAL( lastWindowClosed() ), this, SLOT( hideOrQuit() ) );
sysChannel = new QCopChannel( "QPE/System", this );
connect( sysChannel, SIGNAL( received(const QCString&,const QByteArray&) ),
this, SLOT( systemMessage(const QCString&,const QByteArray&) ) );
/* COde now in initapp */
#if 0
#if defined(Q_WS_QWS) && !defined(QT_NO_COP)
QString qcopfn( "/tmp/qcop-msg-" );
qcopfn += QString( argv[ 0 ] ); // append command name
QFile f( qcopfn );
if ( f.open( IO_ReadOnly ) ) {
flock( f.handle(), LOCK_EX );
}
QCString channel = QCString( argv[ 0 ] );
channel.replace( QRegExp( ".*/" ), "" );
d->appName = channel;
channel = "QPE/Application/" + channel;
pidChannel = new QCopChannel( channel, this );
connect( pidChannel, SIGNAL( received(const QCString&,const QByteArray&) ),
this, SLOT( pidMessage(const QCString&,const QByteArray&) ) );
if ( f.isOpen() ) {
d->keep_running = FALSE;
QDataStream ds( &f );
QCString channel, message;
QByteArray data;
while ( !ds.atEnd() ) {
ds >> channel >> message >> data;
d->enqueueQCop( channel, message, data );
}
flock( f.handle(), LOCK_UN );
f.close();
f.remove();
}
for ( int a = 0; a < argc; a++ ) {
if ( qstrcmp( argv[ a ], "-preload" ) == 0 ) {
argv[ a ] = argv[ a + 1 ];
a++;
d->preloaded = TRUE;
argc -= 1;
}
else if ( qstrcmp( argv[ a ], "-preload-show" ) == 0 ) {
argv[ a ] = argv[ a + 1 ];
a++;
d->preloaded = TRUE;
d->forceshow = TRUE;
argc -= 1;
}
}
/* overide stored arguments */
setArgs( argc, argv );
#endif
#else
initApp( argc, argv );
#endif
#ifdef Q_WS_QWS
/* load the font renderer factories */
FontDatabase::loadRenderers();
#endif
#ifndef QT_NO_TRANSLATION
QStringList qms;
qms << "libqpe";
qms << "libopie";
qms << d->appName;
qtopia_loadTranslations(qms);
#endif
applyStyle();
if ( type() == GuiServer ) {
setVolume();
}
installEventFilter( this );
QPEMenuToolFocusManager::initialize();
#ifdef QT_NO_QWS_CURSOR
// if we have no cursor, probably don't want tooltips
QToolTip::setEnabled( FALSE );
#endif
}
#ifdef QTOPIA_INTERNAL_INITAPP
void QPEApplication::initApp( int argc, char **argv )
{
delete pidChannel;
d->keep_running = TRUE;
d->preloaded = FALSE;
d->forceshow = FALSE;
QCString channel = QCString(argv[0]);
channel.replace(QRegExp(".*/"),"");
d->appName = channel;
#ifndef QT_NO_TRANSLATION
qtopia_loadTranslations( QStringList()<<channel );
#endif
#if QT_VERSION > 235
qt_fbdpy->setIdentity( channel ); // In Qt/E 2.3.6
#endif
channel = "QPE/Application/" + channel;
pidChannel = new QCopChannel( channel, this);
connect( pidChannel, SIGNAL(received(const QCString&,const QByteArray&)),
this, SLOT(pidMessage(const QCString&,const QByteArray&)));
processQCopFile();
d->keep_running = d->qcopq.isEmpty();
for (int a=0; a<argc; a++) {
if ( qstrcmp(argv[a],"-preload")==0 ) {
argv[a] = argv[a+1];
a++;
d->preloaded = TRUE;
argc-=1;
} else if ( qstrcmp(argv[a],"-preload-show")==0 ) {
argv[a] = argv[a+1];
a++;
d->preloaded = TRUE;
d->forceshow = TRUE;
argc-=1;
}
}
/* overide stored arguments */
setArgs(argc, argv);
}
#endif
static QPtrDict<void>* inputMethodDict = 0;
static void createInputMethodDict()
{
if ( !inputMethodDict )
inputMethodDict = new QPtrDict<void>;
}
/*!
Returns the currently set hint to the system as to whether
widget \a w has any use for text input methods.
\sa setInputMethodHint() InputMethodHint
*/
QPEApplication::InputMethodHint QPEApplication::inputMethodHint( QWidget * w )
{
if ( inputMethodDict && w )
return ( InputMethodHint ) ( int ) inputMethodDict->find( w );
return Normal;
}
/*!
\enum QPEApplication::InputMethodHint
\value Normal the application sometimes needs text input (the default).
\value AlwaysOff the application never needs text input.
\value AlwaysOn the application always needs text input.
*/
/*!
Hints to the system that widget \a w has use for text input methods
as specified by \a mode.
\sa inputMethodHint() InputMethodHint
*/
void QPEApplication::setInputMethodHint( QWidget * w, InputMethodHint mode )
{
createInputMethodDict();
if ( mode == Normal ) {
inputMethodDict->remove
( w );
}
else {
inputMethodDict->insert( w, ( void* ) mode );
}
}
class HackDialog : public QDialog
{
public:
void acceptIt()
{
accept();
}
void rejectIt()
{
reject();
}
};
void QPEApplication::mapToDefaultAction( QWSKeyEvent * ke, int key )
{
// specialised actions for certain widgets. May want to
// add more stuff here.
if ( activePopupWidget() && activePopupWidget() ->inherits( "QListBox" )
&& activePopupWidget() ->parentWidget()
&& activePopupWidget() ->parentWidget() ->inherits( "QComboBox" ) )
key = Qt::Key_Return;
if ( activePopupWidget() && activePopupWidget() ->inherits( "QPopupMenu" ) )
key = Qt::Key_Return;
#ifdef QWS
ke->simpleData.keycode = key;
#endif
}
/*!
\internal
*/
#ifdef QWS
bool QPEApplication::qwsEventFilter( QWSEvent * e )
{
if ( !d->notbusysent && e->type == QWSEvent::Focus ) {
if ( qApp->type() != QApplication::GuiServer ) {
QCopEnvelope e( "QPE/System", "notBusy(QString)" );
e << d->appName;
}
d->notbusysent = TRUE;
}
if ( type() == GuiServer ) {
switch ( e->type ) {
case QWSEvent::Mouse:
if ( e->asMouse() ->simpleData.state && !QWidget::find( e->window() ) )
emit clientMoused();
break;
default:
break;
}
}
if ( e->type == QWSEvent::Key ) {
QWSKeyEvent *ke = ( QWSKeyEvent * ) e;
if ( ke->simpleData.keycode == Qt::Key_F33 ) {
// Use special "OK" key to press "OK" on top level widgets
QWidget * active = activeWindow();
QWidget *popup = 0;
if ( active && active->isPopup() ) {
popup = active;
active = active->parentWidget();
}
if ( active && ( int ) active->winId() == ke->simpleData.window &&
!active->testWFlags( WStyle_Customize | WType_Popup | WType_Desktop ) ) {
if ( ke->simpleData.is_press ) {
if ( popup )
popup->close();
if ( active->inherits( "QDialog" ) ) {
HackDialog * d = ( HackDialog * ) active;
d->acceptIt();
return TRUE;
}
else if ( ( ( HackWidget * ) active ) ->needsOk() ) {
QSignal s;
s.connect( active, SLOT( accept() ) );
s.activate();
}
else {
// do the same as with the select key: Map to the default action of the widget:
mapToDefaultAction( ke, Qt::Key_Return );
}
}
}
}
else if ( ke->simpleData.keycode == Qt::Key_F30 ) {
// Use special "select" key to do whatever default action a widget has
mapToDefaultAction( ke, Qt::Key_Space );
}
else if ( ke->simpleData.keycode == Qt::Key_Escape &&
ke->simpleData.is_press ) {
// Escape key closes app if focus on toplevel
QWidget * active = activeWindow();
if ( active && active->testWFlags( WType_TopLevel ) &&
( int ) active->winId() == ke->simpleData.window &&
!active->testWFlags( WStyle_Dialog | WStyle_Customize | WType_Popup | WType_Desktop ) ) {
if ( active->inherits( "QDialog" ) ) {
HackDialog * d = ( HackDialog * ) active;
d->rejectIt();
return TRUE;
} else /*if ( strcmp( argv() [ 0 ], "embeddedkonsole" ) != 0 )*/ {
active->close();
}
}
}
else if ( ke->simpleData.keycode >= Qt::Key_F1 && ke->simpleData.keycode <= Qt::Key_F29 ) {
// this should be if ( ODevice::inst ( )-> buttonForKeycode ( ... ))
// but we cannot access libopie function within libqpe :(
QWidget * active = activeWindow ( );
if ( active && ((int) active-> winId ( ) == ke-> simpleData.window )) {
if ( d-> kbgrabbed ) { // we grabbed the keyboard
QChar ch ( ke-> simpleData.unicode );
QKeyEvent qke ( ke-> simpleData. is_press ? QEvent::KeyPress : QEvent::KeyRelease,
ke-> simpleData.keycode,
ch. latin1 ( ),
ke-> simpleData.modifiers,
QString ( ch ),
ke-> simpleData.is_auto_repeat, 1 );
QObject *which = QWidget::keyboardGrabber ( );
if ( !which )
which = QApplication::focusWidget ( );
if ( !which )
which = QApplication::activeWindow ( );
if ( !which )
which = qApp;
QApplication::sendEvent ( which, &qke );
}
else { // we didn't grab the keyboard, so send the event to the launcher
QCopEnvelope e ( "QPE/Launcher", "deviceButton(int,int,int)" );
e << int( ke-> simpleData.keycode ) << int( ke-> simpleData. is_press ) << int( ke-> simpleData.is_auto_repeat );
}
}
return true;
}
}
if ( e->type == QWSEvent::Focus ) {
QWSFocusEvent * fe = ( QWSFocusEvent* ) e;
if ( !fe->simpleData.get_focus ) {
QWidget * active = activeWindow();
while ( active && active->isPopup() ) {
active->close();
active = activeWindow();
}
}
else {
// make sure our modal widget is ALWAYS on top
QWidget *topm = activeModalWidget();
if ( topm && static_cast<int>( topm->winId() ) != fe->simpleData.window) {
topm->raise();
}
}
if ( fe->simpleData.get_focus && inputMethodDict ) {
InputMethodHint m = inputMethodHint( QWidget::find( e->window() ) );
if ( m == AlwaysOff )
Global::hideInputMethod();
if ( m == AlwaysOn )
Global::showInputMethod();
}
}
return QApplication::qwsEventFilter( e );
}
#endif
/*!
Destroys the QPEApplication.
*/
QPEApplication::~QPEApplication()
{
ungrabKeyboard();
#if defined(Q_WS_QWS) && !defined(QT_NO_COP)
// Need to delete QCopChannels early, since the display will
// be gone by the time we get to ~QObject().
delete sysChannel;
delete pidChannel;
#endif
#ifdef OPIE_WITHROHFEEDBACK
if( d->RoH )
delete d->RoH;
#endif
delete d;
}
/*!
Returns <tt>$OPIEDIR/</tt>.
*/
QString QPEApplication::qpeDir()
{
QString base, dir;
if (getenv( "OPIEDIR" ))
base = QString(getenv("OPIEDIR")).stripWhiteSpace();
if ( !base.isNull() && (base.length() > 0 )){
#ifdef Q_OS_WIN32
QString temp(base);
if (temp[(int)temp.length()-1] != QDir::separator())
temp.append(QDir::separator());
dir = temp;
#else
dir = QString( base ) + "/";
#endif
}else{
dir = QString( ".." ) + QDir::separator();
}
return dir;
}
/*!
Returns the user's current Document directory. There is a trailing "/".
.. well, it does now,, and there's no trailing '/'
*/
QString QPEApplication::documentDir()
{
const char* base = getenv( "HOME");
if ( base )
return QString( base ) + "/Documents";
return QString( "../Documents" );
}
static int deforient = -1;
/*!
\internal
*/
int QPEApplication::defaultRotation()
{
if ( deforient < 0 ) {
QString d = getenv( "QWS_DISPLAY" );
if ( d.contains( "Rot90" ) ) {
deforient = 90;
}
else if ( d.contains( "Rot180" ) ) {
deforient = 180;
}
else if ( d.contains( "Rot270" ) ) {
deforient = 270;
}
else {
deforient = 0;
}
}
return deforient;
}
/*!
\internal
*/
void QPEApplication::setDefaultRotation( int r )
{
if ( qApp->type() == GuiServer ) {
deforient = r;
int j = 0;
QCString old = getenv( "QWS_DISPLAY" ) ? getenv( "QWS_DISPLAY" ) : "Transformed";
QString driver( old.left( ( ( j = old.find( ':' ) ) >= 0 ) ? j : old.size() ).data() );
setenv( "QWS_DISPLAY", QString( "%1:Rot%2:0" ).arg(driver).arg( r ).latin1(), 1 );
Config config("qpe");
config.setGroup( "Rotation" );
config.writeEntry( "Rot", r );
}
else {
#ifndef QT_NO_COP
{ QCopEnvelope e( "QPE/System", "setDefaultRotation(int)" );
e << r;
}
#endif
}
}
#include <qgfx_qws.h>
#include <qwindowsystem_qws.h>
#if QT_VERSION > 236
extern void qws_clearLoadedFonts();
#endif
void QPEApplication::setCurrentMode( int x, int y, int depth )
{
// Reset the caches
#if QT_VERSION > 236
qws_clearLoadedFonts();
#endif
QPixmapCache::clear();
// Change the screen mode
qt_screen->setMode(x, y, depth);
if ( qApp->type() == GuiServer ) {
#if QT_VERSION > 236
// Reconfigure the GuiServer
qwsServer->beginDisplayReconfigure();
qwsServer->endDisplayReconfigure();
#endif
// Get all the running apps to reset
QCopEnvelope env( "QPE/System", "reset()" );
}
}
void QPEApplication::reset() {
// Reconnect to the screen
qt_screen->disconnect();
qt_screen->connect( QString::null );
// Redraw everything
applyStyle();
}
#if (QT_VERSION < 238) && defined Q_OS_MACX
bool qt_left_hand_scrollbars = false;
#else
extern bool qt_left_hand_scrollbars QPE_WEAK_SYMBOL;
#endif
/*!
\internal
*/
void QPEApplication::applyStyle()
{
Config config( "qpe" );
config.setGroup( "Appearance" );
#if QT_VERSION > 233
// Widget style
QString style = config.readEntry( "Style", "FlatStyle" );
internalSetStyle ( style );
// Colors - from /etc/colors/Liquid.scheme
QColor bgcolor( config.readEntry( "Background", "#E0E0E0" ) );
QColor btncolor( config.readEntry( "Button", "#96c8fa" ) );
QPalette pal( btncolor, bgcolor );
QString color = config.readEntry( "Highlight", "#73adef" );
pal.setColor( QColorGroup::Highlight, QColor( color ) );
color = config.readEntry( "HighlightedText", "#FFFFFF" );
pal.setColor( QColorGroup::HighlightedText, QColor( color ) );
color = config.readEntry( "Text", "#000000" );
pal.setColor( QColorGroup::Text, QColor( color ) );
color = config.readEntry( "ButtonText", "#000000" );
pal.setColor( QPalette::Active, QColorGroup::ButtonText, QColor( color ) );
color = config.readEntry( "Base", "#FFFFFF" );
pal.setColor( QColorGroup::Base, QColor( color ) );
pal.setColor( QPalette::Disabled, QColorGroup::Text,
pal.color( QPalette::Active, QColorGroup::Background ).dark() );
setPalette( pal, TRUE );
// Set the ScrollBar on the 'right' side but only if the weak symbol is present
if (&qt_left_hand_scrollbars )
qt_left_hand_scrollbars = config.readBoolEntry( "LeftHand", false );
// Window Decoration
QString dec = config.readEntry( "Decoration", "Flat" );
if ( dec != d->decorationName ) {
qwsSetDecoration( new QPEDecoration( dec ) );
d->decorationName = dec;
}
// Font
QString ff = config.readEntry( "FontFamily", font().family() );
int fs = config.readNumEntry( "FontSize", font().pointSize() );
setFont ( QFont ( ff, fs ), true );
#endif
}
void QPEApplication::systemMessage( const QCString& msg, const QByteArray& data )
{
#ifdef Q_WS_QWS
QDataStream stream( data, IO_ReadOnly );
if ( msg == "applyStyle()" ) {
applyStyle();
}
else if ( msg == "toggleApplicationMenu()" ) {
QWidget *active = activeWindow ( );
if ( active ) {
QPEMenuToolFocusManager *man = QPEMenuToolFocusManager::manager ( );
bool oldactive = man-> isActive ( );
man-> setActive( !man-> isActive() );
if ( !oldactive && !man-> isActive ( )) { // no menubar to toggle -> try O-Menu
QCopEnvelope e ( "QPE/TaskBar", "toggleStartMenu()" );
}
}
}
else if ( msg == "setDefaultRotation(int)" ) {
if ( type() == GuiServer ) {
int r;
stream >> r;
setDefaultRotation( r );
}
}
else if ( msg == "setCurrentMode(int,int,int)" ) { // Added: 2003-06-11 by Tim Ansell <mithro@mithis.net>
if ( type() == GuiServer ) {
int x, y, depth;
stream >> x;
stream >> y;
stream >> depth;
setCurrentMode( x, y, depth );
}
}
else if ( msg == "reset()" ) {
if ( type() != GuiServer )
reset();
}
else if ( msg == "setCurrentRotation(int)" ) {
int r;
stream >> r;
setCurrentRotation( r );
}
else if ( msg == "shutdown()" ) {
if ( type() == GuiServer )
shutdown();
}
else if ( msg == "quit()" ) {
if ( type() != GuiServer )
tryQuit();
}
else if ( msg == "forceQuit()" ) {
if ( type() != GuiServer )
quit();
}
else if ( msg == "restart()" ) {
if ( type() == GuiServer )
restart();
}
else if ( msg == "language(QString)" ) {
if ( type() == GuiServer ) {
QString l;
stream >> l;
QString cl = getenv( "LANG" );
if ( cl != l ) {
if ( l.isNull() )
unsetenv( "LANG" );
else
setenv( "LANG", l.latin1(), 1 );
restart();
}
}
}
else if ( msg == "timeChange(QString)" ) {
QString t;
stream >> t;
if ( t.isNull() )
unsetenv( "TZ" );
else
setenv( "TZ", t.latin1(), 1 );
// emit the signal so everyone else knows...
emit timeChanged();
}
else if ( msg == "addAlarm(QDateTime,QCString,QCString,int)" ) {
if ( type() == GuiServer ) {
QDateTime when;
QCString channel, message;
int data;
stream >> when >> channel >> message >> data;
AlarmServer::addAlarm( when, channel, message, data );
}
}
else if ( msg == "deleteAlarm(QDateTime,QCString,QCString,int)" ) {
if ( type() == GuiServer ) {
QDateTime when;
QCString channel, message;
int data;
stream >> when >> channel >> message >> data;
AlarmServer::deleteAlarm( when, channel, message, data );
}
}
else if ( msg == "clockChange(bool)" ) {
int tmp;
stream >> tmp;
emit clockChanged( tmp );
}
else if ( msg == "weekChange(bool)" ) {
int tmp;
stream >> tmp;
emit weekChanged( tmp );
}
else if ( msg == "setDateFormat(DateFormat)" ) {
DateFormat tmp;
stream >> tmp;
emit dateFormatChanged( tmp );
}
else if ( msg == "setVolume(int,int)" ) {
int t, v;
stream >> t >> v;
setVolume( t, v );
emit volumeChanged( muted );
}
else if ( msg == "volumeChange(bool)" ) {
stream >> muted;
setVolume();
emit volumeChanged( muted );
}
else if ( msg == "setMic(int,int)" ) { // Added: 2002-02-08 by Jeremy Cowgar <jc@cowgar.com>
int t, v;
stream >> t >> v;
setMic( t, v );
emit micChanged( micMuted );
}
else if ( msg == "micChange(bool)" ) { // Added: 2002-02-08 by Jeremy Cowgar <jc@cowgar.com>
stream >> micMuted;
setMic();
emit micChanged( micMuted );
}
else if ( msg == "setBass(int,int)" ) { // Added: 2002-12-13 by Maximilian Reiss <harlekin@handhelds.org>
int t, v;
stream >> t >> v;
setBass( t, v );
}
else if ( msg == "bassChange(bool)" ) { // Added: 2002-12-13 by Maximilian Reiss <harlekin@handhelds.org>
setBass();
}
else if ( msg == "setTreble(int,int)" ) { // Added: 2002-12-13 by Maximilian Reiss <harlekin@handhelds.org>
int t, v;
stream >> t >> v;
setTreble( t, v );
}
else if ( msg == "trebleChange(bool)" ) { // Added: 2002-12-13 by Maximilian Reiss <harlekin@handhelds.org>
setTreble();
} else if ( msg == "getMarkedText()" ) {
if ( type() == GuiServer ) {
const ushort unicode = 'C'-'@';
const int scan = Key_C;
qwsServer->processKeyEvent( unicode, scan, ControlButton, TRUE, FALSE );
qwsServer->processKeyEvent( unicode, scan, ControlButton, FALSE, FALSE );
}
} else if ( msg == "newChannel(QString)") {
QString myChannel = "QPE/Application/" + d->appName;
QString channel;
stream >> channel;
if (channel == myChannel) {
processQCopFile();
d->sendQCopQ();
}
}
#endif
}
/*!
\internal
*/
bool QPEApplication::raiseAppropriateWindow()
{
bool r=FALSE;
// 1. Raise the main widget
QWidget *top = d->qpe_main_widget;
if ( !top ) top = mainWidget();
if ( top && d->keep_running ) {
if ( top->isVisible() )
r = TRUE;
else if (d->preloaded) {
// We are preloaded and not visible.. pretend we just started..
#ifndef QT_NO_COP
QCopEnvelope e("QPE/System", "fastAppShowing(QString)");
e << d->appName;
#endif
}
d->show_mx(top,d->nomaximize, d->appName);
top->raise();
}
QWidget *topm = activeModalWidget();
// 2. Raise any parentless widgets (except top and topm, as they
// are raised before and after this loop). Order from most
// recently raised as deepest to least recently as top, so
// that repeated calls cycle through widgets.
QWidgetList *list = topLevelWidgets();
if ( list ) {
bool foundlast = FALSE;
QWidget* topsub = 0;
if ( d->lastraised ) {
for (QWidget* w = list->first(); w; w = list->next()) {
if ( !w->parentWidget() && w != topm && w->isVisible() && !w->isDesktop() ) {
if ( w == d->lastraised )
foundlast = TRUE;
if ( foundlast ) {
w->raise();
topsub = w;
}
}
}
}
for (QWidget* w = list->first(); w; w = list->next()) {
if ( !w->parentWidget() && w != topm && w->isVisible() && !w->isDesktop() ) {
if ( w == d->lastraised )
break;
w->raise();
topsub = w;
}
}
d->lastraised = topsub;
delete list;
}
// 3. Raise the active modal widget.
if ( topm ) {
topm->show();
topm->raise();
// If we haven't already handled the fastAppShowing message
if (!top && d->preloaded) {
#ifndef QT_NO_COP
QCopEnvelope e("QPE/System", "fastAppShowing(QString)");
e << d->appName;
#endif
}
r = FALSE;
}
return r;
}
void QPEApplication::pidMessage( const QCString& msg, const QByteArray& data)
{
#ifdef Q_WS_QWS
if ( msg == "quit()" ) {
tryQuit();
}
else if ( msg == "quitIfInvisible()" ) {
if ( d->qpe_main_widget && !d->qpe_main_widget->isVisible() )
quit();
}
else if ( msg == "close()" ) {
hideOrQuit();
}
else if ( msg == "disablePreload()" ) {
d->preloaded = FALSE;
d->keep_running = TRUE;
/* so that quit will quit */
}
else if ( msg == "enablePreload()" ) {
if (d->qpe_main_widget)
d->preloaded = TRUE;
d->keep_running = TRUE;
/* so next quit won't quit */
}
else if ( msg == "raise()" ) {
d->keep_running = TRUE;
d->notbusysent = FALSE;
raiseAppropriateWindow();
// Tell the system we're still chugging along...
QCopEnvelope e("QPE/System", "appRaised(QString)");
e << d->appName;
}
else if ( msg == "flush()" ) {
emit flush();
// we need to tell the desktop
QCopEnvelope e( "QPE/Desktop", "flushDone(QString)" );
e << d->appName;
}
else if ( msg == "reload()" ) {
emit reload();
}
else if ( msg == "setDocument(QString)" ) {
d->keep_running = TRUE;
QDataStream stream( data, IO_ReadOnly );
QString doc;
stream >> doc;
QWidget *mw = mainWidget();
if ( !mw )
mw = d->qpe_main_widget;
if ( mw )
Global::setDocument( mw, doc );
} else if ( msg == "QPEProcessQCop()" ) {
processQCopFile();
d->sendQCopQ();
}else
{
bool p = d->keep_running;
d->keep_running = FALSE;
emit appMessage( msg, data);
if ( d->keep_running ) {
d->notbusysent = FALSE;
raiseAppropriateWindow();
if ( !p ) {
// Tell the system we're still chugging along...
#ifndef QT_NO_COP
QCopEnvelope e("QPE/System", "appRaised(QString)");
e << d->appName;
#endif
}
}
if ( p )
d->keep_running = p;
}
#endif
}
/*!
Sets widget \a mw as the mainWidget() and shows it. For small windows,
consider passing TRUE for \a nomaximize rather than the default FALSE.
\sa showMainDocumentWidget()
*/
void QPEApplication::showMainWidget( QWidget* mw, bool nomaximize )
{
// setMainWidget(mw); this breaks FastLoading because lastWindowClose() would quit
d->show(mw, nomaximize );
}
/*!
Sets widget \a mw as the mainWidget() and shows it. For small windows,
consider passing TRUE for \a nomaximize rather than the default FALSE.
This calls designates the application as
a \link docwidget.html document-oriented\endlink application.
The \a mw widget \e must have this slot: setDocument(const QString&).
\sa showMainWidget()
*/
void QPEApplication::showMainDocumentWidget( QWidget* mw, bool nomaximize )
{
- if ( mw && argc() == 2 )
+ if ( mw ) {
+ if ( argc() == 2 )
Global::setDocument( mw, QString::fromUtf8(argv()[1]) );
-
-// setMainWidget(mw); see above
d->show(mw, nomaximize );
}
+}
/*!
If an application is started via a \link qcop.html QCop\endlink
message, the application will process the \link qcop.html
QCop\endlink message and then quit. If the application calls this
function while processing a \link qcop.html QCop\endlink message,
after processing its outstanding \link qcop.html QCop\endlink
messages the application will start 'properly' and show itself.
\sa keepRunning()
*/
void QPEApplication::setKeepRunning()
{
if ( qApp && qApp->inherits( "QPEApplication" ) ) {
QPEApplication * qpeApp = ( QPEApplication* ) qApp;
qpeApp->d->keep_running = TRUE;
}
}
/*!
Returns TRUE if the application will quit after processing the
current list of qcop messages; otherwise returns FALSE.
\sa setKeepRunning()
*/
bool QPEApplication::keepRunning() const
{
return d->keep_running;
}
/*!
\internal
*/
void QPEApplication::internalSetStyle( const QString &style )
{
#if QT_VERSION >= 0x030000
if ( style == "QPE" ) {
setStyle( new QPEStyle );
}
else {
QStyle *s = QStyleFactory::create( style );
if ( s )
setStyle( s );
}
#else
if ( style == "Windows" ) {
setStyle( new QWindowsStyle );
}
else if ( style == "QPE" ) {
setStyle( new QPEStyle );
}
else if ( style == "Light" ) {
setStyle( new LightStyle );
}
#ifndef QT_NO_STYLE_PLATINUM
else if ( style == "Platinum" ) {
setStyle( new QPlatinumStyle );
}
#endif
#ifndef QT_NO_STYLE_MOTIF
else if ( style == "Motif" ) {
setStyle( new QMotifStyle );
}
#endif
#ifndef QT_NO_STYLE_MOTIFPLUS
else if ( style == "MotifPlus" ) {
setStyle( new QMotifPlusStyle );
}
#endif
else {
QStyle *sty = 0;
QString path = QPEApplication::qpeDir ( ) + "plugins/styles/";
#ifdef Q_OS_MACX
if ( style. find ( ".dylib" ) > 0 )
path += style;
else
path = path + "lib" + style. lower ( ) + ".dylib"; // compatibility
#else
if ( style. find ( ".so" ) > 0 )
path += style;
else
path = path + "lib" + style. lower ( ) + ".so"; // compatibility
#endif
static QLibrary *lastlib = 0;
static StyleInterface *lastiface = 0;
QLibrary *lib = new QLibrary ( path );
StyleInterface *iface = 0;
if (( lib-> queryInterface ( IID_Style, ( QUnknownInterface ** ) &iface ) == QS_OK ) && iface )
sty = iface-> style ( );
if ( sty ) {
setStyle ( sty );
if ( lastiface )
lastiface-> release ( );
lastiface = iface;
if ( lastlib ) {
lastlib-> unload ( );
delete lastlib;
}
lastlib = lib;
}
else {
if ( iface )
iface-> release ( );
delete lib;
setStyle ( new LightStyle ( ));
}
}
#endif
}
/*!
\internal
*/
void QPEApplication::prepareForTermination( bool willrestart )
{
if ( willrestart ) {
QLabel *lblWait = new QLabel( tr( "Please wait..." ), 0, "wait hack", QWidget::WStyle_Customize |
QWidget::WStyle_NoBorder | QWidget::WStyle_Tool );
lblWait->setAlignment( QWidget::AlignCenter );
lblWait->show();
lblWait->showMaximized();
}
{ QCopEnvelope envelope( "QPE/System", "forceQuit()" );
}
processEvents(); // ensure the message goes out.
}
/*!
\internal
*/
void QPEApplication::shutdown()
{
// Implement in server's QPEApplication subclass
}
/*!
\internal
*/
void QPEApplication::restart()
{
// Implement in server's QPEApplication subclass
}
static QPtrDict<void>* stylusDict = 0;
static void createDict()
{
if ( !stylusDict )
stylusDict = new QPtrDict<void>;
}
/*!
Returns the current StylusMode for widget \a w.
\sa setStylusOperation() StylusMode
*/
QPEApplication::StylusMode QPEApplication::stylusOperation( QWidget* w )
{
if ( stylusDict )
return ( StylusMode ) ( int ) stylusDict->find( w );
return LeftOnly;
}
/*!
\enum QPEApplication::StylusMode
\value LeftOnly the stylus only generates LeftButton
events (the default).
\value RightOnHold the stylus generates RightButton events
if the user uses the press-and-hold gesture.
\sa setStylusOperation() stylusOperation()
*/
/*!
Causes widget \a w to receive mouse events according to the stylus
\a mode.
\sa stylusOperation() StylusMode
*/
void QPEApplication::setStylusOperation( QWidget * w, StylusMode mode )
{
createDict();
if ( mode == LeftOnly ) {
stylusDict->remove
( w );
w->removeEventFilter( qApp );
}
else {
stylusDict->insert( w, ( void* ) mode );
connect( w, SIGNAL( destroyed() ), qApp, SLOT( removeSenderFromStylusDict() ) );
w->installEventFilter( qApp );
}
}
/*!
\reimp
*/
bool QPEApplication::eventFilter( QObject *o, QEvent *e )
{
if ( !o->isWidgetType() )
return FALSE;
if ( stylusDict && e->type() >= QEvent::MouseButtonPress && e->type() <= QEvent::MouseMove ) {
QMouseEvent * me = ( QMouseEvent* ) e;
StylusMode mode = (StylusMode)(int)stylusDict->find(o);
switch (mode) {
case RightOnHold:
switch ( me->type() ) {
case QEvent::MouseButtonPress:
if ( me->button() == LeftButton ) {
static long Pref = 500; // #### pref.
d->presswidget = (QWidget*)o;
d->presspos = me->pos();
d->rightpressed = FALSE;
#ifdef OPIE_WITHROHFEEDBACK
if( ! d->RoH )
d->RoH = new Opie::Internal::RoHFeedback;
d->RoH->init( me->globalPos(), d->presswidget );
Pref = d->RoH->delay();
#endif
if (!d->presstimer )
d->presstimer = startTimer( Pref ); // #### pref.
}
break;
case QEvent::MouseMove:
if (d->presstimer && (me->pos() - d->presspos).manhattanLength() > 8) {
killTimer(d->presstimer);
#ifdef OPIE_WITHROHFEEDBACK
d->RoH->stop();
#endif
d->presstimer = 0;
}
break;
case QEvent::MouseButtonRelease:
if ( me->button() == LeftButton ) {
if ( d->presstimer ) {
killTimer(d->presstimer);
#ifdef OPIE_WITHROHFEEDBACK
d->RoH->stop( );
#endif
d->presstimer = 0;
}
if ( d->rightpressed && d->presswidget ) {
printf( "Send ButtonRelease\n" );
// Right released
postEvent( d->presswidget,
new QMouseEvent( QEvent::MouseButtonRelease, me->pos(),
RightButton, LeftButton + RightButton ) );
// Left released, off-widget
postEvent( d->presswidget,
new QMouseEvent( QEvent::MouseMove, QPoint( -1, -1),
LeftButton, LeftButton ) );
postEvent( d->presswidget,
new QMouseEvent( QEvent::MouseButtonRelease, QPoint( -1, -1),
LeftButton, LeftButton ) );
d->rightpressed = FALSE;
return TRUE; // don't send the real Left release
}
}
break;
default:
break;
}
break;
default:
;
}
}
else if ( e->type() == QEvent::KeyPress || e->type() == QEvent::KeyRelease ) {
QKeyEvent *ke = (QKeyEvent *)e;
if ( ke->key() == Key_Enter ) {
if ( o->isA( "QRadioButton" ) || o->isA( "QCheckBox" ) ) {
postEvent( o, new QKeyEvent( e->type(), Key_Space, ' ',
ke->state(), " ", ke->isAutoRepeat(), ke->count() ) );
return TRUE;
}
}
}
return FALSE;
}
/*!
\reimp
*/
void QPEApplication::timerEvent( QTimerEvent *e )
{
if ( e->timerId() == d->presstimer && d->presswidget ) {
// Right pressed
postEvent( d->presswidget,
new QMouseEvent( QEvent::MouseButtonPress, d->presspos,
RightButton, LeftButton ) );
killTimer( d->presstimer );
d->presstimer = 0;
d->rightpressed = TRUE;
#ifdef OPIE_WITHROHFEEDBACK
d->RoH->stop();
#endif
}
}
void QPEApplication::removeSenderFromStylusDict()
{
stylusDict->remove
( ( void* ) sender() );
if ( d->presswidget == sender() )
d->presswidget = 0;
}
/*!
\internal
*/
bool QPEApplication::keyboardGrabbed() const
{
return d->kbgrabbed;
}
/*!
Reverses the effect of grabKeyboard(). This is called automatically
on program exit.
*/
void QPEApplication::ungrabKeyboard()
{
((QPEApplication *) qApp )-> d-> kbgrabbed = false;
}
/*!
Grabs the physical keyboard keys, e.g. the application's launching
keys. Instead of launching applications when these keys are pressed
the signals emitted are sent to this application instead. Some games
programs take over the launch keys in this way to make interaction
easier.
\sa ungrabKeyboard()
*/
void QPEApplication::grabKeyboard()
{
((QPEApplication *) qApp )-> d-> kbgrabbed = true;
}
/*!
\reimp
*/
int QPEApplication::exec()
{
d->qcopQok = true;
#ifndef QT_NO_COP
d->sendQCopQ();
if ( !d->keep_running )
processEvents(); // we may have received QCop messages in the meantime.
#endif
if ( d->keep_running )
//|| d->qpe_main_widget && d->qpe_main_widget->isVisible() )
return QApplication::exec();
#ifndef QT_NO_COP
{
QCopEnvelope e( "QPE/System", "closing(QString)" );
e << d->appName;
}
#endif
processEvents();
return 0;
}
/*!
\internal
External request for application to quit. Quits if possible without
loosing state.
*/
void QPEApplication::tryQuit()
{
if ( activeModalWidget() )
return ; // Inside modal loop or konsole. Too hard to save state.
#ifndef QT_NO_COP
{
QCopEnvelope e( "QPE/System", "closing(QString)" );
e << d->appName;
}
#endif
if ( d->keep_running )
d->store_widget_rect(d->qpe_main_widget, d->appName);
processEvents();
quit();
}
/*!
\internal
User initiated quit. Makes the window 'Go Away'. If preloaded this means
hiding the window. If not it means quitting the application.
As this is user initiated we don't need to check state.
*/
void QPEApplication::hideOrQuit()
{
if ( d->keep_running )
d->store_widget_rect(d->qpe_main_widget, d->appName);
processEvents();
// If we are a preloaded application we don't actually quit, so emit
// a System message indicating we're quasi-closing.
if ( d->preloaded && d->qpe_main_widget )
#ifndef QT_NO_COP
{
QCopEnvelope e("QPE/System", "fastAppHiding(QString)" );
e << d->appName;
d->qpe_main_widget->hide();
}
#endif
else
quit();
}
bool QPEApplication::isSaveWindowsPos()
{
return saveWindowsPos;
}
#if (__GNUC__ > 2 ) && !defined(_OS_MACX_)
extern "C" void __cxa_pure_virtual();
void __cxa_pure_virtual()
{
fprintf( stderr, "Pure virtual called\n");
abort();
}
#endif
#if defined(OPIE_NEW_MALLOC)
// The libraries with the skiff package (and possibly others) have
// completely useless implementations of builtin new and delete that
// use about 50% of your CPU. Here we revert to the simple libc
// functions.
void* operator new[]( size_t size )
{
return malloc( size );
}
void* operator new( size_t size )
{
return malloc( size );
}
void operator delete[]( void* p )
{
if ( p )
free( p );
}
void operator delete[]( void* p, size_t /*size*/ )
{
if ( p )
free( p );
}
void operator delete( void* p )
{
if ( p )
free( p );
}
void operator delete( void* p, size_t /*size*/ )
{
if ( p )
free( p );
}
#endif
#if ( QT_VERSION <= 230 ) && !defined(SINGLE_APP)
#include <qwidgetlist.h>
#ifdef QWS
#include <qgfx_qws.h>
extern QRect qt_maxWindowRect;
void qt_setMaxWindowRect(const QRect& r )
{
qt_maxWindowRect = qt_screen->mapFromDevice( r,
qt_screen->mapToDevice( QSize( qt_screen->width(), qt_screen->height() ) ) );
// Re-resize any maximized windows
QWidgetList* l = QApplication::topLevelWidgets();
if ( l ) {
QWidget * w = l->first();
while ( w ) {
if ( w->isVisible() && w->isMaximized() ) {
w->showMaximized();
}
w = l->next();
}
delete l;
}
}
#endif
#endif
diff --git a/noncore/applets/pcmcia/pcmcia.cpp b/noncore/applets/pcmcia/pcmcia.cpp
index 187adc6..c639002 100644
--- a/noncore/applets/pcmcia/pcmcia.cpp
+++ b/noncore/applets/pcmcia/pcmcia.cpp
@@ -1,368 +1,374 @@
/*
                This file is part of the Opie Project
=. (C) 2005 Michael 'Mickey' Lauer <mickey@Vanille.de>
.=l.
           .>+-=
 _;:,     .>    :=|. This program is free software; you can
.> <`_,   >  .   <= redistribute it and/or modify it under
:`=1 )Y*s>-.--   : the terms of the GNU Library General Public
.="- .-=="i,     .._ License as published by the Free Software
 - .   .-<_>     .<> Foundation; either version 2 of the License,
     ._= =}       : or (at your option) any later version.
    .%`+i>       _;_.
    .i_,=:_.      -<s. 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
..}^=.=       =       ; 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.
*/
#include "pcmcia.h"
#include "configdialog.h"
#include "promptactiondialog.h"
/* OPIE */
#include <opie2/odebug.h>
#include <opie2/odevice.h>
#include <opie2/oconfig.h>
#include <opie2/oprocess.h>
#include <opie2/opcmciasystem.h>
#include <opie2/oresource.h>
#include <opie2/otaskbarapplet.h>
#include <qpe/applnk.h>
#include <qpe/global.h>
#include <qpe/resource.h>
using namespace Opie::Core;
using namespace Opie::Ui;
/* QT */
#include <qcombobox.h>
#include <qcopchannel_qws.h>
#include <qpainter.h>
#include <qfile.h>
#include <qtextstream.h>
#include <qmessagebox.h>
#include <qsound.h>
#include <qtimer.h>
/* STD */
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <fcntl.h>
#if defined(_OS_LINUX_) || defined(Q_OS_LINUX)
#include <sys/vfs.h>
#include <mntent.h>
#endif
PcmciaManager::PcmciaManager( QWidget * parent ) : QWidget( parent ), popupMenu( 0 )
{
QCopChannel * pcmciaChannel = new QCopChannel( "QPE/Card", this );
connect( pcmciaChannel,
SIGNAL( received(const QCString&,const QByteArray&) ), this,
SLOT( cardMessage(const QCString&,const QByteArray&) ) );
setFocusPolicy( NoFocus );
setFixedWidth ( AppLnk::smallIconSize() );
setFixedHeight ( AppLnk::smallIconSize() );
pm = Opie::Core::OResource::loadPixmap( "pcmcia", Opie::Core::OResource::SmallIcon );
configuring = false;
QCopChannel *channel = new QCopChannel( "QPE/System", this );
connect( channel, SIGNAL(received(const QCString&,const QByteArray&)),
this, SLOT(handleSystemChannel(const QCString&,const QByteArray&)) );
}
PcmciaManager::~PcmciaManager()
{
}
void PcmciaManager::handleSystemChannel( const QCString&msg, const QByteArray& )
{
if ( msg == "returnFromSuspend()" )
{
if ( !OPcmciaSystem::instance()->cardCount() ) return;
OPcmciaSystem* sys = OPcmciaSystem::instance();
OPcmciaSystem::CardIterator it = sys->iterator();
while ( it.current() )
{
if ( !it.current()->isEmpty() )
{
executeAction( it.current(), "resume" );
}
++it;
}
}
}
void PcmciaManager::popUp( QString message, QString icon )
{
if ( !popupMenu)
{
popupMenu = new QPopupMenu( this );
popupMenu->setFocusPolicy( QWidget::NoFocus );
}
popupMenu->clear();
if ( icon.isEmpty() ) {
popupMenu->insertItem( message, 0 );
} else {
popupMenu->insertItem( QIconSet( Opie::Core::OResource::loadPixmap( icon, Opie::Core::OResource::SmallIcon ) ),
message, 0 );
}
QPoint p = mapToGlobal( QPoint( 0, 0 ) );
QSize s = popupMenu->sizeHint();
popupMenu->popup( QPoint( p.x() + ( width() / 2 ) - ( s.width() / 2 ),
p.y() - s.height() ), 0 );
QTimer::singleShot( 2000, this, SLOT( popupTimeout() ) );
}
void PcmciaManager::popupTimeout()
{
popupMenu->hide();
}
enum { EJECT, INSERT, SUSPEND, RESUME, RESET, CONFIGURE, ACTIVATE };
static const char* actionText[] = { "eject", "insert", "suspend", "resum", "resett", "configur", "activat" };
void PcmciaManager::mousePressEvent( QMouseEvent* )
{
QPopupMenu* menu = new QPopupMenu( this );
QStringList cmd;
bool execute = true;
OPcmciaSystem* sys = OPcmciaSystem::instance();
sys->synchronize();
OPcmciaSystem::CardIterator it = sys->iterator();
if ( !sys->count() ) return;
int i = 0;
while ( it.current() )
{
QPopupMenu* submenu = new QPopupMenu( menu );
submenu->insertItem( "&Eject", EJECT+i*100 );
submenu->insertItem( "&Insert", INSERT+i*100 );
submenu->insertItem( "&Suspend", SUSPEND+i*100 );
submenu->insertItem( "&Resume", RESUME+i*100 );
submenu->insertItem( "Rese&t", RESET+i*100 );
submenu->insertItem( "&Configure", CONFIGURE+i*100 );
bool isSuspended = it.current()->isSuspended();
bool isEmpty = it.current()->isEmpty();
submenu->setItemEnabled( EJECT+i*100, !isEmpty );
submenu->setItemEnabled( INSERT+i*100, isEmpty );
submenu->setItemEnabled( SUSPEND+i*100, !isEmpty && !isSuspended );
submenu->setItemEnabled( RESUME+i*100, !isEmpty && isSuspended );
submenu->setItemEnabled( RESET+i*100, !isEmpty && !isSuspended );
submenu->setItemEnabled( CONFIGURE+i*100, !isEmpty && !configuring );
connect( submenu, SIGNAL(activated(int)), this, SLOT(userCardAction(int)) );
menu->insertItem( tr( "%1: %2" ).arg( i++ ).arg( it.current()->identity() ), submenu, 1 );
++it;
}
QPoint p = mapToGlobal( QPoint( 0, 0 ) );
QSize s = menu->sizeHint();
int opt = menu->exec( QPoint( p.x() + ( width() / 2 ) - ( s.width() / 2 ), p.y() - s.height() ), 0 );
qDebug( "pcmcia: menu result = %d", opt );
delete menu;
}
void PcmciaManager::cardMessage( const QCString & msg, const QByteArray & )
{
odebug << "PcmciaManager::cardMessage( '" << msg << "' )" << oendl;
if ( msg != "stabChanged()" ) return;
/* check if a previously unknown card has been inserted */
OPcmciaSystem::instance()->synchronize();
if ( !OPcmciaSystem::instance()->cardCount() ) return;
OConfig cfg( "PCMCIA" );
cfg.setGroup( "Global" );
int nCards = cfg.readNumEntry( "nCards", 0 );
OPcmciaSystem* sys = OPcmciaSystem::instance();
OPcmciaSystem::CardIterator it = sys->iterator();
bool newCard = true;
OPcmciaSocket* theCard = 0;
while ( it.current() && newCard )
{
if ( it.current()->isEmpty() )
{
odebug << "pcmcia: skipping empty card in socket " << it.current()->number() << oendl;
++it;
continue;
}
else
{
theCard = it.current();
QString cardName = theCard->productIdentity();
for ( int i = 0; i < nCards; ++i )
{
QString cardSection = QString( "Card_%1" ).arg( i );
cfg.setGroup( cardSection );
QString name = cfg.readEntry( "name" );
odebug << "pcmcia: comparing card '" << cardName << "' with known card '" << name << "'" << oendl;
if ( cardName == name )
{
newCard = false;
odebug << "pcmcia: we have seen this card before" << oendl;
executeAction( theCard, "insert" );
break;
}
}
if ( !newCard ) ++it; else break;
}
}
+
+ if ( !theCard ) {
+ owarn << "pcmcia: Finished working through cards in PCMCIA system but I do not have a valid card handle" << oendl;
+ return;
+ }
+
if ( newCard )
{
odebug << "pcmcia: unconfigured card detected" << oendl;
QString newCardName = theCard->productIdentity();
int result = QMessageBox::information( qApp->desktop(),
tr( "PCMCIA/CF Subsystem" ),
tr( "<qt>You have inserted the card<br/><b>%1</b><br/>This card is not yet configured. Do you want to configure it now?</qt>" ).arg( newCardName ),
tr( "Yes" ), tr( "No" ), 0, 0, 1 );
odebug << "pcmcia: result = " << result << oendl;
if ( result == 0 )
{
configure( theCard );
}
else
{
odebug << "pcmcia: user doesn't want to configure " << newCardName << " now." << oendl;
}
}
else // it's an already configured card
{
odebug << "pcmcia: doing nothing... why do we come here?" << oendl;
}
}
void PcmciaManager::paintEvent( QPaintEvent * )
{
QPainter p( this );
p.drawPixmap( 0, 0, pm );
}
int PcmciaManager::position()
{
return 7;
}
void PcmciaManager::execCommand( const QStringList &strList )
{
}
void PcmciaManager::userCardAction( int action )
{
odebug << "pcmcia: user action on socket " << action / 100 << " requested. action = " << action << oendl;
int socket = action / 100;
int what = action % 100;
bool success = false;
switch ( what )
{
case CONFIGURE:
{
QString insertAction; QString resumeAction; QString driver; QString conf;
configure( OPcmciaSystem::instance()->socket( socket ) );
return;
}
case EJECT: success = OPcmciaSystem::instance()->socket( socket )->eject();
break;
case INSERT: success = OPcmciaSystem::instance()->socket( socket )->insert();
break;
case SUSPEND: success = OPcmciaSystem::instance()->socket( socket )->suspend();
break;
case RESUME: success = OPcmciaSystem::instance()->socket( socket )->resume();
break;
case RESET: success = OPcmciaSystem::instance()->socket( socket )->reset();
break;
case ACTIVATE: success = true;
break;
default: odebug << "pcmcia: not yet implemented" << oendl;
}
if ( success )
{
odebug << tr( "Successfully %1ed card in socket #%2" ).arg( actionText[action] ).arg( socket ) << oendl;
popUp( tr( "Successfully %1ed card in socket #%2" ).arg( actionText[action] ).arg( socket ) );
}
else
{
odebug << tr( "Error while %1ing card in socket #%2" ).arg( actionText[action] ).arg( socket ) << oendl;
popUp( tr( "Error while %1ing card in socket #%2" ).arg( actionText[action] ).arg( socket ) );
}
}
void PcmciaManager::configure( OPcmciaSocket* card )
{
configuring = true;
ConfigDialog dialog( card, qApp->desktop() );
int result = QPEApplication::execDialog( &dialog, false );
configuring = false;
odebug << "pcmcia: configresult = " << result << oendl;
if ( result )
{
dialog.writeConfiguration( card );
}
}
void PcmciaManager::executeAction( Opie::Core::OPcmciaSocket* card, const QString& type )
{
odebug << "pcmcia: performing " << type << " action ..." << oendl;
QString theAction = ConfigDialog::preferredAction( card, type );
int intAction = card->number() * 100;
if ( theAction == "prompt for" )
{
PromptActionDialog dialog( qApp->desktop(), "promptfor", true );
dialog.setCaption( QString( "Choose action for card #%1" ).arg( card->number() ) );
int result = QPEApplication::execDialog( &dialog, true );
odebug << "pcmcia: configresult = " << result << oendl;
if ( result )
{
theAction = dialog.cbAction->currentText();
}
else
{
odebug << "pcmcia: prompted to do nothing" << oendl;
return;
}
}
if ( theAction == "activate" ) intAction += ACTIVATE;
else if ( theAction == "eject" ) intAction += EJECT;
else if ( theAction == "suspend" ) intAction += SUSPEND;
else
{
owarn << "pcmcia: action '" << theAction << "' not known. Huh?" << oendl;
return;
}
userCardAction( intAction );
}
EXPORT_OPIE_APPLET_v1( PcmciaManager )
diff --git a/noncore/apps/checkbook/mainwindow.cpp b/noncore/apps/checkbook/mainwindow.cpp
index d9e2047..8e2e2e3 100644
--- a/noncore/apps/checkbook/mainwindow.cpp
+++ b/noncore/apps/checkbook/mainwindow.cpp
@@ -1,363 +1,362 @@
/*
This file is part of the OPIE Project
=.
.=l. Copyright (c) 2002 Dan Williams <drw@handhelds.org>
.>+-=
_;:, .> :=|. This file is free software; you can
.> <`_, > . <= redistribute it and/or modify it under
:`=1 )Y*s>-.-- : the terms of the GNU General Public
.="- .-=="i, .._ License as published by the Free Software
- . .-<_> .<> Foundation; either version 2 of the License,
._= =} : or (at your option) any later version.
.%`+i> _;_.
.i_,=:_. -<s. This file 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 file;
-_. . . )=. = see the file COPYING. If not, write to the
-- :-=` Free Software Foundation, Inc.,
59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA.
*/
#include "mainwindow.h"
#include "cbinfo.h"
#include "configuration.h"
#include "password.h"
#include "checkbook.h"
#include <opie2/oresource.h>
#include <qpe/config.h>
#include <qpe/qpeapplication.h>
#include <qpe/qpemessagebox.h>
#include <qaction.h>
#include <qdir.h>
#include <qmenubar.h>
#include <qtoolbar.h>
#include <qwhatsthis.h>
MainWindow::MainWindow( QWidget* parent, const char* name, WFlags /*fl*/ )
: QMainWindow( parent, name, WStyle_ContextHelp )
{
setCaption( tr( "Checkbook" ) );
cbDir = Global::applicationFileName( "checkbook", "" );
lockIcon = Opie::Core::OResource::loadPixmap( "locked", Opie::Core::OResource::SmallIcon );
// Load configuration options
Config config( "checkbook" );
_cfg.readConfig( config );
// Build menu and tool bars
setToolBarsMovable( FALSE );
QToolBar *bar = new QToolBar( this );
bar->setHorizontalStretchable( TRUE );
QMenuBar *mb = new QMenuBar( bar );
mb->setMargin( 0 );
QPopupMenu *popup = new QPopupMenu( this );
bar = new QToolBar( this );
QAction *a = new QAction( tr( "New" ), Opie::Core::OResource::loadPixmap( "new", Opie::Core::OResource::SmallIcon ),
QString::null, 0, this, 0 );
a->setWhatsThis( tr( "Click here to create a new checkbook.\n\nYou also can select New from the Checkbook menu." ) );
connect( a, SIGNAL( activated() ), this, SLOT( slotNew() ) );
a->addTo( popup );
a->addTo( bar );
actionOpen = new QAction( tr( "Edit" ), Opie::Core::OResource::loadPixmap( "edit", Opie::Core::OResource::SmallIcon ),
QString::null, 0, this, 0 );
actionOpen->setWhatsThis( tr( "Select a checkbook and then click here to edit it.\n\nYou also can select Edit from the Checkbook menu, or click and hold on a checkbook name." ) );
connect( actionOpen, SIGNAL( activated() ), this, SLOT( slotEdit() ) );
actionOpen->addTo( popup );
actionOpen->addTo( bar );
actionDelete = new QAction( tr( "Delete" ), Opie::Core::OResource::loadPixmap( "trash", Opie::Core::OResource::SmallIcon ),
QString::null, 0, this, 0 );
actionDelete->setWhatsThis( tr( "Select a checkbook and then click here delete it.\n\nYou also can select Delete from the Checkbook menu." ) );
connect( actionDelete, SIGNAL( activated() ), this, SLOT( slotDelete() ) );
actionDelete->addTo( popup );
actionDelete->addTo( bar );
popup->insertSeparator();
a = new QAction( tr( "Configure" ), Opie::Core::OResource::loadPixmap( "SettingsIcon", Opie::Core::OResource::SmallIcon ),
QString::null, 0, this, 0 );
a->setWhatsThis( tr( "Click here to configure this app." ) );
connect( a, SIGNAL( activated() ), this, SLOT( slotConfigure() ) );
a->addTo( popup );
a->addTo( bar );
mb->insertItem( tr( "Checkbook" ), popup );
// Load Checkbook selection list
checkbooks = new CBInfoList();
QDir checkdir( cbDir );
if (checkdir.exists() == true)
{
QStringList cblist = checkdir.entryList( "*.qcb", QDir::Files|QDir::Readable|QDir::Writable,
QDir::Time );
CBInfo *cb = 0x0;
QString filename;
for ( QStringList::Iterator it = cblist.begin(); it != cblist.end(); it++ )
{
filename = cbDir;
filename.append( (*it) );
cb = new CBInfo( (*it).remove( (*it).find('.'), (*it).length() ), filename );
checkbooks->inSort( cb );
}
}
// Build Checkbook selection list control
cbList = 0x0;
buildList();
// open last book?
if( _cfg.isOpenLastBook() ) {
this->show();
this->showMaximized();
QListViewItem *itm=cbList->firstChild();
while( itm ) {
if( itm->text(posName)==_cfg.getLastBook() ) {
openBook( itm );
break;
}
itm=itm->nextSibling();
}
}
}
// --- ~MainWindow ------------------------------------------------------------
MainWindow::~MainWindow()
{
writeConfig();
}
// --- buildList --------------------------------------------------------------
void MainWindow::buildList()
{
if ( cbList )
delete cbList;
cbList = new QListView( this );
QWhatsThis::add( cbList, tr( "This is a listing of all checkbooks currently available." ) );
if ( _cfg.getShowLocks() )
{
cbList->addColumn( lockIcon, "", 24 );
posName = 1;
}
else
{
posName = 0;
}
cbList->addColumn( tr( "Checkbook Name" ) );
if ( _cfg.getShowBalances() )
{
int colnum = cbList->addColumn( tr( "Balance" ) );
cbList->setColumnAlignment( colnum, Qt::AlignRight );
}
cbList->setAllColumnsShowFocus( TRUE );
cbList->setSorting( posName );
QPEApplication::setStylusOperation( cbList->viewport(), QPEApplication::RightOnHold );
connect( cbList, SIGNAL( rightButtonPressed(QListViewItem*,const QPoint&,int) ),
this, SLOT( slotEdit() ) );
setCentralWidget( cbList );
for ( CBInfo *cb = checkbooks->first(); cb; cb = checkbooks->next() )
{
addCheckbook( cb );
}
}
void MainWindow::addCheckbook( CBInfo *cb )
{
QListViewItem *lvi = new QListViewItem( cbList );
if ( _cfg.getShowLocks() && !cb->password().isNull() )
{
lvi->setPixmap( 0, lockIcon );
}
lvi->setText( posName, cb->name() );
if ( _cfg.getShowBalances() )
{
QString balance;
balance.sprintf( "%.2f", cb->balance() );
balance.prepend( _cfg.getCurrencySymbol() );
lvi->setText( posName + 1, balance );
}
}
void MainWindow::buildFilename( const QString &name )
{
tempFilename = cbDir;
tempFilename.append( name );
tempFilename.append( ".qcb" );
}
void MainWindow::slotNew()
{
CBInfo *cb = new CBInfo();
Checkbook *currcb = new Checkbook( this, cb, &_cfg );
if ( QPEApplication::execDialog( currcb ) == QDialog::Accepted )
{
// Save new checkbook
buildFilename( cb->name() );
_cfg.setLastBook( cb->name() );
cb->setFilename( tempFilename );
cb->write();
// Add to listbox
checkbooks->inSort( cb );
addCheckbook( cb );
}
delete currcb;
}
// --- slotEdit ---------------------------------------------------------------
void MainWindow::slotEdit()
{
// get name and open it
QListViewItem *curritem = cbList->currentItem();
if ( !curritem )
return;
openBook( curritem );
}
// --- openBook ---------------------------------------------------------------
void MainWindow::openBook(QListViewItem *curritem)
{
+ if ( !curritem ) return;
// find book in List
QString currname=curritem->text(posName);
CBInfo *cb = checkbooks->first();
while ( cb ) {
if ( cb->name() == currname )
break;
cb = checkbooks->next();
}
if ( !cb ) return;
//
buildFilename( currname );
float currbalance = cb->balance();
bool currlock = !cb->password().isNull();
if ( currlock )
{
Password *pw = new Password( this, tr( "Enter password" ), tr( "Please enter your password:" ) );
if ( pw->exec() != QDialog::Accepted || pw->password != cb->password() )
{
delete pw;
return;
}
delete pw;
}
_cfg.setLastBook( currname );
Checkbook *currcb = new Checkbook( this, cb, &_cfg );
if ( QPEApplication::execDialog( currcb ) == QDialog::Accepted )
{
QString newname = cb->name();
if ( currname != newname )
{
// Update name if changed
- if( curritem ) {
curritem->setText( posName, newname );
cbList->sort();
- }
_cfg.setLastBook( newname );
// Remove old file
QFile f( tempFilename );
if ( f.exists() )
f.remove();
// Get new filename
buildFilename( newname );
cb->setFilename( tempFilename );
}
cb->write();
// Update lock if changed
if ( _cfg.getShowLocks() && !cb->password().isNull() != currlock )
{
if ( !cb->password().isNull() )
curritem->setPixmap( 0, lockIcon );
else
curritem->setPixmap( 0, nullIcon );
}
// Update balance if changed
if ( _cfg.getShowBalances() && cb->balance() != currbalance )
{
QString tempstr;
tempstr.sprintf( "%.2f", cb->balance() );
tempstr.prepend( _cfg.getCurrencySymbol() );
curritem->setText( posName + 1, tempstr );
}
// write config, if needed
if( _cfg.isDirty() ) {
Config config("checkbook");
_cfg.writeConfig( config );
}
}
delete currcb;
}
// --- slotDelete -------------------------------------------------------------
void MainWindow::slotDelete()
{
QString currname = cbList->currentItem()->text( posName );
if ( QPEMessageBox::confirmDelete ( this, tr( "Delete checkbook" ), currname ) )
{
buildFilename( currname );
QFile f( tempFilename );
if ( f.exists() )
{
f.remove();
}
delete cbList->currentItem();
}
}
// --- slotConfigure ----------------------------------------------------------
void MainWindow::slotConfigure()
{
Configuration *cfgdlg = new Configuration( this, _cfg );
if ( QPEApplication::execDialog( cfgdlg ) == QDialog::Accepted )
{
// read data from config dialog & save it
cfgdlg->saveConfig( _cfg );
writeConfig();
buildList();
}
delete cfgdlg;
}
// --- writeConfig --------------------------------------------------------------
void MainWindow::writeConfig()
{
Config config("checkbook");
_cfg.writeConfig( config );
}
diff --git a/noncore/apps/opie-console/procctl.cpp b/noncore/apps/opie-console/procctl.cpp
index a44529b..5239e26 100644
--- a/noncore/apps/opie-console/procctl.cpp
+++ b/noncore/apps/opie-console/procctl.cpp
@@ -1,97 +1,100 @@
#include <sys/wait.h>
#include <fcntl.h>
#include <unistd.h>
#include "procctl.h"
ProcContainer *ProcCtl::m_last = 0;
ProcCtl* ProcCtl::m_self = 0;
ProcCtl::ProcCtl() {
signal( SIGCHLD, signal_handler );
}
ProcCtl::~ProcCtl() {
}
ProcCtl* ProcCtl::self() {
if (!m_self ) {
m_self = new ProcCtl;
}
return m_self;
}
void ProcCtl::add(pid_t pi, int fd ) {
ProcContainer * con = new ProcContainer;
//memset(con, 0, sizeof(con) );
con->pid = pi;
con->fd = fd;
con->status = 0;
con->prev = m_last;
m_last = con;
}
void ProcCtl::remove( pid_t pi ) {
/*
* We first check if the last item
* is equal to pi the we
*
*/
ProcContainer* con;
if (m_last->pid == pi ) {
con = m_last;
m_last = con->prev;
delete con;
return;
}
con = m_last;
ProcContainer* forw = 0l;
while (con ) {
/* remove it */
if ( pi == con->pid ) {
+ if (forw)
forw->prev = con->prev;
+ else
+ forw = con->prev;
delete con;
return;
}
forw = con;
con = con->prev;
}
}
void ProcCtl::remove( ProcContainer con ) {
remove( con.pid );
}
int ProcCtl::status(pid_t pid )const{
ProcContainer *con = m_last;
while (con) {
if (con->pid == pid )
return con->status;
con = con->prev;
}
return -1;
}
void ProcCtl::signal_handler(int) {
int status;
signal( SIGCHLD, signal_handler );
pid_t pi = waitpid( -1, &status, WNOHANG );
/*
* find the container for pid
*
*/
if ( pi < 0 ) {
return;
}
ProcContainer* con = m_last;
while (con) {
if ( con->pid == pi ) {
con->status = status;
char result = 1;
/* give a 'signal' */
::write(con->fd, &result, 1 );
}
con = con->prev;
}
}
diff --git a/noncore/apps/tinykate/libkate/document/katedocument.cpp b/noncore/apps/tinykate/libkate/document/katedocument.cpp
index b82a86a..692fd46 100644
--- a/noncore/apps/tinykate/libkate/document/katedocument.cpp
+++ b/noncore/apps/tinykate/libkate/document/katedocument.cpp
@@ -1,3180 +1,3181 @@
/***************************************************************************
katedocument.cpp - description
-------------------
begin : Mon Jan 15 2001
copyright : (C) 2001 by Christoph "Crossfire" Cullmann
(C) 2002 by Joseph Wenninger
email : crossfire@babylon2k.de
jowenn@kde.org
***************************************************************************/
/***************************************************************************
* *
* 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. *
* *
***************************************************************************/
/*
Copyright (C) 1998, 1999 Jochen Wilhelmy
digisnap@cs.tu-berlin.de
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.
*/
#include "katedocument.h"
#include "kmessagebox.h"
#include "kglobal.h"
//#include "kcharsets.h"
#include "kdebug.h"
//#include "kinstance.h"
#include "kglobalsettings.h"
//#include "kaction.h"
//#include "kstdaction.h"
#include "../view/kateview.h"
#include "katebuffer.h"
#include "katetextline.h"
#include "katecmd.h"
/* OPIE */
#include <opie2/odebug.h>
#include <qpe/config.h>
/* QT */
#include <qfileinfo.h>
#include <qdatetime.h>
#include <qstring.h>
#include <qtimer.h>
#include <qobject.h>
#include <qapplication.h>
#include <qclipboard.h>
#include <qfont.h>
#include <qpainter.h>
#include <qfile.h>
#include <qtextstream.h>
#include <qtextcodec.h>
/* STD */
#include <sys/time.h>
#include <unistd.h>
#include <stdio.h>
KateAction::KateAction(Action a, PointStruc &cursor, int len, const QString &text)
: action(a), cursor(cursor), len(len), text(text) {
}
KateActionGroup::KateActionGroup(PointStruc &aStart, int type)
: start(aStart), action(0L), undoType(type) {
}
KateActionGroup::~KateActionGroup() {
KateAction *current, *next;
current = action;
while (current) {
next = current->next;
delete current;
current = next;
}
}
void KateActionGroup::insertAction(KateAction *a) {
a->next = action;
action = a;
}
const char * KateActionGroup::typeName(int type)
{
// return a short text description of the given undo group type suitable for a menu
// not the lack of i18n's, the caller is expected to handle translation
switch (type) {
case ugPaste : return "Paste Text";
case ugDelBlock : return "Selection Overwrite";
case ugIndent : return "Indent";
case ugUnindent : return "Unindent";
case ugComment : return "Comment";
case ugUncomment : return "Uncomment";
case ugReplace : return "Text Replace";
case ugSpell : return "Spell Check";
case ugInsChar : return "Typing";
case ugDelChar : return "Delete Text";
case ugInsLine : return "New Line";
case ugDelLine : return "Delete Line";
}
return "";
}
const int KateDocument::maxAttribs = 32;
QStringList KateDocument::searchForList = QStringList();
QStringList KateDocument::replaceWithList = QStringList();
uint KateDocument::uniqueID = 0;
QPtrDict<KateDocument::KateDocPrivate>* KateDocument::d_ptr = 0;
KateDocument::KateDocument(bool bSingleViewMode, bool bBrowserView,
QWidget *parentWidget, const char *widgetName,
QObject *, const char *)
: Kate::Document (),
myFont(KGlobalSettings::generalFont()), myFontBold(KGlobalSettings::generalFont()), myFontItalic(KGlobalSettings::generalFont()), myFontBI(KGlobalSettings::generalFont()),
myFontMetrics (myFont), myFontMetricsBold (myFontBold), myFontMetricsItalic (myFontItalic), myFontMetricsBI (myFontBI),
hlManager(HlManager::self ())
{
d(this)->hlSetByUser = false;
PreHighlightedTill=0;
RequestPreHighlightTill=0;
m_bSingleViewMode=bSingleViewMode;
m_bBrowserView = bBrowserView;
m_url = QString::null;
// NOTE: QFont::CharSet doesn't provide all the charsets KDE supports
// (esp. it doesn't distinguish between UTF-8 and iso10646-1)
myEncoding = QString::fromLatin1(QTextCodec::codecForLocale()->name());
maxLength = -1;
setFont (KGlobalSettings::generalFont());
myDocID = uniqueID;
uniqueID++;
myDocName = QString ("");
fileInfo = new QFileInfo ();
myCmd = new KateCmd (this);
connect(this,SIGNAL(modifiedChanged()),this,SLOT(slotModChanged()));
buffer = new KWBuffer;
connect(buffer, SIGNAL(linesChanged(int)), this, SLOT(slotBufferChanged()));
// connect(buffer, SIGNAL(textChanged()), this, SIGNAL(textChanged()));
connect(buffer, SIGNAL(needHighlight(long,long)),this,SLOT(slotBufferHighlight(long,long)));
colors[0] = KGlobalSettings::baseColor();
colors[1] = KGlobalSettings::highlightColor();
m_attribs = new Attribute[maxAttribs];
m_highlight = 0L;
tabChars = 8;
m_singleSelection = false;
newDocGeometry = false;
readOnly = false;
newDoc = false;
modified = false;
undoList.setAutoDelete(true);
undoState = 0;
undoSteps = 50;
pseudoModal = 0L;
clear();
setHighlight(0); //calls updateFontData()
// if the user changes the highlight with the dialog, notify the doc
connect(hlManager,SIGNAL(changed()),SLOT(hlChanged()));
newDocGeometry = false;
readConfig();
setReadOnly(false);
}
void KateDocument::setDontChangeHlOnSave()
{
d(this)->hlSetByUser = true;
}
void KateDocument::setFont (QFont font)
{
kdDebug()<<"Kate:: setFont"<<endl;
int oldwidth=myFontMetrics.width('W'); //Quick & Dirty Hack (by JoWenn) //Remove in KDE 3.0
myFont = font;
myFontBold = QFont (font);
myFontBold.setBold (true);
myFontItalic = QFont (font);
myFontItalic.setItalic (true);
myFontBI = QFont (font);
myFontBI.setBold (true);
myFontBI.setItalic (true);
myFontMetrics = CachedFontMetrics (myFont);
myFontMetricsBold = CachedFontMetrics (myFontBold);
myFontMetricsItalic = CachedFontMetrics (myFontItalic);
myFontMetricsBI = CachedFontMetrics (myFontBI);
int newwidth=myFontMetrics.width('W'); //Quick & Dirty Hack (by JoWenn) //Remove in KDE 3.0
maxLength=maxLength*(float)newwidth/(float)oldwidth; //Quick & Dirty Hack (by JoWenn) //Remove in KDE 3.0
updateFontData();
updateViews(); //Quick & Dirty Hack (by JoWenn) //Remove in KDE 3.0
}
long KateDocument::needPreHighlight(long till)
{
int max=numLines()-1;
if (till>max)
{
till=max;
}
if (PreHighlightedTill>=till) return -1;
long tmp=RequestPreHighlightTill;
if (RequestPreHighlightTill<till)
{
RequestPreHighlightTill=till;
if (tmp<=PreHighlightedTill) QTimer::singleShot(10,this,SLOT(doPreHighlight()));
}
return RequestPreHighlightTill;
}
void KateDocument::doPreHighlight()
{
int from = PreHighlightedTill;
int till = PreHighlightedTill+200;
int max = numLines()-1;
if (till > max)
{
till = max;
}
PreHighlightedTill = till;
updateLines(from,till);
emit preHighlightChanged(PreHighlightedTill);
if (PreHighlightedTill<RequestPreHighlightTill)
QTimer::singleShot(10,this,SLOT(doPreHighlight()));
}
KateDocument::~KateDocument()
{
m_highlight->release();
writeConfig();
if ( !m_bSingleViewMode )
{
m_views.setAutoDelete( true );
m_views.clear();
m_views.setAutoDelete( false );
}
delete_d(this);
}
void KateDocument::openURL(const QString &filename)
{
m_file=filename;
fileInfo->setFile (m_file);
setMTime();
if (!fileInfo->exists() || !fileInfo->isReadable())
{
odebug << "File doesn't exit or couldn't be read" << oendl;
return ;
}
buffer->clear();
#warning fixme
// buffer->insertFile(0, m_file, KGlobal::charsets()->codecForName(myEncoding));
odebug << "Telling buffer to open file" << oendl;
buffer->insertFile(0, m_file, QTextCodec::codecForLocale());
setMTime();
if (myWordWrap)
wrapText (myWordWrapAt);
int hl = hlManager->wildcardFind( m_file );
setHighlight(hl);
updateLines();
updateViews();
emit fileNameChanged();
return ;
}
bool KateDocument::saveFile()
{
QFile f( m_file );
if ( !f.open( IO_WriteOnly ) )
return false; // Error
QTextStream stream(&f);
stream.setEncoding(QTextStream::RawUnicode); // disable Unicode headers
#warning fixme
// stream.setCodec(KGlobal::charsets()->codecForName(myEncoding));
stream.setCodec(QTextCodec::codecForLocale()); // this line sets the mapper to the correct codec
int maxLine = numLines();
int line = 0;
while(true)
{
stream << getTextLine(line)->getString();
line++;
if (line >= maxLine) break;
if (eolMode == KateDocument::eolUnix) stream << "\n";
else if (eolMode == KateDocument::eolDos) stream << "\r\n";
else if (eolMode == KateDocument::eolMacintosh) stream << '\r';
};
f.close();
fileInfo->setFile (m_file);
setMTime();
if (!(d(this)->hlSetByUser))
{
int hl = hlManager->wildcardFind( m_file );
setHighlight(hl);
}
emit fileNameChanged ();
if(f.status() == IO_Ok) {
setModified(false);
return true;
}
else
return false;
}
KTextEditor::View *KateDocument::createView( QWidget *parent, const char *name )
{
return new KateView( this, parent, name);
}
QString KateDocument::textLine( int line ) const
{
TextLine::Ptr l = getTextLine( line );
if ( !l )
return QString();
return l->getString();
}
void KateDocument::replaceLine(const QString& s,int line)
{
remove_Line(line,false);
insert_Line(s,line,true);
}
void KateDocument::insertLine( const QString &str, int l ) {
insert_Line(str,l,true);
}
void KateDocument::insert_Line(const QString& s,int line, bool update)
{
kdDebug(13020)<<"KateDocument::insertLine "<<s<<QString(" %1").arg(line)<<endl;
TextLine::Ptr TL=new TextLine();
TL->append(s.unicode(),s.length());
buffer->insertLine(line,TL);
if (update)
{
newDocGeometry=true;
updateLines(line);
updateViews();
}
}
void KateDocument::insertAt( const QString &s, int line, int col, bool )
{
VConfig c;
c.view = 0; // ### FIXME
c.cursor.x = col;
c.cursor.y = line;
c.cXPos = 0; // ### FIXME
c.flags = 0; // ### FIXME
insert( c, s );
}
void KateDocument::removeLine( int line ) {
remove_Line(line,true);
}
void KateDocument::remove_Line(int line,bool update)
{
kdDebug(13020)<<"KateDocument::removeLine "<<QString("%1").arg(line)<<endl;
buffer->removeLine(line);
// newDocGeometry=true;
// if line==0)
if (update)
{
updateLines(line);
updateViews();
}
}
int KateDocument::length() const
{
return text().length();
}
void KateDocument::setSelection( int , int , int , int )
{
}
bool KateDocument::hasSelection() const
{
return (selectEnd >= selectStart);
}
QString KateDocument::selection() const
{
uint flags = 0;
TextLine::Ptr textLine;
int len, z, start, end, i;
len = 1;
if (!(flags & KateView::cfVerticalSelect)) {
for (z = selectStart; z <= selectEnd; z++) {
textLine = getTextLine(z);
len += textLine->numSelected();
if (textLine->isSelected()) len++;
}
QString s;
len = 0;
for (z = selectStart; z <= selectEnd; z++) {
textLine = getTextLine(z);
end = 0;
do {
start = textLine->findUnselected(end);
end = textLine->findSelected(start);
for (i = start; i < end; i++) {
s[len] = textLine->getChar(i);
len++;
}
} while (start < end);
if (textLine->isSelected()) {
s[len] = '\n';
len++;
}
}
// s[len] = '\0';
return s;
} else {
for (z = selectStart; z <= selectEnd; z++) {
textLine = getTextLine(z);
len += textLine->numSelected() + 1;
}
QString s;
len = 0;
for (z = selectStart; z <= selectEnd; z++) {
textLine = getTextLine(z);
end = 0;
do {
start = textLine->findUnselected(end);
end = textLine->findSelected(start);
for (i = start; i < end; i++) {
s[len] = textLine->getChar(i);
len++;
}
} while (start < end);
s[len] = '\n';
len++;
}
// s[len] = '\0'; // the final \0 is not counted in length()
return s;
}
}
int KateDocument::numLines() const
{
return buffer->count();
}
TextLine::Ptr KateDocument::getTextLine(int line) const
{
// This is a hack to get this stuff working.
return buffer->line(line);
}
int KateDocument::textLength(int line) {
TextLine::Ptr textLine = getTextLine(line);
if (!textLine) return 0;
return textLine->length();
}
void KateDocument::setTabWidth(int chars) {
if (tabChars == chars) return;
if (chars < 1) chars = 1;
if (chars > 16) chars = 16;
tabChars = chars;
updateFontData();
maxLength = -1;
for (int i=0; i < buffer->count(); i++)
{
TextLine::Ptr textLine = buffer->line(i);
int len = textWidth(textLine,textLine->length());
if (len > maxLength) {
maxLength = len;
longestLine = textLine;
}
}
}
void KateDocument::setReadOnly(bool m) {
KTextEditor::View *view;
if (m != readOnly) {
readOnly = m;
// if (readOnly) recordReset();
for (view = m_views.first(); view != 0L; view = m_views.next() ) {
emit static_cast<KateView *>( view )->newStatus();
}
}
}
bool KateDocument::isReadOnly() const {
return readOnly;
}
void KateDocument::setNewDoc( bool m )
{
// KTextEditor::View *view;
if ( m != newDoc )
{
newDoc = m;
//// if (readOnly) recordReset();
// for (view = m_views.first(); view != 0L; view = m_views.next() ) {
// emit static_cast<KateView *>( view )->newStatus();
// }
}
}
bool KateDocument::isNewDoc() const {
return newDoc;
}
void KateDocument::setModified(bool m) {
KTextEditor::View *view;
if (m != modified) {
modified = m;
for (view = m_views.first(); view != 0L; view = m_views.next() ) {
emit static_cast<KateView *>( view )->newStatus();
}
emit modifiedChanged ();
}
}
bool KateDocument::isModified() const {
return modified;
}
void KateDocument::readConfig()
{
KateConfig *config = KGlobal::config();
config->setGroup("Kate Document");
myWordWrap = config->readBoolEntry("Word Wrap On", false);
myWordWrapAt = config->readNumEntry("Word Wrap At", 80);
if (myWordWrap)
wrapText (myWordWrapAt);
setTabWidth(config->readNumEntry("TabWidth", 8));
setUndoSteps(config->readNumEntry("UndoSteps", 50));
m_singleSelection = config->readBoolEntry("SingleSelection", false);
myEncoding = config->readEntry("Encoding", QString::fromLatin1(QTextCodec::codecForLocale()->name()));
setFont (config->readFontEntry("Font", myFont));
colors[0] = config->readColorEntry("Color Background", colors[0]);
colors[1] = config->readColorEntry("Color Selected", colors[1]);
// config->sync();
}
void KateDocument::writeConfig()
{
KateConfig *config = KGlobal::config();
config->setGroup("Kate Document");
config->writeEntry("Word Wrap On", myWordWrap);
config->writeEntry("Word Wrap At", myWordWrapAt);
config->writeEntry("TabWidth", tabChars);
config->writeEntry("UndoSteps", undoSteps);
config->writeEntry("SingleSelection", m_singleSelection);
config->writeEntry("Encoding", myEncoding);
config->writeEntry("Font", myFont);
config->writeEntry("Color Background", colors[0]);
config->writeEntry("Color Selected", colors[1]);
// config->sync();
}
void KateDocument::readSessionConfig(KateConfig *config)
{
m_url = config->readEntry("URL"); // ### doesn't this break the encoding? (Simon)
setHighlight(hlManager->nameFind(config->readEntry("Highlight")));
// anders: restore bookmarks if possible
QValueList<int> l = config->readIntListEntry("Bookmarks");
if ( l.count() ) {
for (uint i=0; i < l.count(); i++) {
if ( numLines() < l[i] ) break;
getTextLine( l[i] )->addMark( Bookmark );
}
}
}
void KateDocument::writeSessionConfig(KateConfig *config)
{
#if 0
config->writeEntry("URL", m_url); // ### encoding?? (Simon)
config->writeEntry("Highlight", m_highlight->name());
// anders: save bookmarks
QList<Kate::Mark> l = marks();
QValueList<int> ml;
for (uint i=0; i < l.count(); i++) {
if ( l.at(i)->type == 1) // only save bookmarks
ml << l.at(i)->line;
}
if ( ml.count() )
config->writeEntry("Bookmarks", ml);
#endif
}
void KateDocument::setHighlight(int n) {
Highlight *h;
// hlNumber = n;
h = hlManager->getHl(n);
if (h == m_highlight) {
updateLines();
} else {
if (m_highlight != 0L) m_highlight->release();
h->use();
m_highlight = h;
makeAttribs();
}
PreHighlightedTill=0;
RequestPreHighlightTill=0;
emit(highlightChanged());
}
void KateDocument::makeAttribs() {
odebug << "KateDocument::makeAttribs()" << oendl;
m_numAttribs = hlManager->makeAttribs(m_highlight, m_attribs, maxAttribs);
updateFontData();
updateLines();
}
void KateDocument::updateFontData() {
int maxAscent, maxDescent;
int tabWidth;
KateView *view;
maxAscent = myFontMetrics.ascent();
maxDescent = myFontMetrics.descent();
tabWidth = myFontMetrics.width(' ');
fontHeight = maxAscent + maxDescent + 1;
fontAscent = maxAscent;
m_tabWidth = tabChars*tabWidth;
for (view = views.first(); view != 0L; view = views.next() ) {
view->myViewInternal->drawBuffer->resize(view->width(),fontHeight);
view->tagAll();
view->updateCursor();
}
}
void KateDocument::hlChanged() { //slot
makeAttribs();
updateViews();
}
void KateDocument::addView(KTextEditor::View *view) {
views.append( static_cast<KateView *>( view ) );
KTextEditor::Document::addView( view );
connect( static_cast<KateView *>( view ), SIGNAL( destroyed() ), this, SLOT( slotViewDestroyed() ) );
}
void KateDocument::removeView(KTextEditor::View *view) {
// if (undoView == view) recordReset();
disconnect( static_cast<KateView *>( view ), SIGNAL( destroyed() ), this, SLOT( slotViewDestroyed() ) );
views.removeRef( static_cast<KateView *>( view ) );
KTextEditor::Document::removeView( view );
}
void KateDocument::slotViewDestroyed()
{
views.removeRef( static_cast<const KateView *>( sender() ) );
}
bool KateDocument::ownedView(KateView *view) {
// do we own the given view?
return (views.containsRef(view) > 0);
}
bool KateDocument::isLastView(int numViews) {
return ((int) views.count() == numViews);
}
int KateDocument::textWidth(const TextLine::Ptr &textLine, int cursorX) {
int x;
int z;
QChar ch;
Attribute *a;
x = 0;
for (z = 0; z < cursorX; z++) {
ch = textLine->getChar(z);
a = &m_attribs[textLine->getAttr(z)];
if (ch == '\t')
x += m_tabWidth - (x % m_tabWidth);
else if (a->bold && a->italic)
x += myFontMetricsBI.width(ch);
else if (a->bold)
x += myFontMetricsBold.width(ch);
else if (a->italic)
x += myFontMetricsItalic.width(ch);
else
x += myFontMetrics.width(ch);
}
return x;
}
int KateDocument::textWidth(PointStruc &cursor) {
if (cursor.x < 0)
cursor.x = 0;
if (cursor.y < 0)
cursor.y = 0;
if (cursor.y >= numLines())
cursor.y = lastLine();
return textWidth(getTextLine(cursor.y),cursor.x);
}
int KateDocument::textWidth(bool wrapCursor, PointStruc &cursor, int xPos) {
int len;
int x, oldX;
int z;
QChar ch;
Attribute *a;
if (cursor.y < 0) cursor.y = 0;
if (cursor.y > lastLine()) cursor.y = lastLine();
TextLine::Ptr textLine = getTextLine(cursor.y);
len = textLine->length();
x = oldX = z = 0;
while (x < xPos && (!wrapCursor || z < len)) {
oldX = x;
ch = textLine->getChar(z);
a = &m_attribs[textLine->getAttr(z)];
if (ch == '\t')
x += m_tabWidth - (x % m_tabWidth);
else if (a->bold && a->italic)
x += myFontMetricsBI.width(ch);
else if (a->bold)
x += myFontMetricsBold.width(ch);
else if (a->italic)
x += myFontMetricsItalic.width(ch);
else
x += myFontMetrics.width(ch);
z++;
}
if (xPos - oldX < x - xPos && z > 0) {
z--;
x = oldX;
}
cursor.x = z;
return x;
}
int KateDocument::textPos(const TextLine::Ptr &textLine, int xPos) {
int x, oldX;
int z;
QChar ch;
Attribute *a;
x = oldX = z = 0;
while (x < xPos) { // && z < len) {
oldX = x;
ch = textLine->getChar(z);
a = &m_attribs[textLine->getAttr(z)];
if (ch == '\t')
x += m_tabWidth - (x % m_tabWidth);
else if (a->bold && a->italic)
x += myFontMetricsBI.width(ch);
else if (a->bold)
x += myFontMetricsBold.width(ch);
else if (a->italic)
x += myFontMetricsItalic.width(ch);
else
x += myFontMetrics.width(ch);
z++;
}
if (xPos - oldX < x - xPos && z > 0) {
z--;
// newXPos = oldX;
}// else newXPos = x;
return z;
}
int KateDocument::textWidth() {
return int(maxLength + 8);
}
int KateDocument::textHeight() {
return numLines()*fontHeight;
}
void KateDocument::insert(VConfig &c, const QString &s) {
int pos;
QChar ch;
QString buf;
if (s.isEmpty()) return;
recordStart(c, KateActionGroup::ugPaste);
pos = 0;
if (!(c.flags & KateView::cfVerticalSelect)) {
do {
ch = s[pos];
if (ch.isPrint() || ch == '\t') {
buf += ch; // append char to buffer
} else if (ch == '\n') {
recordAction(KateAction::newLine, c.cursor); // wrap contents behind cursor to new line
recordInsert(c, buf); // append to old line
// c.cursor.x += buf.length();
buf.truncate(0); // clear buffer
c.cursor.y++;
c.cursor.x = 0;
}
pos++;
} while (pos < (int) s.length());
} else {
int xPos;
xPos = textWidth(c.cursor);
do {
ch = s[pos];
if (ch.isPrint() || ch == '\t') {
buf += ch;
} else if (ch == '\n') {
recordInsert(c, buf);
c.cursor.x += buf.length();
buf.truncate(0);
c.cursor.y++;
if (c.cursor.y >= numLines())
recordAction(KateAction::insLine, c.cursor);
c.cursor.x = textPos(getTextLine(c.cursor.y), xPos);
}
pos++;
} while (pos < (int) s.length());
}
recordInsert(c, buf);
c.cursor.x += buf.length();
recordEnd(c);
}
void KateDocument::insertFile(VConfig &c, QIODevice &dev)
{
recordStart(c, KateActionGroup::ugPaste);
QString buf;
QChar ch, last;
QTextStream stream( &dev );
while ( !stream.atEnd() ) {
stream >> ch;
if (ch.isPrint() || ch == '\t') {
buf += ch;
} else if (ch == '\n' || ch == '\r') {
if (last != '\r' || ch != '\n') {
recordAction(KateAction::newLine, c.cursor);
recordInsert(c, buf);
buf.truncate(0);
c.cursor.y++;
c.cursor.x = 0;
}
last = ch;
}
}
recordInsert(c, buf);
recordEnd(c);
}
int KateDocument::currentColumn(PointStruc &cursor) {
return getTextLine(cursor.y)->cursorX(cursor.x,tabChars);
}
bool KateDocument::insertChars(VConfig &c, const QString &chars) {
int z, pos, l;
bool onlySpaces;
QChar ch;
QString buf;
TextLine::Ptr textLine = getTextLine(c.cursor.y);
pos = 0;
onlySpaces = true;
for (z = 0; z < (int) chars.length(); z++) {
ch = chars[z];
if (ch == '\t' && c.flags & KateView::cfReplaceTabs) {
l = tabChars - (textLine->cursorX(c.cursor.x, tabChars) % tabChars);
while (l > 0) {
buf.insert(pos, ' ');
pos++;
l--;
}
} else if (ch.isPrint() || ch == '\t') {
buf.insert(pos, ch);
pos++;
if (ch != ' ') onlySpaces = false;
if (c.flags & KateView::cfAutoBrackets) {
if (ch == '(') buf.insert(pos, ')');
if (ch == '[') buf.insert(pos, ']');
if (ch == '{') buf.insert(pos, '}');
}
}
}
//pos = cursor increment
//return false if nothing has to be inserted
if (buf.isEmpty()) return false;
//auto deletion of the marked text occurs not very often and can therefore
// be recorded separately
if (c.flags &KateView:: cfDelOnInput) delMarkedText(c);
recordStart(c, KateActionGroup::ugInsChar);
recordReplace(c/*.cursor*/, (c.flags & KateView::cfOvr) ? buf.length() : 0, buf);
c.cursor.x += pos;
if (myWordWrap && myWordWrapAt > 0) {
int line;
const QChar *s;
// int pos;
PointStruc actionCursor;
line = c.cursor.y;
do {
textLine = getTextLine(line);
s = textLine->getText();
l = textLine->length();
for (z = myWordWrapAt; z < l; z++) if (!s[z].isSpace()) break; //search for text to wrap
if (z >= l) break; // nothing more to wrap
pos = myWordWrapAt;
for (; z >= 0; z--) { //find wrap position
if (s[z].isSpace()) {
pos = z + 1;
break;
}
}
//pos = wrap position
if (line == c.cursor.y && pos <= c.cursor.x) {
//wrap cursor
c.cursor.y++;
c.cursor.x -= pos;
}
if (line == lastLine() || (getTextLine(line+1)->length() == 0) ) {
//at end of doc: create new line
actionCursor.x = pos;
actionCursor.y = line;
recordAction(KateAction::newLine,actionCursor);
} else {
//wrap
actionCursor.y = line + 1;
if (!s[l - 1].isSpace()) { //add space in next line if necessary
actionCursor.x = 0;
recordInsert(actionCursor, " ");
}
actionCursor.x = textLine->length() - pos;
recordAction(KateAction::wordWrap, actionCursor);
}
line++;
} while (true);
}
recordEnd(c);
return true;
}
QString tabString(int pos, int tabChars) {
QString s;
while (pos >= tabChars) {
s += '\t';
pos -= tabChars;
}
while (pos > 0) {
s += ' ';
pos--;
}
return s;
}
void KateDocument::newLine(VConfig &c) {
//auto deletion of marked text is done by the view to have a more
// "low level" KateDocument::newLine method
recordStart(c, KateActionGroup::ugInsLine);
if (!(c.flags & KateView::cfAutoIndent)) {
recordAction(KateAction::newLine,c.cursor);
c.cursor.y++;
c.cursor.x = 0;
} else {
TextLine::Ptr textLine = getTextLine(c.cursor.y);
int pos = textLine->firstChar();
if (c.cursor.x < pos) c.cursor.x = pos; // place cursor on first char if before
int y = c.cursor.y;
while ((y > 0) && (pos < 0)) { // search a not empty text line
textLine = getTextLine(--y);
pos = textLine->firstChar();
}
recordAction(KateAction::newLine, c.cursor);
c.cursor.y++;
c.cursor.x = 0;
if (pos > 0) {
pos = textLine->cursorX(pos, tabChars);
// if (getTextLine(c.cursor.y)->length() > 0) {
QString s = tabString(pos, (c.flags & KateView::cfSpaceIndent) ? 0xffffff : tabChars);
recordInsert(c.cursor, s);
pos = s.length();
// }
// recordInsert(c.cursor, QString(textLine->getText(), pos));
c.cursor.x = pos;
}
}
recordEnd(c);
}
void KateDocument::killLine(VConfig &c) {
recordStart(c, KateActionGroup::ugDelLine);
c.cursor.x = 0;
recordDelete(c.cursor, 0xffffff);
if (c.cursor.y < lastLine()) {
recordAction(KateAction::killLine, c.cursor);
}
recordEnd(c);
}
void KateDocument::backspace(VConfig &c) {
if (c.cursor.x <= 0 && c.cursor.y <= 0) return;
if (c.cursor.x > 0) {
recordStart(c, KateActionGroup::ugDelChar);
if (!(c.flags & KateView::cfBackspaceIndents)) {
// ordinary backspace
c.cursor.x--;
recordDelete(c.cursor, 1);
} else {
// backspace indents: erase to next indent position
int l = 1; // del one char
TextLine::Ptr textLine = getTextLine(c.cursor.y);
int pos = textLine->firstChar();
if (pos < 0 || pos >= c.cursor.x) {
// only spaces on left side of cursor
// search a line with less spaces
int y = c.cursor.y;
while (y > 0) {
textLine = getTextLine(--y);
pos = textLine->firstChar();
if (pos >= 0 && pos < c.cursor.x) {
l = c.cursor.x - pos; // del more chars
break;
}
}
}
// break effectively jumps here
c.cursor.x -= l;
recordDelete(c.cursor, l);
}
} else {
// c.cursor.x == 0: wrap to previous line
recordStart(c, KateActionGroup::ugDelLine);
c.cursor.y--;
c.cursor.x = getTextLine(c.cursor.y)->length();
recordAction(KateAction::delLine,c.cursor);
}
recordEnd(c);
}
void KateDocument::del(VConfig &c) {
TextLine::Ptr textLine = getTextLine(c.cursor.y);
int len = (c.flags & KateView::cfRemoveSpaces) ? textLine->lastChar() : textLine->length();
if (c.cursor.x < len/*getTextLine(c.cursor.y)->length()*/) {
// delete one character
recordStart(c, KateActionGroup::ugDelChar);
recordDelete(c.cursor, 1);
recordEnd(c);
} else {
if (c.cursor.y < lastLine()) {
// wrap next line to this line
textLine->truncate(c.cursor.x); // truncate spaces
recordStart(c, KateActionGroup::ugDelLine);
recordAction(KateAction::delLine,c.cursor);
recordEnd(c);
}
}
}
void KateDocument::clear() {
PointStruc cursor;
KateView *view;
setPseudoModal(0L);
cursor.x = cursor.y = 0;
for (view = views.first(); view != 0L; view = views.next() ) {
view->updateCursor(cursor);
view->tagAll();
}
eolMode = KateDocument::eolUnix;
buffer->clear();
longestLine = buffer->line(0);
maxLength = 0;
select.x = -1;
selectStart = 0xffffff;
selectEnd = 0;
oldMarkState = false;
setModified(false);
undoList.clear();
currentUndo = 0;
newUndo();
}
void KateDocument::cut(VConfig &c) {
if (selectEnd < selectStart) return;
copy(c.flags);
delMarkedText(c);
}
void KateDocument::copy(int flags) {
if (selectEnd < selectStart) return;
QString s = markedText(flags);
if (!s.isEmpty()) {
//#if defined(_WS_X11_)
if (m_singleSelection)
disconnect(QApplication::clipboard(), SIGNAL(dataChanged()), this, 0);
//#endif
QApplication::clipboard()->setText(s);
//#if defined(_WS_X11_)
if (m_singleSelection) {
connect(QApplication::clipboard(), SIGNAL(dataChanged()),
this, SLOT(clipboardChanged()));
}
//#endif
}
}
void KateDocument::paste(VConfig &c) {
QString s = QApplication::clipboard()->text();
if (!s.isEmpty()) {
insert(c, s);
}
}
void KateDocument::toggleRect(int start, int end, int x1, int x2) {
int z, line;
bool t;
if (x1 > x2) {
z = x1;
x1 = x2;
x2 = z;
}
if (start > end) {
z = start;
start = end;
end = z;
}
t = false;
for (line = start; line < end; line++) {
int x, oldX, s, e, newX1, newX2;
QChar ch;
Attribute *a;
TextLine::Ptr textLine = getTextLine(line);
//--- speed optimization
//s = textPos(textLine, x1, newX1);
x = oldX = z = 0;
while (x < x1) { // && z < len) {
oldX = x;
ch = textLine->getChar(z);
a = &m_attribs[textLine->getAttr(z)];
if (ch == '\t')
x += m_tabWidth - (x % m_tabWidth);
else if (a->bold && a->italic)
x += myFontMetricsBI.width(ch);
else if (a->bold)
x += myFontMetricsBold.width(ch);
else if (a->italic)
x += myFontMetricsItalic.width(ch);
else
x += myFontMetrics.width(ch);
z++;
}
s = z;
if (x1 - oldX < x - x1 && z > 0) {
s--;
newX1 = oldX;
} else newX1 = x;
//e = textPos(textLine, x2, newX2);
while (x < x2) { // && z < len) {
oldX = x;
ch = textLine->getChar(z);
a = &m_attribs[textLine->getAttr(z)];
if (ch == '\t')
x += m_tabWidth - (x % m_tabWidth);
else if (a->bold && a->italic)
x += myFontMetricsBI.width(ch);
else if (a->bold)
x += myFontMetricsBold.width(ch);
else if (a->italic)
x += myFontMetricsItalic.width(ch);
else
x += myFontMetrics.width(ch);
z++;
}
e = z;
if (x2 - oldX < x - x2 && z > 0) {
e--;
newX2 = oldX;
} else newX2 = x;
//---
if (e > s) {
textLine->toggleSelect(s, e);
tagLineRange(line, newX1, newX2);
t = true;
}
}
if (t) {
end--;
// tagLines(start, end);
if (start < selectStart) selectStart = start;
if (end > selectEnd) selectEnd = end;
emit selectionChanged();
}
}
void KateDocument::selectTo(VConfig &c, PointStruc &cursor, int cXPos) {
//c.cursor = old cursor position
//cursor = new cursor position
if (c.cursor.x != select.x || c.cursor.y != select.y) {
//new selection
if (!(c.flags & KateView::cfKeepSelection)) deselectAll();
// else recordReset();
anchor = c.cursor;
aXPos = c.cXPos;
}
if (!(c.flags & KateView::cfVerticalSelect)) {
//horizontal selections
int x, y, sXPos;
int ex, ey, eXPos;
bool sel;
if (cursor.y > c.cursor.y || (cursor.y == c.cursor.y && cursor.x > c.cursor.x)) {
x = c.cursor.x;
y = c.cursor.y;
sXPos = c.cXPos;
ex = cursor.x;
ey = cursor.y;
eXPos = cXPos;
sel = true;
} else {
x = cursor.x;
y = cursor.y;
sXPos = cXPos;
ex = c.cursor.x;
ey = c.cursor.y;
eXPos = c.cXPos;
sel = false;
}
// tagLines(y, ye);
if (y < ey) {
//tagLineRange(y, sXPos, 0xffffff);
tagLines(y, ey -1);
tagLineRange(ey, 0, eXPos);
} else tagLineRange(y, sXPos, eXPos);
if (y < selectStart) selectStart = y;
if (ey > selectEnd) selectEnd = ey;
TextLine::Ptr textLine = getTextLine(y);
if (c.flags & KateView::cfXorSelect) {
//xor selection with old selection
while (y < ey) {
textLine->toggleSelectEol(x);
x = 0;
y++;
textLine = getTextLine(y);
}
textLine->toggleSelect(x, ex);
} else {
//set selection over old selection
if (anchor.y > y || (anchor.y == y && anchor.x > x)) {
if (anchor.y < ey || (anchor.y == ey && anchor.x < ex)) {
sel = !sel;
while (y < anchor.y) {
textLine->selectEol(sel, x);
x = 0;
y++;
textLine = getTextLine(y);
}
textLine->select(sel, x, anchor.x);
x = anchor.x;
}
sel = !sel;
}
while (y < ey) {
textLine->selectEol(sel, x);
x = 0;
y++;
textLine = getTextLine(y);
}
textLine->select(sel, x, ex);
}
} else {
//vertical (block) selections
// int ax, sx, ex;
// ax = textWidth(anchor);
// sx = textWidth(start);
// ex = textWidth(end);
toggleRect(c.cursor.y + 1, cursor.y + 1, aXPos, c.cXPos);
toggleRect(anchor.y, cursor.y + 1, c.cXPos, cXPos);
}
select = cursor;
optimizeSelection();
emit selectionChanged();
}
void KateDocument::selectAll() {
int z;
TextLine::Ptr textLine;
select.x = -1;
// if (selectStart != 0 || selectEnd != lastLine()) recordReset();
selectStart = 0;
selectEnd = lastLine();
tagLines(selectStart,selectEnd);
for (z = selectStart; z < selectEnd; z++) {
textLine = getTextLine(z);
textLine->selectEol(true,0);
}
textLine = getTextLine(z);
textLine->select(true,0,textLine->length());
emit selectionChanged();
}
void KateDocument::deselectAll() {
select.x = -1;
if (selectEnd < selectStart) return;
// recordReset();
tagLines(selectStart,selectEnd);
for (int z = selectStart; z <= selectEnd; z++) {
TextLine::Ptr textLine = getTextLine(z);
textLine->selectEol(false,0);
}
selectStart = 0xffffff;
selectEnd = 0;
emit selectionChanged();
}
void KateDocument::invertSelection() {
TextLine::Ptr textLine;
select.x = -1;
// if (selectStart != 0 || selectEnd != lastLine()) recordReset();
selectStart = 0;
selectEnd = lastLine();
tagLines(selectStart,selectEnd);
for (int z = selectStart; z < selectEnd; z++) {
textLine = getTextLine(z);
textLine->toggleSelectEol(0);
}
textLine = getTextLine(selectEnd);
textLine->toggleSelect(0,textLine->length());
optimizeSelection();
emit selectionChanged();
}
void KateDocument::selectWord(PointStruc &cursor, int flags) {
int start, end, len;
TextLine::Ptr textLine = getTextLine(cursor.y);
len = textLine->length();
start = end = cursor.x;
while (start > 0 && m_highlight->isInWord(textLine->getChar(start - 1))) start--;
while (end < len && m_highlight->isInWord(textLine->getChar(end))) end++;
if (end <= start) return;
if (!(flags & KateView::cfKeepSelection)) deselectAll();
// else recordReset();
textLine->select(true, start, end);
anchor.x = start;
select.x = end;
anchor.y = select.y = cursor.y;
tagLines(cursor.y, cursor.y);
if (cursor.y < selectStart) selectStart = cursor.y;
if (cursor.y > selectEnd) selectEnd = cursor.y;
emit selectionChanged();
}
void KateDocument::selectLength(PointStruc &cursor, int length, int flags) {
int start, end;
TextLine::Ptr textLine = getTextLine(cursor.y);
start = cursor.x;
end = start + length;
if (end <= start) return;
if (!(flags & KateView::cfKeepSelection)) deselectAll();
textLine->select(true, start, end);
anchor.x = start;
select.x = end;
anchor.y = select.y = cursor.y;
tagLines(cursor.y, cursor.y);
if (cursor.y < selectStart) selectStart = cursor.y;
if (cursor.y > selectEnd) selectEnd = cursor.y;
emit selectionChanged();
}
void KateDocument::doIndent(VConfig &c, int change) {
c.cursor.x = 0;
recordStart(c, (change < 0) ? KateActionGroup::ugUnindent
: KateActionGroup::ugIndent);
if (selectEnd < selectStart) {
// single line
optimizeLeadingSpace(c.cursor.y, c.flags, change);
} else {
// entire selection
TextLine::Ptr textLine;
int line, z;
QChar ch;
if (c.flags & KateView::cfKeepIndentProfile && change < 0) {
// unindent so that the existing indent profile doesn´t get screwed
// if any line we may unindent is already full left, don't do anything
for (line = selectStart; line <= selectEnd; line++) {
textLine = getTextLine(line);
if (textLine->isSelected() || textLine->numSelected()) {
for (z = 0; z < tabChars; z++) {
ch = textLine->getChar(z);
if (ch == '\t') break;
if (ch != ' ') {
change = 0;
goto jumpOut;
}
}
}
}
jumpOut:;
}
for (line = selectStart; line <= selectEnd; line++) {
textLine = getTextLine(line);
if (textLine->isSelected() || textLine->numSelected()) {
optimizeLeadingSpace(line, c.flags, change);
}
}
}
// recordEnd now removes empty undo records
recordEnd(c.view, c.cursor, c.flags | KateView::cfPersistent);
}
/*
Optimize the leading whitespace for a single line.
If change is > 0, it adds indentation units (tabChars)
if change is == 0, it only optimizes
If change is < 0, it removes indentation units
This will be used to indent, unindent, and optimal-fill a line.
If excess space is removed depends on the flag cfKeepExtraSpaces
which has to be set by the user
*/
void KateDocument::optimizeLeadingSpace(int line, int flags, int change) {
int len;
int chars, space, okLen;
QChar ch;
int extra;
QString s;
PointStruc cursor;
TextLine::Ptr textLine = getTextLine(line);
len = textLine->length();
space = 0; // length of space at the beginning of the textline
okLen = 0; // length of space which does not have to be replaced
for (chars = 0; chars < len; chars++) {
ch = textLine->getChar(chars);
if (ch == ' ') {
space++;
if (flags & KateView::cfSpaceIndent && okLen == chars) okLen++;
} else if (ch == '\t') {
space += tabChars - space % tabChars;
if (!(flags & KateView::cfSpaceIndent) && okLen == chars) okLen++;
} else break;
}
space += change*tabChars; // modify space width
// if line contains only spaces it will be cleared
if (space < 0 || chars == len) space = 0;
extra = space % tabChars; // extra spaces which don´t fit the indentation pattern
if (flags & KateView::cfKeepExtraSpaces) chars -= extra;
if (flags & KateView::cfSpaceIndent) {
space -= extra;
ch = ' ';
} else {
space /= tabChars;
ch = '\t';
}
// don´t replace chars which are already ok
cursor.x = QMIN(okLen, QMIN(chars, space));
chars -= cursor.x;
space -= cursor.x;
if (chars == 0 && space == 0) return; //nothing to do
s.fill(ch, space);
//printf("chars %d insert %d cursor.x %d\n", chars, insert, cursor.x);
cursor.y = line;
recordReplace(cursor, chars, s);
}
void KateDocument::doComment(VConfig &c, int change)
{
c.flags |=KateView:: cfPersistent;
recordStart(c, (change < 0) ? KateActionGroup::ugUncomment
: KateActionGroup::ugComment);
QString startComment = m_highlight->getCommentStart();
QString startLineComment = m_highlight->getCommentSingleLineStart();
QString endComment = m_highlight->getCommentEnd();
int startCommentLen = startComment.length();
int startLineCommentLen = startLineComment.length();
int endCommentLen = endComment.length();
if (change > 0)
{
if ( !hasMarkedText() )
{
if (startLineComment != "")
{
// Add a start comment mark
c.cursor.x = 0;
recordReplace(c.cursor, 0, startLineComment);
}
else if ((startComment != "") && (endComment != ""))
{
// Add a start comment mark
c.cursor.x = 0;
recordReplace(c.cursor, 0, startComment);
// Add an end comment mark
TextLine* textline = getTextLine(c.cursor.y);
c.cursor.x = textline->length();
recordReplace(c.cursor, 0, endComment);
c.cursor.x = 0;
}
}
else if ((startComment != "") && (endComment != ""))
{
QString marked (c.view->markedText ());
int preDeleteLine = -1, preDeleteCol = -1;
c.view->getCursorPosition (&preDeleteLine, &preDeleteCol);
if (marked.length() > 0)
c.view->keyDelete ();
int line = -1, col = -1;
c.view->getCursorPosition (&line, &col);
c.view->insertText (startComment + marked + endComment);
}
}
else
{
if ( !hasMarkedText() )
{
TextLine* textline = getTextLine(c.cursor.y);
if(textline->startingWith(startLineComment))
{
// Remove start comment mark
c.cursor.x = 0;
recordReplace(c.cursor, startLineCommentLen, "");
}
else if (textline->startingWith(startComment) && textline->endingWith(endComment))
{
// Remove start comment mark
c.cursor.x = 0;
recordReplace(c.cursor, startCommentLen, "");
// Remove end comment mark
if(endComment != "")
{
c.cursor.x = textline->length() - endCommentLen;
recordReplace(c.cursor, endCommentLen, "");
c.cursor.x = 0;
}
}
}
else
{
QString marked (c.view->markedText ());
int preDeleteLine = -1, preDeleteCol = -1;
c.view->getCursorPosition (&preDeleteLine, &preDeleteCol);
int start = marked.find (startComment);
int end = marked.findRev (endComment);
if ((start > -1) && (end > -1))
{
marked.remove (start, startCommentLen);
marked.remove (end-startCommentLen, endCommentLen);
c.view->keyDelete ();
int line = -1, col = -1;
c.view->getCursorPosition (&line, &col);
c.view->insertText (marked);
}
}
}
recordEnd(c.view, c.cursor, c.flags | KateView::cfPersistent);
}
QString KateDocument::text() const
{
QString s;
for (int i=0; i < buffer->count(); i++)
{
TextLine::Ptr textLine = buffer->line(i);
s.insert(s.length(), textLine->getText(), textLine->length());
if ( (i < (buffer->count()-1)) )
s.append('\n');
}
return s;
}
QString KateDocument::getWord(PointStruc &cursor) {
int start, end, len;
TextLine::Ptr textLine = getTextLine(cursor.y);
len = textLine->length();
start = end = cursor.x;
while (start > 0 && m_highlight->isInWord(textLine->getChar(start - 1))) start--;
while (end < len && m_highlight->isInWord(textLine->getChar(end))) end++;
len = end - start;
return QString(&textLine->getText()[start], len);
}
void KateDocument::setText(const QString &s) {
int pos;
QChar ch;
clear();
int line=1;
TextLine::Ptr textLine = buffer->line(0);
for (pos = 0; pos <= (int) s.length(); pos++) {
ch = s[pos];
if (ch.isPrint() || ch == '\t') {
textLine->append(&ch, 1);
} else if (ch == '\n')
{
textLine = new TextLine();
buffer->insertLine (line, textLine);
line++;
}
}
updateLines();
}
QString KateDocument::markedText(int flags) {
TextLine::Ptr textLine;
int len, z, start, end, i;
len = 1;
if (!(flags & KateView::cfVerticalSelect)) {
for (z = selectStart; z <= selectEnd; z++) {
textLine = getTextLine(z);
len += textLine->numSelected();
if (textLine->isSelected()) len++;
}
QString s;
len = 0;
for (z = selectStart; z <= selectEnd; z++) {
textLine = getTextLine(z);
end = 0;
do {
start = textLine->findUnselected(end);
end = textLine->findSelected(start);
for (i = start; i < end; i++) {
s[len] = textLine->getChar(i);
len++;
}
} while (start < end);
if (textLine->isSelected()) {
s[len] = '\n';
len++;
}
}
// s[len] = '\0';
return s;
} else {
for (z = selectStart; z <= selectEnd; z++) {
textLine = getTextLine(z);
len += textLine->numSelected() + 1;
}
QString s;
len = 0;
for (z = selectStart; z <= selectEnd; z++) {
textLine = getTextLine(z);
end = 0;
do {
start = textLine->findUnselected(end);
end = textLine->findSelected(start);
for (i = start; i < end; i++) {
s[len] = textLine->getChar(i);
len++;
}
} while (start < end);
s[len] = '\n';
len++;
}
// s[len] = '\0'; // the final \0 is not counted in length()
return s;
}
}
void KateDocument::delMarkedText(VConfig &c/*, bool undo*/) {
int end = 0;
if (selectEnd < selectStart) return;
// the caller may have already started an undo record for the current action
// if (undo)
//auto deletion of the marked text occurs not very often and can therefore
// be recorded separately
recordStart(c, KateActionGroup::ugDelBlock);
for (c.cursor.y = selectEnd; c.cursor.y >= selectStart; c.cursor.y--) {
TextLine::Ptr textLine = getTextLine(c.cursor.y);
c.cursor.x = textLine->length();
do {
end = textLine->findRevUnselected(c.cursor.x);
if (end == 0) break;
c.cursor.x = textLine->findRevSelected(end);
recordDelete(c.cursor, end - c.cursor.x);
} while (true);
end = c.cursor.x;
c.cursor.x = textLine->length();
if (textLine->isSelected()) recordAction(KateAction::delLine,c.cursor);
}
c.cursor.y++;
/*if (end < c.cursor.x)*/ c.cursor.x = end;
selectEnd = -1;
select.x = -1;
/*if (undo)*/ recordEnd(c);
}
void KateDocument::tagLineRange(int line, int x1, int x2) {
int z;
for (z = 0; z < (int) views.count(); z++) {
views.at(z)->tagLines(line, line, x1, x2);
}
}
void KateDocument::tagLines(int start, int end) {
int z;
for (z = 0; z < (int) views.count(); z++) {
views.at(z)->tagLines(start, end, 0, 0xffffff);
}
}
void KateDocument::tagAll() {
int z;
for (z = 0; z < (int) views.count(); z++) {
views.at(z)->tagAll();
}
}
void KateDocument::updateLines(int startLine, int endLine, int flags, int cursorY) {
TextLine::Ptr textLine;
int line, last_line;
int ctxNum, endCtx;
// kdDebug(13020)<<"******************KateDocument::updateLines Checkpoint 1"<<endl;
if (buffer->line(startLine)==0) {kdDebug(13020)<<"********************No buffer for line " << startLine << " found**************"<<endl; return;};
// kdDebug(13020)<<"KateDocument::updateLines Checkpoint 2"<<endl;
last_line = lastLine();
// if (endLine >= last_line) endLine = last_line;
line = startLine;
ctxNum = 0;
if (line > 0) ctxNum = getTextLine(line - 1)->getContext();
do {
// kdDebug(13020)<<QString("**************Working on line: %1").arg(line)<<endl;
textLine = getTextLine(line);
if (textLine==0) kdDebug(13020)<<"****updateLines()>> error textLine==0"<<endl;
if (line <= endLine && line != cursorY) {
if (flags & KateView::cfRemoveSpaces) textLine->removeSpaces();
updateMaxLength(textLine);
}
endCtx = textLine->getContext();
// odebug << "DOHIGHLIGHT" << oendl;
ctxNum = m_highlight->doHighlight(ctxNum,textLine);
textLine->setContext(ctxNum);
line++;
} while ((buffer->line(line)!=0) && (line <= endLine || endCtx != ctxNum));
// kdDebug(13020)<<"updateLines :: while loop left"<<endl;
tagLines(startLine, line - 1);
}
void KateDocument::updateMaxLength(TextLine::Ptr &textLine) {
int len;
len = textWidth(textLine,textLine->length());
if (len > maxLength) {
longestLine = textLine;
maxLength = len;
newDocGeometry = true;
} else {
if (!longestLine || (textLine == longestLine && len <= maxLength*3/4)) {
maxLength = -1;
for (int i = 0; i < numLines();i++) {
textLine = getTextLine(i);
len = textWidth(textLine,textLine->length());
if (len > maxLength) {
maxLength = len;
longestLine = textLine;
}
}
newDocGeometry = true;
}
}
}
void KateDocument::slotBufferChanged() {
newDocGeometry = true;
//updateLines();//JW
updateViews();
}
void KateDocument::slotBufferHighlight(long start,long stop) {
kdDebug(13020)<<"KateDocument::slotBufferHighlight"<<QString("%1-%2").arg(start).arg(stop)<<endl;
updateLines(start,stop);
// buffer->startLoadTimer();
}
void KateDocument::updateViews(KateView *exclude) {
KateView *view;
int flags;
bool markState = hasMarkedText();
flags = (newDocGeometry) ? KateView::ufDocGeometry : 0;
for (view = views.first(); view != 0L; view = views.next() ) {
if (view != exclude) view->updateView(flags);
// notify every view about the changed mark state....
if (oldMarkState != markState) emit view->newMarkStatus();
}
oldMarkState = markState;
newDocGeometry = false;
}
QColor &KateDocument::cursorCol(int x, int y) {
int attr;
Attribute *a;
TextLine::Ptr textLine = getTextLine(y);
attr = textLine->getRawAttr(x);
a = &m_attribs[attr & taAttrMask];
if (attr & taSelected) return a->selCol; else return a->col;
}
void KateDocument::paintTextLine(QPainter &paint, int line, int xStart, int xEnd, bool showTabs)
{
paintTextLine (paint, line, 0, xStart, xEnd, showTabs);
}
void KateDocument::paintTextLine(QPainter &paint, int line, int y, int xStart, int xEnd, bool showTabs)
{
TextLine::Ptr textLine;
int len;
const QChar *s;
int z, x;
QChar ch;
- Attribute *a = 0L;
+ Attribute *attrptr = 0L;
int attr, nextAttr;
int xs;
int xc, zc;
if (line > lastLine()) {
paint.fillRect(0, y, xEnd - xStart,fontHeight, colors[0]);
return;
}
textLine = getTextLine(line);
len = textLine->length();
s = textLine->getText();
// skip to first visible character
x = 0;
z = 0;
do {
xc = x;
zc = z;
if (z == len) break;
ch = s[z];//textLine->getChar(z);
if (ch == '\t') {
x += m_tabWidth - (x % m_tabWidth);
} else {
- a = &m_attribs[textLine->getAttr(z)];
+ attrptr = &m_attribs[textLine->getAttr(z)];
- if (a->bold && a->italic)
+ if (attrptr->bold && attrptr->italic)
x += myFontMetricsBI.width(ch);
- else if (a->bold)
+ else if (attrptr->bold)
x += myFontMetricsBold.width(ch);
- else if (a->italic)
+ else if (attrptr->italic)
x += myFontMetricsItalic.width(ch);
else
x += myFontMetrics.width(ch);
}
z++;
} while (x <= xStart);
// draw background
xs = xStart;
attr = textLine->getRawAttr(zc);
while (x < xEnd)
{
nextAttr = textLine->getRawAttr(z);
if ((nextAttr ^ attr) & taSelected)
{
if (attr & taSelected)
paint.fillRect(xs - xStart, y, x - xs, fontHeight, colors[1]);
else
paint.fillRect(xs - xStart, y, x - xs, fontHeight, colors[0]);
xs = x;
attr = nextAttr;
}
if (z == len) break;
ch = s[z];//textLine->getChar(z);
if (ch == '\t')
x += m_tabWidth - (x % m_tabWidth);
else
{
- a = &m_attribs[textLine->getAttr(z)];
+ attrptr = &m_attribs[textLine->getAttr(z)];
- if (a->bold && a->italic)
+ if (attrptr->bold && attrptr->italic)
x += myFontMetricsBI.width(ch);
- else if (a->bold)
+ else if (attrptr->bold)
x += myFontMetricsBold.width(ch);
- else if (a->italic)
+ else if (attrptr->italic)
x += myFontMetricsItalic.width(ch);
else
x += myFontMetrics.width(ch);
}
z++;
}
if (attr & taSelected)
paint.fillRect(xs - xStart, y, xEnd - xs, fontHeight, colors[1]);
else
paint.fillRect(xs - xStart, y, xEnd - xs, fontHeight, colors[0]);
len = z; //reduce length to visible length
// draw text
x = xc;
z = zc;
y += fontAscent;// -1;
attr = -1;
while (z < len) {
ch = s[z];//textLine->getChar(z);
if (ch == '\t') {
if (z > zc) {
//this should cause no copy at all
QConstString str((QChar *) &s[zc], z - zc /*+1*/);
QString s = str.string();
paint.drawText(x - xStart, y, s);
- if (a->bold && a->italic)
+ if (attrptr && attrptr->bold && attrptr->italic)
x += myFontMetricsBI.width(s);
- else if (a->bold)
+ else if (attrptr && attrptr->bold)
x += myFontMetricsBold.width(s);
- else if (a->italic)
+ else if (attrptr && attrptr->italic)
x += myFontMetricsItalic.width(s);
else
x += myFontMetrics.width(s);
}
zc = z +1;
if (showTabs) {
nextAttr = textLine->getRawAttr(z);
if (nextAttr != attr) {
attr = nextAttr;
- a = &m_attribs[attr & taAttrMask];
+ attrptr = &m_attribs[attr & taAttrMask];
- if (attr & taSelected) paint.setPen(a->selCol);
- else paint.setPen(a->col);
+ if (attr & taSelected) paint.setPen(attrptr->selCol);
+ else paint.setPen(attrptr->col);
- if (a->bold && a->italic)
+ if (attrptr->bold && attrptr->italic)
paint.setFont(myFontBI);
- else if (a->bold)
+ else if (attrptr->bold)
paint.setFont(myFontBold);
- else if (a->italic)
+ else if (attrptr->italic)
paint.setFont(myFontItalic);
else
paint.setFont(myFont);
}
-// paint.drawLine(x - xStart, y -2, x - xStart, y);
-// paint.drawLine(x - xStart, y, x - xStart + 2, y);
paint.drawPoint(x - xStart, y);
paint.drawPoint(x - xStart +1, y);
paint.drawPoint(x - xStart, y -1);
}
x += m_tabWidth - (x % m_tabWidth);
} else {
nextAttr = textLine->getRawAttr(z);
if (nextAttr != attr) {
if (z > zc) {
QConstString str((QChar *) &s[zc], z - zc /*+1*/);
QString s = str.string();
paint.drawText(x - xStart, y, s);
- if (a->bold && a->italic)
+ if (attrptr->bold && attrptr->italic)
x += myFontMetricsBI.width(s);
- else if (a->bold)
+ else if (attrptr->bold)
x += myFontMetricsBold.width(s);
- else if (a->italic)
+ else if (attrptr->italic)
x += myFontMetricsItalic.width(s);
else
x += myFontMetrics.width(s);
zc = z;
}
attr = nextAttr;
- a = &m_attribs[attr & taAttrMask];
+ attrptr = &m_attribs[attr & taAttrMask];
- if (attr & taSelected) paint.setPen(a->selCol);
- else paint.setPen(a->col);
+ if (attr & taSelected) paint.setPen(attrptr->selCol);
+ else paint.setPen(attrptr->col);
- if (a->bold && a->italic)
+ if (attrptr->bold && attrptr->italic)
paint.setFont(myFontBI);
- else if (a->bold)
+ else if (attrptr->bold)
paint.setFont(myFontBold);
- else if (a->italic)
+ else if (attrptr->italic)
paint.setFont(myFontItalic);
else
paint.setFont(myFont);
}
}
z++;
}
if (z > zc) {
QConstString str((QChar *) &s[zc], z - zc /*+1*/);
paint.drawText(x - xStart, y, str.string());
}
}
// Applies the search context, and returns whether a match was found. If one is,
// the length of the string matched is also returned.
bool KateDocument::doSearch(SConfig &sc, const QString &searchFor) {
int line, col;
int searchEnd;
int bufLen, tlen;
QChar *t;
TextLine::Ptr textLine;
int pos, newPos;
if (searchFor.isEmpty()) return false;
bufLen = 0;
t = 0L;
line = sc.cursor.y;
col = sc.cursor.x;
if (!(sc.flags & KateView::sfBackward)) {
//forward search
if (sc.flags & KateView::sfSelected) {
if (line < selectStart) {
line = selectStart;
col = 0;
}
searchEnd = selectEnd;
} else searchEnd = lastLine();
while (line <= searchEnd) {
textLine = getTextLine(line);
tlen = textLine->length();
if (tlen > bufLen) {
delete [] t;
bufLen = (tlen + 255) & (~255);
t = new QChar[bufLen];
- }
+ } else if (!t)
+ t = new QChar[bufLen];
+
memcpy(t, textLine->getText(), tlen*sizeof(QChar));
if (sc.flags & KateView::sfSelected) {
pos = 0;
do {
pos = textLine->findSelected(pos);
newPos = textLine->findUnselected(pos);
memset(&t[pos], 0, (newPos - pos)*sizeof(QChar));
pos = newPos;
} while (pos < tlen);
}
QString text(t, tlen);
if (sc.flags & KateView::sfWholeWords) {
// Until the end of the line...
while (col < tlen) {
// ...find the next match.
col = sc.search(text, col);
if (col != -1) {
// Is the match delimited correctly?
if (((col == 0) || (!m_highlight->isInWord(t[col]))) &&
((col + sc.matchedLength == tlen) || (!m_highlight->isInWord(t[col + sc.matchedLength])))) {
goto found;
}
else {
// Start again from the next character.
col++;
}
}
else {
// No match.
break;
}
}
}
else {
// Non-whole-word search.
col = sc.search(text, col);
if (col != -1)
goto found;
}
col = 0;
line++;
}
} else {
// backward search
if (sc.flags & KateView::sfSelected) {
if (line > selectEnd) {
line = selectEnd;
col = -1;
}
searchEnd = selectStart;
} else searchEnd = 0;
while (line >= searchEnd) {
textLine = getTextLine(line);
tlen = textLine->length();
if (tlen > bufLen) {
delete [] t;
bufLen = (tlen + 255) & (~255);
t = new QChar[bufLen];
- }
+ } else if (!t)
+ t = new QChar[bufLen];
memcpy(t, textLine->getText(), tlen*sizeof(QChar));
if (sc.flags & KateView::sfSelected) {
pos = 0;
do {
pos = textLine->findSelected(pos);
newPos = textLine->findUnselected(pos);
memset(&t[pos], 0, (newPos - pos)*sizeof(QChar));
pos = newPos;
} while (pos < tlen);
}
if (col < 0 || col > tlen) col = tlen;
QString text(t, tlen);
if (sc.flags & KateView::sfWholeWords) {
// Until the beginning of the line...
while (col >= 0) {
// ...find the next match.
col = sc.search(text, col);
if (col != -1) {
// Is the match delimited correctly?
if (((col == 0) || (!m_highlight->isInWord(t[col]))) &&
((col + sc.matchedLength == tlen) || (!m_highlight->isInWord(t[col + sc.matchedLength])))) {
goto found;
}
else {
// Start again from the previous character.
col--;
}
}
else {
// No match.
break;
}
}
}
else {
// Non-whole-word search.
col = sc.search(text, col);
if (col != -1)
goto found;
}
col = -1;
line--;
}
}
sc.flags |= KateView::sfWrapped;
return false;
found:
if (sc.flags & KateView::sfWrapped) {
if ((line > sc.startCursor.y || (line == sc.startCursor.y && col >= sc.startCursor.x))
^ ((sc.flags & KateView::sfBackward) != 0)) return false;
}
sc.cursor.x = col;
sc.cursor.y = line;
return true;
}
void KateDocument::tagLine(int line) {
if (tagStart > line) tagStart = line;
if (tagEnd < line) tagEnd = line;
}
void KateDocument::insLine(int line) {
KateView *view;
if (selectStart >= line) selectStart++;
if (selectEnd >= line) selectEnd++;
if (tagStart >= line) tagStart++;
if (tagEnd >= line) tagEnd++;
newDocGeometry = true;
for (view = views.first(); view != 0L; view = views.next() ) {
view->insLine(line);
}
}
void KateDocument::delLine(int line) {
KateView *view;
if (selectStart >= line && selectStart > 0) selectStart--;
if (selectEnd >= line) selectEnd--;
if (tagStart >= line && tagStart > 0) tagStart--;
if (tagEnd >= line) tagEnd--;
newDocGeometry = true;
for (view = views.first(); view != 0L; view = views.next() ) {
view->delLine(line);
}
}
void KateDocument::optimizeSelection() {
TextLine::Ptr textLine;
while (selectStart <= selectEnd) {
textLine = getTextLine(selectStart);
if (textLine->isSelected() || textLine->numSelected() > 0) break;
selectStart++;
}
while (selectEnd >= selectStart) {
textLine = getTextLine(selectEnd);
if (textLine->isSelected() || textLine->numSelected() > 0) break;
selectEnd--;
}
if (selectStart > selectEnd) {
selectStart = 0xffffff;
selectEnd = 0;
}
}
void KateDocument::doAction(KateAction *a) {
switch (a->action) {
case KateAction::replace:
doReplace(a);
break;
case KateAction::wordWrap:
doWordWrap(a);
break;
case KateAction::wordUnWrap:
doWordUnWrap(a);
break;
case KateAction::newLine:
doNewLine(a);
break;
case KateAction::delLine:
doDelLine(a);
break;
case KateAction::insLine:
doInsLine(a);
break;
case KateAction::killLine:
doKillLine(a);
break;
/* case KateAction::doubleLine:
break;
case KateAction::removeLine:
break;*/
}
}
void KateDocument::doReplace(KateAction *a) {
TextLine::Ptr textLine;
int l;
//exchange current text with stored text in KateAction *a
textLine = getTextLine(a->cursor.y);
l = textLine->length() - a->cursor.x;
if (l > a->len) l = a->len;
QString oldText(&textLine->getText()[a->cursor.x], (l < 0) ? 0 : l);
textLine->replace(a->cursor.x, a->len, a->text.unicode(), a->text.length());
a->len = a->text.length();
a->text = oldText;
buffer->changeLine(a->cursor.y);
tagLine(a->cursor.y);
}
void KateDocument::doWordWrap(KateAction *a) {
TextLine::Ptr textLine;
textLine = getTextLine(a->cursor.y - 1);
a->len = textLine->length() - a->cursor.x;
textLine->wrap(getTextLine(a->cursor.y),a->len);
buffer->changeLine(a->cursor.y - 1);
buffer->changeLine(a->cursor.y);
tagLine(a->cursor.y - 1);
tagLine(a->cursor.y);
if (selectEnd == a->cursor.y - 1) selectEnd++;
a->action = KateAction::wordUnWrap;
}
void KateDocument::doWordUnWrap(KateAction *a) {
TextLine::Ptr textLine;
textLine = getTextLine(a->cursor.y - 1);
// textLine->setLength(a->len);
textLine->unWrap(a->len, getTextLine(a->cursor.y),a->cursor.x);
buffer->changeLine(a->cursor.y - 1);
buffer->changeLine(a->cursor.y);
tagLine(a->cursor.y - 1);
tagLine(a->cursor.y);
a->action = KateAction::wordWrap;
}
void KateDocument::doNewLine(KateAction *a) {
TextLine::Ptr textLine, newLine;
textLine = getTextLine(a->cursor.y);
newLine = new TextLine(textLine->getRawAttr(), textLine->getContext());
textLine->wrap(newLine,a->cursor.x);
buffer->insertLine(a->cursor.y + 1, newLine);
buffer->changeLine(a->cursor.y);
insLine(a->cursor.y + 1);
tagLine(a->cursor.y);
tagLine(a->cursor.y + 1);
if (selectEnd == a->cursor.y) selectEnd++;//addSelection(a->cursor.y + 1);
a->action = KateAction::delLine;
}
void KateDocument::doDelLine(KateAction *a) {
TextLine::Ptr textLine, nextLine;
textLine = getTextLine(a->cursor.y);
nextLine = getTextLine(a->cursor.y+1);
// textLine->setLength(a->cursor.x);
textLine->unWrap(a->cursor.x, nextLine,nextLine->length());
textLine->setContext(nextLine->getContext());
if (longestLine == nextLine) longestLine = 0L;
buffer->changeLine(a->cursor.y);
buffer->removeLine(a->cursor.y+1);
tagLine(a->cursor.y);
delLine(a->cursor.y + 1);
a->action = KateAction::newLine;
}
void KateDocument::doInsLine(KateAction *a) {
buffer->insertLine(a->cursor.y, new TextLine());
insLine(a->cursor.y);
a->action = KateAction::killLine;
}
void KateDocument::doKillLine(KateAction *a) {
TextLine::Ptr textLine = getTextLine(a->cursor.y);
if (longestLine == textLine) longestLine = 0L;
buffer->removeLine(a->cursor.y);
delLine(a->cursor.y);
tagLine(a->cursor.y);
a->action = KateAction::insLine;
}
void KateDocument::newUndo() {
KTextEditor::View *view;
int state;
state = 0;
if (currentUndo > 0) state |= 1;
if (currentUndo < (int) undoList.count()) state |= 2;
undoState = state;
for (view = m_views.first(); view != 0L; view = m_views.next() ) {
emit static_cast<KateView *>( view )->newUndo();
}
}
void KateDocument::recordStart(VConfig &c, int newUndoType) {
recordStart(c.view, c.cursor, c.flags, newUndoType);
}
void KateDocument::recordStart(KateView *, PointStruc &cursor, int flags,
int newUndoType, bool keepModal, bool mergeUndo) {
KateActionGroup *g;
// if (newUndoType == KateActionGroup::ugNone) {
// only a bug would cause this
//why should someone do this? we can't prevent all programming errors :) (jochen whilhelmy)
// debug("KateDocument::recordStart() called with no undo group type!");
// return;
// }
if (!keepModal) setPseudoModal(0L);
//i optimized the group undo stuff a bit (jochen wilhelmy)
// recordReset() is not needed any more
g = undoList.getLast();
if (g != 0L && ((undoCount < 1024 && flags & KateView::cfGroupUndo
&& g->end.x == cursor.x && g->end.y == cursor.y) || mergeUndo)) {
//undo grouping : same actions are put into one undo step
//precondition : new action starts where old stops or mergeUndo flag
if (g->undoType == newUndoType
|| (g->undoType == KateActionGroup::ugInsChar
&& newUndoType == KateActionGroup::ugInsLine)
|| (g->undoType == KateActionGroup::ugDelChar
&& newUndoType == KateActionGroup::ugDelLine)) {
undoCount++;
if (g->undoType != newUndoType) undoCount = 0xffffff;
return;
}
}
undoCount = 0;
/*
if (undoView != view) {
// always kill the current undo group if the editing view changes
recordReset();
undoType = newUndoType;
} else if (newUndoType == undoType) {
printf("bla!!!\n");
// same as current type, keep using it
return;
} else if ( (undoType == KateActionGroup::ugInsChar && newUndoType == KateActionGroup::ugInsLine) ||
(undoType == KateActionGroup::ugDelChar && newUndoType == KateActionGroup::ugDelLine) ) {
// some type combinations can run together...
undoType += 1000;
return;
} else {
recordReset();
undoType = newUndoType;
}
undoView = view;
*/
while ((int) undoList.count() > currentUndo) undoList.removeLast();
while ((int) undoList.count() > undoSteps) {
undoList.removeFirst();
currentUndo--;
}
g = new KateActionGroup(cursor, newUndoType);
undoList.append(g);
// currentUndo++;
tagEnd = 0;
tagStart = 0xffffff;
}
void KateDocument::recordAction(KateAction::Action action, PointStruc &cursor) {
KateAction *a;
a = new KateAction(action, cursor);
doAction(a);
undoList.getLast()->insertAction(a);
}
void KateDocument::recordInsert(VConfig &c, const QString &text) {
recordReplace(c, 0, text);
}
void KateDocument::recordReplace(VConfig &c, int len, const QString &text) {
if (c.cursor.x > 0 && !(c.flags & KateView::cfSpaceIndent)) {
TextLine::Ptr textLine = getTextLine(c.cursor.y);
if (textLine->length() == 0) {
QString s = tabString(c.cursor.x, tabChars);
int len = s.length();
s += text;
c.cursor.x = 0;
recordReplace(c.cursor, len, s);
c.cursor.x = len;
return;
}
}
recordReplace(c.cursor, len, text);
}
void KateDocument::recordInsert(PointStruc &cursor, const QString &text) {
recordReplace(cursor, 0, text);
}
void KateDocument::recordDelete(PointStruc &cursor, int len) {
recordReplace(cursor, len, QString::null);
}
void KateDocument::recordReplace(PointStruc &cursor, int len, const QString &text) {
KateAction *a;
TextLine::Ptr textLine;
int l;
if (len == 0 && text.isEmpty()) return;
//try to append to last replace action
a = undoList.getLast()->action;
if (a == 0L || a->action != KateAction::replace
|| a->cursor.x + a->len != cursor.x || a->cursor.y != cursor.y) {
//if (a != 0L) printf("new %d %d\n", a->cursor.x + a->len, cursor.x);
a = new KateAction(KateAction::replace, cursor);
undoList.getLast()->insertAction(a);
}
//replace
textLine = getTextLine(cursor.y);
l = textLine->length() - cursor.x;
if (l > len) l = len;
a->text.insert(a->text.length(), &textLine->getText()[cursor.x], (l < 0) ? 0 : l);
textLine->replace(cursor.x, len, text.unicode(), text.length());
a->len += text.length();
buffer->changeLine(a->cursor.y);
updateMaxLength(textLine);
tagLine(a->cursor.y);
}
void KateDocument::recordEnd(VConfig &c) {
recordEnd(c.view, c.cursor, c.flags);
}
void KateDocument::recordEnd(KateView *view, PointStruc &cursor, int flags) {
KateActionGroup *g;
// clear selection if option "persistent selections" is off
// if (!(flags & cfPersistent)) deselectAll();
g = undoList.getLast();
if (g->action == 0L) {
// no action has been done: remove empty undo record
undoList.removeLast();
return;
}
// store end cursor position for redo
g->end = cursor;
currentUndo = undoList.count();
if (tagStart <= tagEnd) {
optimizeSelection();
updateLines(tagStart, tagEnd, flags, cursor.y);
setModified(true);
}
view->updateCursor(cursor, flags);
// newUndo();
/*
undoCount++;
// we limit the number of individual undo operations for sanity - is 1K reasonable?
// this is also where we handle non-group undo preference
// if the undo type is singlular, we always finish it now
if ( undoType == KateActionGroup::ugPaste ||
undoType == KateActionGroup::ugDelBlock ||
undoType > 1000 ||
undoCount > 1024 || !(flags & cfGroupUndo) ) {
printf("recordend %d %d\n", undoType, undoCount);
recordReset();
}
*/
// this should keep the flood of signals down a little...
if (undoCount == 0) newUndo();
emit textChanged();
}
/*
void KateDocument::recordReset()
{
if (pseudoModal)
return;
// forces the next call of recordStart() to begin a new undo group
// not used in normal editing, but used by markFound(), etc.
undoType = KateActionGroup::ugNone;
undoCount = 0;
undoView = NULL;
undoReported = false;
printf("recordreset\n");
}
*/
/*
void KateDocument::recordDel(PointStruc &cursor, TextLine::Ptr &textLine, int l) {
int len;
len = textLine->length() - cursor.x;
if (len > l) len = l;
if (len > 0) {
insertUndo(new KateAction(KateAction::replace,cursor,&textLine->getText()[cursor.x],len));
}
}
*/
void KateDocument::doActionGroup(KateActionGroup *g, int flags, bool undo) {
KateAction *a, *next;
setPseudoModal(0L);
if (!(flags & KateView::cfPersistent)) deselectAll();
tagEnd = 0;
tagStart = 0xffffff;
a = g->action;
g->action = 0L;
while (a) {
doAction(a);
next = a->next;
g->insertAction(a);
a = next;
}
optimizeSelection();
if (tagStart <= tagEnd) updateLines(tagStart, tagEnd, flags);
// the undo/redo functions set undo to true, all others should leave it
// alone (default)
if (!undo) {
setModified(true);
newUndo();
}
}
int KateDocument::nextUndoType()
{
KateActionGroup *g;
if (currentUndo <= 0) return KateActionGroup::ugNone;
g = undoList.at(currentUndo - 1);
return g->undoType;
}
int KateDocument::nextRedoType()
{
KateActionGroup *g;
if (currentUndo >= (int) undoList.count()) return KateActionGroup::ugNone;
g = undoList.at(currentUndo);
// if (!g) return KateActionGroup::ugNone;
return g->undoType;
}
void KateDocument::undoTypeList(QValueList<int> &lst)
{
lst.clear();
for (int i = currentUndo-1; i>=0 ;i--)
lst.append(undoList.at(i)->undoType);
}
void KateDocument::redoTypeList(QValueList<int> &lst)
{
lst.clear();
for (int i = currentUndo+1; i<(int)undoList.count(); i++)
lst.append(undoList.at(i)->undoType);
}
void KateDocument::undo(VConfig &c, int count) {
KateActionGroup *g = 0L;
int num;
bool needUpdate = false; // don't update the cursor until completely done
if (count <= 0) return;
for (num = 0 ; num < count ; num++) {
if (currentUndo <= 0) break;
currentUndo--;
g = undoList.at(currentUndo);
doActionGroup(g, c.flags, true); // do not setModified() or newUndo()
needUpdate = true;
// if (num == 0) recordReset();
}
if (needUpdate) {
// since we told doActionGroup() not to do this stuff, we need to do it now
c.view->updateCursor(g->start);
setModified(true);
newUndo();
}
}
void KateDocument::redo(VConfig &c, int count) {
KateActionGroup *g = 0L;
int num;
bool needUpdate = false; // don't update the cursor until completely done
if (count <= 0) return;
for (num = 0 ; num < count ; num++) {
if (currentUndo+1 > (int)undoList.count()) break;
g = undoList.at(currentUndo);
currentUndo++;
doActionGroup(g, c.flags, true); // do not setModified() or newUndo()
needUpdate = true;
// if (num == 0) recordReset();
}
if (needUpdate) {
// since we told doActionGroup() not to do this stuff, we need to do it now
c.view->updateCursor(g->end);
setModified(true);
newUndo();
}
}
void KateDocument::clearRedo() {
// disable redos
// this was added as an assist to the spell checker
bool deleted = false;
while ((int) undoList.count() > currentUndo) {
deleted = true;
undoList.removeLast();
}
if (deleted) newUndo();
}
void KateDocument::setUndoSteps(int steps) {
if (steps < 5) steps = 5;
undoSteps = steps;
}
void KateDocument::setPseudoModal(QWidget *w) {
// QWidget *old = pseudoModal;
// (glenebob)
// this is a temporary hack to make the spell checker work a little
// better - as kspell progresses, this sort of thing should become
// obsolete or worked around more cleanly
// this is relied upon *only* by the spell-check code
if (pseudoModal && pseudoModal != (QWidget*)1L)
delete pseudoModal;
// pseudoModal = 0L;
// if (old || w) recordReset();
pseudoModal = w;
}
void KateDocument::newBracketMark(PointStruc &cursor, BracketMark &bm)
{
TextLine::Ptr textLine;
int x, line, count, attr;
QChar bracket, opposite, ch;
Attribute *a;
bm.eXPos = -1; //mark bracked mark as invalid
x = cursor.x -1; // -1 to look at left side of cursor
if (x < 0) return;
line = cursor.y; //current line
count = 0; //bracket counter for nested brackets
textLine = getTextLine(line);
if (!textLine) return;
bracket = textLine->getChar(x);
attr = textLine->getAttr(x);
if (bracket == '(' || bracket == '[' || bracket == '{')
{
//get opposite bracket
opposite = ')';
if (bracket == '[') opposite = ']';
if (bracket == '{') opposite = '}';
//get attribute of bracket (opposite bracket must have the same attribute)
x++;
while (line - cursor.y < 40) {
//go to next line on end of line
while (x >= (int) textLine->length()) {
line++;
if (line > lastLine()) return;
textLine = getTextLine(line);
x = 0;
}
if (textLine->getAttr(x) == attr) {
//try to find opposite bracked
ch = textLine->getChar(x);
if (ch == bracket) count++; //same bracket : increase counter
if (ch == opposite) {
count--;
if (count < 0) goto found;
}
}
x++;
}
}
else if (bracket == ')' || bracket == ']' || bracket == '}')
{
opposite = '(';
if (bracket == ']') opposite = '[';
if (bracket == '}') opposite = '{';
x--;
while (cursor.y - line < 20) {
while (x < 0) {
line--;
if (line < 0) return;
textLine = getTextLine(line);
x = textLine->length() -1;
}
if (textLine->getAttr(x) == attr) {
ch = textLine->getChar(x);
if (ch == bracket) count++;
if (ch == opposite) {
count--;
if (count < 0) goto found;
}
}
x--;
}
}
return;
found:
//cursor position of opposite bracket
bm.cursor.x = x;
bm.cursor.y = line;
//x position (start and end) of related bracket
bm.sXPos = textWidth(textLine, x);
a = &m_attribs[attr];
if (a->bold && a->italic)
bm.eXPos = bm.sXPos + myFontMetricsBI.width(bracket);
else if (a->bold)
bm.eXPos = bm.sXPos + myFontMetricsBold.width(bracket);
else if (a->italic)
bm.eXPos = bm.sXPos + myFontMetricsItalic.width(bracket);
else
bm.eXPos = bm.sXPos + myFontMetrics.width(bracket);
}
void KateDocument::clipboardChanged() { //slot
//#if defined(_WS_X11_)
if (m_singleSelection) {
disconnect(QApplication::clipboard(), SIGNAL(dataChanged()),
this, SLOT(clipboardChanged()));
deselectAll();
updateViews();
}
//#endif
}
#if 0
void KateDocument::guiActivateEvent( KParts::GUIActivateEvent *ev )
{
KParts::ReadWritePart::guiActivateEvent( ev );
if ( ev->activated() )
emit selectionChanged();
}
#endif
void KateDocument::setDocName (QString docName)
{
myDocName = docName;
emit nameChanged (this);
}
void KateDocument::setDocFile (QString docFile)
{
m_file = docFile;
emit fileNameChanged ();
}
void KateDocument::setMTime()
{
if (fileInfo && !fileInfo->fileName().isEmpty()) {
fileInfo->refresh();
mTime = fileInfo->lastModified();
}
}
void KateDocument::isModOnHD(bool forceReload)
{
if (fileInfo && !fileInfo->fileName().isEmpty()) {
fileInfo->refresh();
if (fileInfo->lastModified() > mTime) {
if ( forceReload ||
(KMessageBox::warningContinueCancel(0,
(i18n("The file %1 has changed on disk.\nDo you want to reload it?\n\nIf you cancel you will lose these changes next time you save this file")).arg(m_url),
i18n("File has changed on Disk"),
i18n("Yes") ) == KMessageBox::Continue)
)
reloadFile();
else
setMTime();
}
}
}
void KateDocument::reloadFile()
{
#warning fixme
#if 0
if (fileInfo && !fileInfo->fileName().isEmpty()) {
KateDocument::openFile();
setMTime();
}
#endif
}
void KateDocument::slotModChanged()
{
emit modStateChanged (this);
}
QList<Kate::Mark> KateDocument::marks ()
{
QList<Kate::Mark> list;
TextLine::Ptr line;
for (int i=0; i < numLines(); i++)
{
line = getTextLine(i);
if (line->mark() != 0)
{
Kate::Mark *mark=new Kate::Mark;
mark->line = i;
mark->type = line->mark();
list.append (mark);
}
}
return list;
}
void KateDocument::flush ()
{
if (isReadOnly())
return;
m_url = QString::null;
fileInfo->setFile (QString());
setMTime();
clear();
updateViews();
emit fileNameChanged ();
}
void KateDocument::open (const QString &name)
{
openURL (name);
}
void KateDocument::wrapText (uint col)
{
int line = 0;
int z = 0;
while(true)
{
TextLine::Ptr l = getTextLine(line);
if (l->length() > col)
{
TextLine::Ptr tl = new TextLine();
buffer->insertLine(line+1,tl);
const QChar *text = l->getText();
for (z=col; z>0; z--)
{
if (z < 1) break;
if (text[z].isSpace()) break;
}
if (z < 1) z=col;
l->wrap (tl, z);
}
line++;
if (line >= numLines()) break;
};
newDocGeometry=true;
updateLines();
updateViews();
}
void KateDocument::setWordWrap (bool on)
{
if (on != myWordWrap && on)
wrapText (myWordWrapAt);
myWordWrap = on;
}
void KateDocument::setWordWrapAt (uint col)
{
if (myWordWrapAt != col && myWordWrap)
wrapText (myWordWrapAt);
myWordWrapAt = col;
}
void KateDocument::applyWordWrap ()
{
wrapText (myWordWrapAt);
}
diff --git a/noncore/settings/sysinfo/devicesinfo.cpp b/noncore/settings/sysinfo/devicesinfo.cpp
index 164d608..428cfd4 100644
--- a/noncore/settings/sysinfo/devicesinfo.cpp
+++ b/noncore/settings/sysinfo/devicesinfo.cpp
@@ -1,433 +1,433 @@
/*
                This file is part of the Opie Project
=. Copyright (C) 2005 Michael 'Mickey' Lauer <mickey@Vanille.de>
.=l. Copyright (C) The Opie Team <opie-devel@handhelds.org>
         .>+-=
_;:,     .>    :=|. This program is free software; you can
.> <`_,   >  .   <= redistribute it and/or modify it under
:`=1 )Y*s>-.--   : the terms of the GNU General Public
.="- .-=="i,     .._ License as published by the Free Software
- .   .-<_>     .<> Foundation; version 2 of the License.
   ._= =}       :
  .%`+i>       _;_.
  .i_,=:_.      -<s. 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 application; see the file LICENSE.GPL.
If not, write to the Free Software Foundation,
Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA.
*/
#include "devicesinfo.h"
/* OPIE */
#include <opie2/odebug.h>
#include <opie2/oinputsystem.h>
#include <opie2/opcmciasystem.h>
#include <opie2/olayout.h>
#include <opie2/olistview.h>
#include <qpe/qpeapplication.h>
using namespace Opie::Core;
using namespace Opie::Ui;
/* QT */
#include <qobjectlist.h>
#include <qlistview.h>
#include <qcombobox.h>
#include <qfile.h>
#include <qpushbutton.h>
#include <qstringlist.h>
#include <qtextstream.h>
#include <qtextview.h>
#include <qtimer.h>
#include <qwhatsthis.h>
//=================================================================================================
DevicesView::DevicesView( QWidget* parent, const char* name, WFlags fl )
:Opie::Ui::OListView( parent, name, fl )
{
addColumn( tr( "My Computer" ) );
setAllColumnsShowFocus( true );
setRootIsDecorated( true );
QWhatsThis::add( this, tr( "This is a list of all the devices currently recognized on this device." ) );
DevicesView* root = this;
( new CpuCategory( root ) )->populate();
( new InputCategory( root ) )->populate();
( new CardsCategory( root ) )->populate();
( new UsbCategory( root ) )->populate();
connect( this, SIGNAL(selectionChanged(QListViewItem*)), this, SLOT(selectionChanged(QListViewItem*)) );
}
DevicesView::~DevicesView()
{
}
void DevicesView::selectionChanged( QListViewItem* item )
{
odebug << "DevicesView::selectionChanged to '" << item->text( 0 ) << "'" << oendl;
if ( item->parent() )
{
QWidget* details = ( static_cast<Device*>( item ) )->detailsWidget();
( static_cast<DevicesInfo*>( parent() ) )->setDetailsWidget( details );
}
else
{
odebug << "DevicesView::not a device node." << oendl;
}
}
//=================================================================================================
DevicesInfo::DevicesInfo( QWidget* parent, const char* name, WFlags fl )
:QWidget( parent, name, fl ), details( 0 )
{
layout = new OAutoBoxLayout( this );
layout->setSpacing( 2 );
layout->setMargin( 2 );
view = new DevicesView( this );
layout->addWidget( view, 100 );
stack = new QWidgetStack( this );
layout->addWidget( stack, 80 );
}
DevicesInfo::~DevicesInfo()
{
}
void DevicesInfo::setDetailsWidget( QWidget* w )
{
if ( details )
{
qDebug( "hiding widget '%s' ('%s')", details->name(), details->className() );
stack->removeWidget( w );
}
stack->addWidget( details = w, 40 );
stack->raiseWidget( details );
}
//=================================================================================================
Category::Category( DevicesView* parent, const QString& name )
:OListViewItem( parent, name )
{
odebug << "Category '" << name << "' inserted. Scanning for devices..." << oendl;
}
Category::~Category()
{
}
//=================================================================================================
CpuCategory::CpuCategory( DevicesView* parent )
:Category( parent, "1. Central Processing Unit" )
{
}
CpuCategory::~CpuCategory()
{
}
void CpuCategory::populate()
{
odebug << "CpuCategory::populate()" << oendl;
QFile cpuinfofile( "/proc/cpuinfo" );
if ( !cpuinfofile.exists() || !cpuinfofile.open( IO_ReadOnly ) )
{
new CpuDevice( this, "(no cpu found)" );
return;
}
QTextStream cpuinfo( &cpuinfofile );
int cpucount = 0;
CpuDevice* dev = 0;
while ( !cpuinfo.atEnd() )
{
QString line = cpuinfo.readLine();
odebug << "got line '" << line << "'" << oendl;
if ( line.lower().startsWith( "processor" ) )
{
dev = new CpuDevice( this, QString( "CPU #%1" ).arg( cpucount++ ) );
dev->addInfo( line );
}
else
{
if ( dev ) dev->addInfo( line );
}
}
}
//=================================================================================================
InputCategory::InputCategory( DevicesView* parent )
:Category( parent, "2. Input Subsystem" )
{
}
InputCategory::~InputCategory()
{
}
void InputCategory::populate()
{
odebug << "InputCategory::populate()" << oendl;
OInputSystem* sys = OInputSystem::instance();
OInputSystem::DeviceIterator it = sys->iterator();
while ( it.current() )
{
InputDevice* dev = new InputDevice( this, it.current()->identity() );
dev->setInfo( it.current() );
++it;
}
}
//=================================================================================================
CardsCategory::CardsCategory( DevicesView* parent )
:Category( parent, "3. Removable Cards" )
{
}
CardsCategory::~CardsCategory()
{
}
void CardsCategory::populate()
{
odebug << "CardsCategory::populate()" << oendl;
OPcmciaSystem* sys = OPcmciaSystem::instance();
OPcmciaSystem::CardIterator it = sys->iterator();
while ( it.current() )
{
CardDevice *dev = new CardDevice( this, it.current()->identity() );
dev->setInfo( it.current() );
++it;
}
}
//=================================================================================================
UsbCategory::UsbCategory( DevicesView* parent )
:Category( parent, "4. Universal Serial Bus" )
{
}
UsbCategory::~UsbCategory()
{
}
void UsbCategory::populate()
{
odebug << "UsbCategory::populate()" << oendl;
QFile usbinfofile( "/proc/bus/usb/devices" );
if ( !usbinfofile.exists() || !usbinfofile.open( IO_ReadOnly ) )
{
new UsbDevice( this, "(no USB found)" );
return;
}
QTextStream usbinfo( &usbinfofile );
int _bus, _level, _parent, _port, _count, _device, _channels, _power;
float _speed;
QString _manufacturer, _product, _serial;
int usbcount = 0;
UsbDevice* lastDev = 0;
UsbDevice* dev = 0;
while ( !usbinfo.atEnd() )
{
QString line = usbinfo.readLine();
odebug << "got line '" << line << "'" << oendl;
if ( line.startsWith( "T:" ) )
{
sscanf(line.local8Bit().data(), "T: Bus=%2d Lev=%2d Prnt=%2d Port=%d Cnt=%2d Dev#=%3d Spd=%3f MxCh=%2d", &_bus, &_level, &_parent, &_port, &_count, &_device, &_speed, &_channels);
if ( !_level )
{
odebug << "adding new bus" << oendl;
dev = new UsbDevice( this, QString( "Generic USB Hub Device" ) );
lastDev = dev;
}
else
{
odebug << "adding new dev" << oendl;
dev = new UsbDevice( lastDev, QString( "Generic USB Hub Device" ) );
lastDev = dev;
}
}
- else if ( line.startsWith( "S: Product" ) )
+ else if ( dev && line.startsWith( "S: Product" ) )
{
int dp = line.find( '=' );
dev->setText( 0, dp != -1 ? line.right( line.length()-1-dp ) : "<unknown>" );
}
else
{
continue;
}
}
}
//=================================================================================================
Device::Device( Category* parent, const QString& name )
:OListViewItem( parent, name )
{
devinfo = static_cast<QWidget*>( listView()->parent() );
}
Device::Device( Device* parent, const QString& name )
:OListViewItem( parent, name )
{
devinfo = static_cast<QWidget*>( listView()->parent() );
}
Device::~Device()
{
}
QWidget* Device::detailsWidget()
{
return details;
}
//=================================================================================================
CpuDevice::CpuDevice( Category* parent, const QString& name )
:Device( parent, name )
{
OListView* w = new OListView( devinfo );
details = w;
w->addColumn( "Info" );
w->addColumn( "Value" );
w->hide();
}
CpuDevice::~CpuDevice()
{
}
void CpuDevice::addInfo( const QString& info )
{
int dp = info.find( ':' );
if ( dp != -1 )
{
new OListViewItem( (OListView*) details, info.left( dp ), info.right( info.length()-dp ) );
}
}
//=================================================================================================
CardDevice::CardDevice( Category* parent, const QString& name )
:Device( parent, name )
{
OListView* w = new OListView( devinfo );
details = w;
w->addColumn( "Info" );
w->addColumn( "Value" );
w->hide();
}
void CardDevice::setInfo( const OPcmciaSocket* card )
{
QStringList vendorlst = card->productIdentityVector();
for( QStringList::Iterator it = vendorlst.begin(); it != vendorlst.end(); ++it )
{
new OListViewItem( (OListView*) details, "VendorID", *it );
}
new OListViewItem( (OListView*) details, "Manufacturer", card->manufacturerIdentity() );
new OListViewItem( (OListView*) details, "Function", card->function() );
QStringList text;
OPcmciaSocket::OPcmciaSocketCardStatus status = card->status();
if ( status )
{
if ( status & OPcmciaSocket::Occupied ) text += "Occupied";
if ( status & OPcmciaSocket::OccupiedCardBus ) text += "CardBus";
if ( status & OPcmciaSocket::WriteProtected ) text += "WriteProtected";
if ( status & OPcmciaSocket::BatteryLow ) text += "BatteryLow";
if ( status & OPcmciaSocket::BatteryDead ) text += "BatteryDead";
if ( status & OPcmciaSocket::Ready ) text += "Ready";
if ( status & OPcmciaSocket::Suspended ) text += "Suspended";
if ( status & OPcmciaSocket::Attention ) text += "Attention";
if ( status & OPcmciaSocket::InsertionInProgress ) text += "InsertionInProgress";
if ( status & OPcmciaSocket::RemovalInProgress ) text += "RemovalInProgress";
if ( status & OPcmciaSocket::ThreeVolts ) text += "3V";
if ( status & OPcmciaSocket::SupportsVoltage ) text += "SupportsVoltage";
}
else
{
text += "<unknown>";
}
new OListViewItem( (OListView*) details, "Status", text.join( ", " ) );
}
CardDevice::~CardDevice()
{
}
//=================================================================================================
InputDevice::InputDevice( Category* parent, const QString& name )
:Device( parent, name )
{
OListView* w = new OListView( devinfo );
details = w;
w->addColumn( "Info" );
w->addColumn( "Value" );
w->hide();
}
void InputDevice::setInfo( const OInputDevice* dev )
{
new OListViewItem( (OListView*) details, "Identity", dev->identity() );
new OListViewItem( (OListView*) details, "Path", dev->path() );
new OListViewItem( (OListView*) details, "Unique", dev->uniq() );
QStringList text;
if ( dev->hasFeature( OInputDevice::Synchronous ) ) text += "Synchronous";
if ( dev->hasFeature( OInputDevice::Keys ) ) text += "Keys";
if ( dev->hasFeature( OInputDevice::Relative ) ) text += "Relative";
if ( dev->hasFeature( OInputDevice::Absolute ) ) text += "Absolute";
if ( dev->hasFeature( OInputDevice::Miscellaneous ) ) text += "Miscellaneous";
if ( dev->hasFeature( OInputDevice::Switches ) ) text += "Switches";
if ( dev->hasFeature( OInputDevice::Leds ) ) text += "Leds";
if ( dev->hasFeature( OInputDevice::Sound ) ) text += "Sound";
if ( dev->hasFeature( OInputDevice::AutoRepeat ) ) text += "AutoRepeat";
if ( dev->hasFeature( OInputDevice::ForceFeedback ) ) text += "ForceFeedback";
if ( dev->hasFeature( OInputDevice::PowerManagement ) ) text += "PowerManagement";
if ( dev->hasFeature( OInputDevice::ForceFeedbackStatus ) ) text += "ForceFeedbackStatus";
new OListViewItem( (OListView*) details, "Features", text.join( ", " ) );
}
InputDevice::~InputDevice()
{
}
//=================================================================================================
UsbDevice::UsbDevice( Category* parent, const QString& name )
:Device( parent, name )
{
details = new QPushButton( name, devinfo );
details->hide();
}
//=================================================================================================
UsbDevice::UsbDevice( UsbDevice* parent, const QString& name )
:Device( parent, name )
{
details = new QPushButton( name, devinfo );
details->hide();
}
UsbDevice::~UsbDevice()
{
}
diff --git a/noncore/todayplugins/stockticker/libstocks/http.c b/noncore/todayplugins/stockticker/libstocks/http.c
index 2f38f8a..cc78ab7 100644
--- a/noncore/todayplugins/stockticker/libstocks/http.c
+++ b/noncore/todayplugins/stockticker/libstocks/http.c
@@ -1,303 +1,303 @@
/* libstocks - Library to get current stock quotes from Yahoo Finance
*
* Copyright (C) 2000 Eric Laeuffer
*
* 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; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
#define __HTTP_C__
#ifndef __UNIX__
#define __UNIX__
#endif
#ifdef __UNIX__
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <unistd.h>
#elif __WINDOWS__
#include <winsock.h>
#include <mbstring.h>
#endif
#include <sys/types.h>
#include <ctype.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include "http.h"
#include "stocks.h"
#define BUF_SIZE 1024
#define HEADER_MAXBUF 512
/* pointer to proxy server name or NULL */
char *http_proxy_server=NULL;
/* proxy server port number or 0 */
int http_proxy_port=0;
/*****************************************************************************/
/* Gets the file from http://http_server/http_file */
/* This function is used to get quotes csv file from yahoo. */
/* It allocates memory for the file and defines *pdata (the pointer of datas)*/
/*****************************************************************************/
libstocks_return_code http_get(char *http_file, char *http_server, char **pdata)
{
struct hostent *host; /* structs needed by socket */
struct sockaddr_in server;
int s; /* socket descriptor */
char header[HEADER_MAXBUF]; /* request header */
int hlg; /* header length */
char buf[BUF_SIZE+1]; /* tempory buffer from socket read */
int r; /* number of bytes read by read function */
char *data=NULL; /* http server response */
int data_lgr; /* http server response length */
char *temp; /* pointer used to split header and csv */
int error_code; /* error code returned by http server */
char *csv_ptr; /* pointer to the csv content */
int header_founded; /* test if header is founded */
#ifdef DEBUG
printf("*http_get\n");
#endif
/* get host info by name :*/
if ((host = gethostbyname( http_proxy_server ? http_proxy_server : http_server)))
{
memset((char *) &server,0, sizeof(server));
memmove((char *) &server.sin_addr, host->h_addr, host->h_length);
server.sin_family = host->h_addrtype;
server.sin_port = (unsigned short) htons( http_proxy_server ? http_proxy_port : 80 );
} else
{
#ifdef DEBUG
printf(" gethostbyname : NOK\n");
#endif
return ERRHOST;
}
/* create socket */
if ((s = socket(AF_INET, SOCK_STREAM, 0)) < 0)
{
#ifdef DEBUG
printf(" create socket : NOK\n");
#endif
return ERRSOCK;
}
setsockopt(s, SOL_SOCKET, SO_KEEPALIVE, 0, 0);
/* connect to server */
if (connect(s, &server, sizeof(server)) < 0)
{
#ifdef DEBUG
printf(" connect to server : NOK\n");
#endif
#ifdef __UNIX__
close(s);
#elif __WINDOWS__
closesocket(s);
#endif
return ERRCONN;
}
/* create header */
if (http_proxy_server)
{
sprintf(header,"GET http://%.128s:80%.256s HTTP/1.0\015\012\015\012",
http_server, http_file);
}
else
{
sprintf(header,"GET %s HTTP/1.0\015\012\015\012",http_file);
}
hlg=strlen(header);
/* send header */
#ifdef __UNIX__
if (write(s,header,hlg)!=hlg)
#elif __WINDOWS__
if (send(s,header,hlg, 0)!=hlg)
#endif
{
#ifdef DEBUG
printf(" send header : NOK\n");
#endif
return ERRWHEA;
}
data_lgr = 0;
r=1;
while(r)
{
/* Clear Buffer */
memset(buf,0,BUF_SIZE+1);
#ifdef __UNIX__
r=read(s,buf,BUF_SIZE);
#elif __WINDOWS__
r=recv(s,buf,BUF_SIZE,0);
#endif
if (r)
{
if(!data_lgr)
{
if((data = malloc(r+1))==NULL)
{
fprintf(stderr,"Memory allocating error (%s line %d)\n"
,__FILE__, __LINE__);
exit(1);
}
memcpy(data,buf,r);
data_lgr = r;
data[r]=0;
}
else
{
if((temp = malloc(r+data_lgr+1))==NULL)
{
fprintf(stderr,"Memory allocating error (%s line %d)\n"
,__FILE__, __LINE__);
exit(1);
}
memcpy(temp, data, data_lgr);
memcpy(temp+data_lgr, buf, r);
temp[r+data_lgr]=0;
data_lgr += r;
free(data);
data = temp;
}
}
}
/* close socket */
#ifdef __UNIX__
close(s);
#elif __WINDOWS__
closesocket(s);
#endif
#ifdef DEBUG
printf("%s\n", data);
#endif
/* get headers to test status line */
/* and to split headers and content */
temp = data;
header_founded = 0;
while( !header_founded )
{
- if (*temp==0) return ERRRHEA;
+ if (!temp || *temp==0) return ERRRHEA;
if( *temp==0x0A )
{
/* test if it is the header end */
temp ++;
if (*temp == 0x0D) temp++;
if (*temp == 0x0A) header_founded = 1;
}
else
temp++;
}
*temp = 0;
temp++;
sscanf(data,"HTTP/1.%*d %03d",&error_code);
if (error_code != 200)
{
#ifdef DEBUG
printf(" HTTP error code : %d\n", error_code);
#endif
free(data);
return ERRPAHD;
}
if ((csv_ptr = malloc(strlen(temp)+1))==NULL)
{
free(data);
fprintf(stderr,"Memory allocating error (%s line %d)\n"
,__FILE__, __LINE__);
exit(1);
}
memcpy(csv_ptr, temp, strlen(temp)+1);
free(data);
#ifdef DEBUG
printf(" CSV\n");
printf("%s,\n", csv_ptr);
#endif
*pdata = csv_ptr;
return 0;
}
/******************************************************************************/
/* Set the proxy server to use */
/******************************************************************************/
libstocks_return_code set_proxy(char *proxy)
{
char *ptr;
char c;
#ifdef DEBUG
printf("*set_proxy\n");
#endif
/* Parse the proxy URL - It must start with http:// */
#ifdef __UNIX__
if (strncasecmp("http://",proxy,7)) return ERRPROX;
#elif __WINDOWS__
if (_mbsnbicmp("http://",proxy,7)) return ERRPROX;
#endif
proxy+=7;
/* find ":" in the proxy url */
ptr = proxy;
for (c=*ptr; (c && c!=':');) c=*ptr++;
/* ptr points just after the ":" or at the end of proxy if : not founded */
*(ptr-1)=0; /* clear the ":" */
http_proxy_server=strdup(proxy);
#ifdef DEBUG
printf("http_proxy_server : %s\n", http_proxy_server);
#endif
/* get the port number of the url */
if (sscanf(ptr,"%d",&http_proxy_port)!=1) return ERRPROX;
#ifdef DEBUG
printf("http_proxy_port : %d\n", http_proxy_port);
#endif
return 0;
}