summaryrefslogtreecommitdiff
authorerik <erik>2007-02-08 01:45:16 (UTC)
committer erik <erik>2007-02-08 01:45:16 (UTC)
commit2e497f7cae45184184e2416114887095735958f5 (patch) (side-by-side diff)
treea6b399d9bce5854dc7ad6c985b48965cf20680b0
parent853b61f97e718359bef95147ab3c7beb0705acda (diff)
downloadopie-2e497f7cae45184184e2416114887095735958f5.zip
opie-2e497f7cae45184184e2416114887095735958f5.tar.gz
opie-2e497f7cae45184184e2416114887095735958f5.tar.bz2
Each file in this commit has a problem where it is possible to dereference
a pointer without that pointer being valid. This commit fixes each instance of that.
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--core/multimedia/opieplayer/modplug/sndfile.cpp5
-rw-r--r--core/multimedia/opieplayer/vorbis/tremor/block.c6
-rw-r--r--core/multimedia/opieplayer/vorbis/tremor/info.c2
-rw-r--r--noncore/apps/opie-write/qrichtext.cpp69
-rw-r--r--noncore/settings/networksettings2/opietooth2/OTSDPAttribute.cpp3
-rw-r--r--noncore/settings/packagemanager/oipkgconfigdlg.cpp6
6 files changed, 62 insertions, 29 deletions
diff --git a/core/multimedia/opieplayer/modplug/sndfile.cpp b/core/multimedia/opieplayer/modplug/sndfile.cpp
index 1d0d610..799555c 100644
--- a/core/multimedia/opieplayer/modplug/sndfile.cpp
+++ b/core/multimedia/opieplayer/modplug/sndfile.cpp
@@ -1550,326 +1550,329 @@ void CSoundFile::AdjustSampleLoop(MODINSTRUMENT *pIns)
{
pSample[len+4] = pSample[len+3] = pSample[len+2] = pSample[len+1] = pSample[len] = pSample[len-1];
}
if ((pIns->uFlags & (CHN_LOOP|CHN_PINGPONGLOOP|CHN_STEREO)) == CHN_LOOP)
{
// Fix bad loops
if ((pIns->nLoopEnd+3 >= pIns->nLength) || (m_nType & MOD_TYPE_S3M))
{
pSample[pIns->nLoopEnd] = pSample[pIns->nLoopStart];
pSample[pIns->nLoopEnd+1] = pSample[pIns->nLoopStart+1];
pSample[pIns->nLoopEnd+2] = pSample[pIns->nLoopStart+2];
pSample[pIns->nLoopEnd+3] = pSample[pIns->nLoopStart+3];
pSample[pIns->nLoopEnd+4] = pSample[pIns->nLoopStart+4];
}
}
} else
{
signed char *pSample = pIns->pSample;
#ifndef FASTSOUNDLIB
// Crappy samples (except chiptunes) ?
if ((pIns->nLength > 0x100) && (m_nType & (MOD_TYPE_MOD|MOD_TYPE_S3M))
&& (!(pIns->uFlags & CHN_STEREO)))
{
int smpend = pSample[pIns->nLength-1], smpfix = 0, kscan;
for (kscan=pIns->nLength-1; kscan>0; kscan--)
{
smpfix = pSample[kscan-1];
if (smpfix != smpend) break;
}
int delta = smpfix - smpend;
if (((!(pIns->uFlags & CHN_LOOP)) || (kscan > (int)pIns->nLoopEnd))
&& ((delta < -8) || (delta > 8)))
{
while (kscan<(int)pIns->nLength)
{
if (!(kscan & 7))
{
if (smpfix > 0) smpfix--;
if (smpfix < 0) smpfix++;
}
pSample[kscan] = (signed char)smpfix;
kscan++;
}
}
}
#endif
// Adjust end of sample
if (pIns->uFlags & CHN_STEREO)
{
pSample[len*2+6] = pSample[len*2+4] = pSample[len*2+2] = pSample[len*2] = pSample[len*2-2];
pSample[len*2+7] = pSample[len*2+5] = pSample[len*2+3] = pSample[len*2+1] = pSample[len*2-1];
} else
{
pSample[len+4] = pSample[len+3] = pSample[len+2] = pSample[len+1] = pSample[len] = pSample[len-1];
}
if ((pIns->uFlags & (CHN_LOOP|CHN_PINGPONGLOOP|CHN_STEREO)) == CHN_LOOP)
{
if ((pIns->nLoopEnd+3 >= pIns->nLength) || (m_nType & (MOD_TYPE_MOD|MOD_TYPE_S3M)))
{
pSample[pIns->nLoopEnd] = pSample[pIns->nLoopStart];
pSample[pIns->nLoopEnd+1] = pSample[pIns->nLoopStart+1];
pSample[pIns->nLoopEnd+2] = pSample[pIns->nLoopStart+2];
pSample[pIns->nLoopEnd+3] = pSample[pIns->nLoopStart+3];
pSample[pIns->nLoopEnd+4] = pSample[pIns->nLoopStart+4];
}
}
}
}
/////////////////////////////////////////////////////////////
// Transpose <-> Frequency conversions
// returns 8363*2^((transp*128+ftune)/(12*128))
DWORD CSoundFile::TransposeToFrequency(int transp, int ftune)
//-----------------------------------------------------------
{
//---GCCFIX: Removed assembly.
return (DWORD)(8363*pow(2, (transp*128+ftune)/(1536)));
#ifdef WIN32
const float _fbase = 8363;
const float _factor = 1.0f/(12.0f*128.0f);
int result;
DWORD freq;
transp = (transp << 7) + ftune;
_asm {
fild transp
fld _factor
fmulp st(1), st(0)
fist result
fisub result
f2xm1
fild result
fld _fbase
fscale
fstp st(1)
fmul st(1), st(0)
faddp st(1), st(0)
fistp freq
}
UINT derr = freq % 11025;
if (derr <= 8) freq -= derr;
if (derr >= 11015) freq += 11025-derr;
derr = freq % 1000;
if (derr <= 5) freq -= derr;
if (derr >= 995) freq += 1000-derr;
return freq;
#endif
}
// returns 12*128*log2(freq/8363)
int CSoundFile::FrequencyToTranspose(DWORD freq)
//----------------------------------------------
{
//---GCCFIX: Removed assembly.
return int(1536*(log(freq/8363)/log(2)));
#ifdef WIN32
const float _f1_8363 = 1.0f / 8363.0f;
const float _factor = 128 * 12;
LONG result;
if (!freq) return 0;
_asm {
fld _factor
fild freq
fld _f1_8363
fmulp st(1), st(0)
fyl2x
fistp result
}
return result;
#endif
}
void CSoundFile::FrequencyToTranspose(MODINSTRUMENT *psmp)
//--------------------------------------------------------
{
int f2t = FrequencyToTranspose(psmp->nC4Speed);
int transp = f2t >> 7;
int ftune = f2t & 0x7F;
if (ftune > 80)
{
transp++;
ftune -= 128;
}
if (transp > 127) transp = 127;
if (transp < -127) transp = -127;
psmp->RelativeTone = transp;
psmp->nFineTune = ftune;
}
void CSoundFile::CheckCPUUsage(UINT nCPU)
//---------------------------------------
{
if (nCPU > 100) nCPU = 100;
gnCPUUsage = nCPU;
if (nCPU < 90)
{
m_dwSongFlags &= ~SONG_CPUVERYHIGH;
} else
if ((m_dwSongFlags & SONG_CPUVERYHIGH) && (nCPU >= 94))
{
UINT i=MAX_CHANNELS;
while (i >= 8)
{
i--;
if (Chn[i].nLength)
{
Chn[i].nLength = Chn[i].nPos = 0;
nCPU -= 2;
if (nCPU < 94) break;
}
}
} else
if (nCPU > 90)
{
m_dwSongFlags |= SONG_CPUVERYHIGH;
}
}
BOOL CSoundFile::SetPatternName(UINT nPat, LPCSTR lpszName)
//---------------------------------------------------------
{
char szName[MAX_PATTERNNAME] = ""; // changed from CHAR
if (nPat >= MAX_PATTERNS) return FALSE;
- if (lpszName) lstrcpyn(szName, lpszName, MAX_PATTERNNAME);
+ if (lpszName)
+ lstrcpyn(szName, lpszName, MAX_PATTERNNAME);
+ else
+ return FALSE;
szName[MAX_PATTERNNAME-1] = 0;
if (!m_lpszPatternNames) m_nPatternNames = 0;
if (nPat >= m_nPatternNames)
{
if (!lpszName[0]) return TRUE;
UINT len = (nPat+1)*MAX_PATTERNNAME;
char *p = new char[len]; // changed from CHAR
if (!p) return FALSE;
memset(p, 0, len);
if (m_lpszPatternNames)
{
memcpy(p, m_lpszPatternNames, m_nPatternNames * MAX_PATTERNNAME);
delete m_lpszPatternNames;
m_lpszPatternNames = NULL;
}
m_lpszPatternNames = p;
m_nPatternNames = nPat + 1;
}
memcpy(m_lpszPatternNames + nPat * MAX_PATTERNNAME, szName, MAX_PATTERNNAME);
return TRUE;
}
BOOL CSoundFile::GetPatternName(UINT nPat, LPSTR lpszName, UINT cbSize) const
//---------------------------------------------------------------------------
{
if ((!lpszName) || (!cbSize)) return FALSE;
lpszName[0] = 0;
if (cbSize > MAX_PATTERNNAME) cbSize = MAX_PATTERNNAME;
if ((m_lpszPatternNames) && (nPat < m_nPatternNames))
{
memcpy(lpszName, m_lpszPatternNames + nPat * MAX_PATTERNNAME, cbSize);
lpszName[cbSize-1] = 0;
return TRUE;
}
return FALSE;
}
#ifndef FASTSOUNDLIB
UINT CSoundFile::DetectUnusedSamples(BOOL *pbIns)
//-----------------------------------------------
{
UINT nExt = 0;
if (!pbIns) return 0;
if (m_nInstruments)
{
memset(pbIns, 0, MAX_SAMPLES * sizeof(BOOL));
for (UINT ipat=0; ipat<MAX_PATTERNS; ipat++)
{
MODCOMMAND *p = Patterns[ipat];
if (p)
{
UINT jmax = PatternSize[ipat] * m_nChannels;
for (UINT j=0; j<jmax; j++, p++)
{
if ((p->note) && (p->note <= 120))
{
if ((p->instr) && (p->instr < MAX_INSTRUMENTS))
{
INSTRUMENTHEADER *penv = Headers[p->instr];
if (penv)
{
UINT n = penv->Keyboard[p->note-1];
if (n < MAX_SAMPLES) pbIns[n] = TRUE;
}
} else
{
for (UINT k=1; k<=m_nInstruments; k++)
{
INSTRUMENTHEADER *penv = Headers[k];
if (penv)
{
UINT n = penv->Keyboard[p->note-1];
if (n < MAX_SAMPLES) pbIns[n] = TRUE;
}
}
}
}
}
}
}
for (UINT ichk=1; ichk<=m_nSamples; ichk++)
{
if ((!pbIns[ichk]) && (Ins[ichk].pSample)) nExt++;
}
}
return nExt;
}
BOOL CSoundFile::RemoveSelectedSamples(BOOL *pbIns)
//-------------------------------------------------
{
if (!pbIns) return FALSE;
for (UINT j=1; j<MAX_SAMPLES; j++)
{
if ((!pbIns[j]) && (Ins[j].pSample))
{
DestroySample(j);
if ((j == m_nSamples) && (j > 1)) m_nSamples--;
}
}
return TRUE;
}
BOOL CSoundFile::DestroySample(UINT nSample)
//------------------------------------------
{
if ((!nSample) || (nSample >= MAX_SAMPLES)) return FALSE;
if (!Ins[nSample].pSample) return TRUE;
MODINSTRUMENT *pins = &Ins[nSample];
signed char *pSample = pins->pSample;
pins->pSample = NULL;
pins->nLength = 0;
pins->uFlags &= ~(CHN_16BIT);
for (UINT i=0; i<MAX_CHANNELS; i++)
{
if (Chn[i].pSample == pSample)
{
Chn[i].nPos = Chn[i].nLength = 0;
Chn[i].pSample = Chn[i].pCurrentSample = NULL;
}
}
FreeSample(pSample);
return TRUE;
}
#endif // FASTSOUNDLIB
diff --git a/core/multimedia/opieplayer/vorbis/tremor/block.c b/core/multimedia/opieplayer/vorbis/tremor/block.c
index 8949253..7b5531b 100644
--- a/core/multimedia/opieplayer/vorbis/tremor/block.c
+++ b/core/multimedia/opieplayer/vorbis/tremor/block.c
@@ -37,386 +37,388 @@ static int ilog(unsigned int v){
}
/* pcm accumulator examples (not exhaustive):
<-------------- lW ---------------->
<--------------- W ---------------->
: .....|..... _______________ |
: .''' | '''_--- | |\ |
:.....''' |_____--- '''......| | \_______|
:.................|__________________|_______|__|______|
|<------ Sl ------>| > Sr < |endW
|beginSl |endSl | |endSr
|beginW |endlW |beginSr
|< lW >|
<--------------- W ---------------->
| | .. ______________ |
| | ' `/ | ---_ |
|___.'___/`. | ---_____|
|_______|__|_______|_________________|
| >|Sl|< |<------ Sr ----->|endW
| | |endSl |beginSr |endSr
|beginW | |endlW
mult[0] |beginSl mult[n]
<-------------- lW ----------------->
|<--W-->|
: .............. ___ | |
: .''' |`/ \ | |
:.....''' |/`....\|...|
:.........................|___|___|___|
|Sl |Sr |endW
| | |endSr
| |beginSr
| |endSl
|beginSl
|beginW
*/
/* block abstraction setup *********************************************/
#ifndef WORD_ALIGN
#define WORD_ALIGN 8
#endif
int vorbis_block_init(vorbis_dsp_state *v, vorbis_block *vb){
memset(vb,0,sizeof(*vb));
vb->vd=v;
vb->localalloc=0;
vb->localstore=NULL;
return(0);
}
void *_vorbis_block_alloc(vorbis_block *vb,long bytes){
bytes=(bytes+(WORD_ALIGN-1)) & ~(WORD_ALIGN-1);
if(bytes+vb->localtop>vb->localalloc){
/* can't just _ogg_realloc... there are outstanding pointers */
if(vb->localstore){
struct alloc_chain *link=(struct alloc_chain *)_ogg_malloc(sizeof(*link));
vb->totaluse+=vb->localtop;
link->next=vb->reap;
link->ptr=vb->localstore;
vb->reap=link;
}
/* highly conservative */
vb->localalloc=bytes;
vb->localstore=_ogg_malloc(vb->localalloc);
vb->localtop=0;
}
{
void *ret=(void *)(((char *)vb->localstore)+vb->localtop);
vb->localtop+=bytes;
return ret;
}
}
/* reap the chain, pull the ripcord */
void _vorbis_block_ripcord(vorbis_block *vb){
/* reap the chain */
struct alloc_chain *reap=vb->reap;
while(reap){
struct alloc_chain *next=reap->next;
_ogg_free(reap->ptr);
memset(reap,0,sizeof(*reap));
_ogg_free(reap);
reap=next;
}
/* consolidate storage */
if(vb->totaluse){
vb->localstore=_ogg_realloc(vb->localstore,vb->totaluse+vb->localalloc);
vb->localalloc+=vb->totaluse;
vb->totaluse=0;
}
/* pull the ripcord */
vb->localtop=0;
vb->reap=NULL;
}
int vorbis_block_clear(vorbis_block *vb){
_vorbis_block_ripcord(vb);
if(vb->localstore)_ogg_free(vb->localstore);
memset(vb,0,sizeof(*vb));
return(0);
}
static int _vds_init(vorbis_dsp_state *v,vorbis_info *vi){
int i;
codec_setup_info *ci=(codec_setup_info *)vi->codec_setup;
private_state *b=NULL;
memset(v,0,sizeof(*v));
b=(private_state *)(v->backend_state=_ogg_calloc(1,sizeof(*b)));
v->vi=vi;
b->modebits=ilog(ci->modes);
/* Vorbis I uses only window type 0 */
b->window[0]=_vorbis_window(0,ci->blocksizes[0]/2);
b->window[1]=_vorbis_window(0,ci->blocksizes[1]/2);
/* finish the codebooks */
if(!ci->fullbooks){
ci->fullbooks=(codebook *)_ogg_calloc(ci->books,sizeof(*ci->fullbooks));
for(i=0;i<ci->books;i++){
vorbis_book_init_decode(ci->fullbooks+i,ci->book_param[i]);
/* decode codebooks are now standalone after init */
vorbis_staticbook_destroy(ci->book_param[i]);
ci->book_param[i]=NULL;
}
}
v->pcm_storage=ci->blocksizes[1];
v->pcm=(ogg_int32_t **)_ogg_malloc(vi->channels*sizeof(*v->pcm));
v->pcmret=(ogg_int32_t **)_ogg_malloc(vi->channels*sizeof(*v->pcmret));
for(i=0;i<vi->channels;i++)
v->pcm[i]=(ogg_int32_t *)_ogg_calloc(v->pcm_storage,sizeof(*v->pcm[i]));
/* all 1 (large block) or 0 (small block) */
/* explicitly set for the sake of clarity */
v->lW=0; /* previous window size */
v->W=0; /* current window size */
/* initialize all the mapping/backend lookups */
b->mode=(vorbis_look_mapping **)_ogg_calloc(ci->modes,sizeof(*b->mode));
for(i=0;i<ci->modes;i++){
int mapnum=ci->mode_param[i]->mapping;
int maptype=ci->map_type[mapnum];
b->mode[i]=_mapping_P[maptype]->look(v,ci->mode_param[i],
ci->map_param[mapnum]);
}
return(0);
}
int vorbis_synthesis_restart(vorbis_dsp_state *v){
vorbis_info *vi=v->vi;
codec_setup_info *ci;
if(!v->backend_state)return -1;
if(!vi)return -1;
ci=vi->codec_setup;
if(!ci)return -1;
v->centerW=ci->blocksizes[1]/2;
v->pcm_current=v->centerW;
v->pcm_returned=-1;
v->granulepos=-1;
v->sequence=-1;
((private_state *)(v->backend_state))->sample_count=-1;
return(0);
}
int vorbis_synthesis_init(vorbis_dsp_state *v,vorbis_info *vi){
_vds_init(v,vi);
vorbis_synthesis_restart(v);
return(0);
}
void vorbis_dsp_clear(vorbis_dsp_state *v){
int i;
if(v){
vorbis_info *vi=v->vi;
codec_setup_info *ci=(codec_setup_info *)(vi?vi->codec_setup:NULL);
private_state *b=(private_state *)v->backend_state;
if(v->pcm){
- for(i=0;i<vi->channels;i++)
- if(v->pcm[i])_ogg_free(v->pcm[i]);
+ if (vi) {
+ for(i=0;i<vi->channels;i++)
+ if(v->pcm[i])_ogg_free(v->pcm[i]);
+ }
_ogg_free(v->pcm);
if(v->pcmret)_ogg_free(v->pcmret);
}
/* free mode lookups; these are actually vorbis_look_mapping structs */
if(ci){
for(i=0;i<ci->modes;i++){
int mapnum=ci->mode_param[i]->mapping;
int maptype=ci->map_type[mapnum];
if(b && b->mode)_mapping_P[maptype]->free_look(b->mode[i]);
}
}
if(b){
if(b->mode)_ogg_free(b->mode);
_ogg_free(b);
}
memset(v,0,sizeof(*v));
}
}
/* Unlike in analysis, the window is only partially applied for each
block. The time domain envelope is not yet handled at the point of
calling (as it relies on the previous block). */
int vorbis_synthesis_blockin(vorbis_dsp_state *v,vorbis_block *vb){
vorbis_info *vi=v->vi;
codec_setup_info *ci=(codec_setup_info *)vi->codec_setup;
private_state *b=v->backend_state;
int i,j;
if(v->pcm_current>v->pcm_returned && v->pcm_returned!=-1)return(OV_EINVAL);
v->lW=v->W;
v->W=vb->W;
v->nW=-1;
if((v->sequence==-1)||
(v->sequence+1 != vb->sequence)){
v->granulepos=-1; /* out of sequence; lose count */
b->sample_count=-1;
}
v->sequence=vb->sequence;
if(vb->pcm){ /* no pcm to process if vorbis_synthesis_trackonly
was called on block */
int n=ci->blocksizes[v->W]/2;
int n0=ci->blocksizes[0]/2;
int n1=ci->blocksizes[1]/2;
int thisCenter;
int prevCenter;
if(v->centerW){
thisCenter=n1;
prevCenter=0;
}else{
thisCenter=0;
prevCenter=n1;
}
/* v->pcm is now used like a two-stage double buffer. We don't want
to have to constantly shift *or* adjust memory usage. Don't
accept a new block until the old is shifted out */
/* overlap/add PCM */
for(j=0;j<vi->channels;j++){
/* the overlap/add section */
if(v->lW){
if(v->W){
/* large/large */
ogg_int32_t *pcm=v->pcm[j]+prevCenter;
ogg_int32_t *p=vb->pcm[j];
for(i=0;i<n1;i++)
pcm[i]+=p[i];
}else{
/* large/small */
ogg_int32_t *pcm=v->pcm[j]+prevCenter+n1/2-n0/2;
ogg_int32_t *p=vb->pcm[j];
for(i=0;i<n0;i++)
pcm[i]+=p[i];
}
}else{
if(v->W){
/* small/large */
ogg_int32_t *pcm=v->pcm[j]+prevCenter;
ogg_int32_t *p=vb->pcm[j]+n1/2-n0/2;
for(i=0;i<n0;i++)
pcm[i]+=p[i];
for(;i<n1/2+n0/2;i++)
pcm[i]=p[i];
}else{
/* small/small */
ogg_int32_t *pcm=v->pcm[j]+prevCenter;
ogg_int32_t *p=vb->pcm[j];
for(i=0;i<n0;i++)
pcm[i]+=p[i];
}
}
/* the copy section */
{
ogg_int32_t *pcm=v->pcm[j]+thisCenter;
ogg_int32_t *p=vb->pcm[j]+n;
for(i=0;i<n;i++)
pcm[i]=p[i];
}
}
if(v->centerW)
v->centerW=0;
else
v->centerW=n1;
/* deal with initial packet state; we do this using the explicit
pcm_returned==-1 flag otherwise we're sensitive to first block
being short or long */
if(v->pcm_returned==-1){
v->pcm_returned=thisCenter;
v->pcm_current=thisCenter;
}else{
v->pcm_returned=prevCenter;
v->pcm_current=prevCenter+
ci->blocksizes[v->lW]/4+
ci->blocksizes[v->W]/4;
}
}
/* track the frame number... This is for convenience, but also
making sure our last packet doesn't end with added padding. If
the last packet is partial, the number of samples we'll have to
return will be past the vb->granulepos.
This is not foolproof! It will be confused if we begin
decoding at the last page after a seek or hole. In that case,
we don't have a starting point to judge where the last frame
is. For this reason, vorbisfile will always try to make sure
it reads the last two marked pages in proper sequence */
if(b->sample_count==-1){
b->sample_count=0;
}else{
b->sample_count+=ci->blocksizes[v->lW]/4+ci->blocksizes[v->W]/4;
}
if(v->granulepos==-1){
if(vb->granulepos!=-1){ /* only set if we have a position to set to */
v->granulepos=vb->granulepos;
/* is this a short page? */
if(b->sample_count>v->granulepos){
/* corner case; if this is both the first and last audio page,
then spec says the end is cut, not beginning */
if(vb->eofflag){
/* trim the end */
/* no preceeding granulepos; assume we started at zero (we'd
have to in a short single-page stream) */
/* granulepos could be -1 due to a seek, but that would result
in a long coun`t, not short count */
v->pcm_current-=(b->sample_count-v->granulepos);
}else{
/* trim the beginning */
v->pcm_returned+=(b->sample_count-v->granulepos);
if(v->pcm_returned>v->pcm_current)
v->pcm_returned=v->pcm_current;
}
}
}
}else{
v->granulepos+=ci->blocksizes[v->lW]/4+ci->blocksizes[v->W]/4;
if(vb->granulepos!=-1 && v->granulepos!=vb->granulepos){
if(v->granulepos>vb->granulepos){
long extra=v->granulepos-vb->granulepos;
if(extra)
if(vb->eofflag){
/* partial last frame. Strip the extra samples off */
v->pcm_current-=extra;
} /* else {Shouldn't happen *unless* the bitstream is out of
spec. Either way, believe the bitstream } */
} /* else {Shouldn't happen *unless* the bitstream is out of
spec. Either way, believe the bitstream } */
diff --git a/core/multimedia/opieplayer/vorbis/tremor/info.c b/core/multimedia/opieplayer/vorbis/tremor/info.c
index 941695e..3499ae4 100644
--- a/core/multimedia/opieplayer/vorbis/tremor/info.c
+++ b/core/multimedia/opieplayer/vorbis/tremor/info.c
@@ -1,293 +1,293 @@
/********************************************************************
* *
* THIS FILE IS PART OF THE OggVorbis 'TREMOR' CODEC SOURCE CODE. *
* *
* USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS *
* GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
* IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
* *
* THE OggVorbis 'TREMOR' SOURCE CODE IS (C) COPYRIGHT 1994-2003 *
* BY THE Xiph.Org FOUNDATION http://www.xiph.org/ *
* *
********************************************************************
function: maintain the info structure, info <-> header packets
********************************************************************/
/* general handling of the header and the vorbis_info structure (and
substructures) */
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include "ogg.h"
#include "ivorbiscodec.h"
#include "codec_internal.h"
#include "codebook.h"
#include "registry.h"
#include "window.h"
#include "misc.h"
#include "os.h"
/* helpers */
static void _v_readstring(oggpack_buffer *o,char *buf,int bytes){
while(bytes--){
*buf++=oggpack_read(o,8);
}
}
void vorbis_comment_init(vorbis_comment *vc){
memset(vc,0,sizeof(*vc));
}
/* This is more or less the same as strncasecmp - but that doesn't exist
* everywhere, and this is a fairly trivial function, so we include it */
static int tagcompare(const char *s1, const char *s2, int n){
int c=0;
while(c < n){
if(toupper(s1[c]) != toupper(s2[c]))
return !0;
c++;
}
return 0;
}
char *vorbis_comment_query(vorbis_comment *vc, char *tag, int count){
long i;
int found = 0;
int taglen = strlen(tag)+1; /* +1 for the = we append */
char *fulltag = (char *)alloca(taglen+ 1);
strcpy(fulltag, tag);
strcat(fulltag, "=");
for(i=0;i<vc->comments;i++){
if(!tagcompare(vc->user_comments[i], fulltag, taglen)){
if(count == found)
/* We return a pointer to the data, not a copy */
return vc->user_comments[i] + taglen;
else
found++;
}
}
return NULL; /* didn't find anything */
}
int vorbis_comment_query_count(vorbis_comment *vc, char *tag){
int i,count=0;
int taglen = strlen(tag)+1; /* +1 for the = we append */
char *fulltag = (char *)alloca(taglen+1);
strcpy(fulltag,tag);
strcat(fulltag, "=");
for(i=0;i<vc->comments;i++){
if(!tagcompare(vc->user_comments[i], fulltag, taglen))
count++;
}
return count;
}
void vorbis_comment_clear(vorbis_comment *vc){
if(vc){
long i;
for(i=0;i<vc->comments;i++)
if(vc->user_comments[i])_ogg_free(vc->user_comments[i]);
if(vc->user_comments)_ogg_free(vc->user_comments);
if(vc->comment_lengths)_ogg_free(vc->comment_lengths);
if(vc->vendor)_ogg_free(vc->vendor);
+ memset(vc,0,sizeof(*vc));
}
- memset(vc,0,sizeof(*vc));
}
/* blocksize 0 is guaranteed to be short, 1 is guarantted to be long.
They may be equal, but short will never ge greater than long */
int vorbis_info_blocksize(vorbis_info *vi,int zo){
codec_setup_info *ci = (codec_setup_info *)vi->codec_setup;
return ci ? ci->blocksizes[zo] : -1;
}
/* used by synthesis, which has a full, alloced vi */
void vorbis_info_init(vorbis_info *vi){
memset(vi,0,sizeof(*vi));
vi->codec_setup=(codec_setup_info *)_ogg_calloc(1,sizeof(codec_setup_info));
}
void vorbis_info_clear(vorbis_info *vi){
codec_setup_info *ci=(codec_setup_info *)vi->codec_setup;
int i;
if(ci){
for(i=0;i<ci->modes;i++)
if(ci->mode_param[i])_ogg_free(ci->mode_param[i]);
for(i=0;i<ci->maps;i++) /* unpack does the range checking */
_mapping_P[ci->map_type[i]]->free_info(ci->map_param[i]);
for(i=0;i<ci->floors;i++) /* unpack does the range checking */
_floor_P[ci->floor_type[i]]->free_info(ci->floor_param[i]);
for(i=0;i<ci->residues;i++) /* unpack does the range checking */
_residue_P[ci->residue_type[i]]->free_info(ci->residue_param[i]);
for(i=0;i<ci->books;i++){
if(ci->book_param[i]){
/* knows if the book was not alloced */
vorbis_staticbook_destroy(ci->book_param[i]);
}
if(ci->fullbooks)
vorbis_book_clear(ci->fullbooks+i);
}
if(ci->fullbooks)
_ogg_free(ci->fullbooks);
_ogg_free(ci);
}
memset(vi,0,sizeof(*vi));
}
/* Header packing/unpacking ********************************************/
static int _vorbis_unpack_info(vorbis_info *vi,oggpack_buffer *opb){
codec_setup_info *ci=(codec_setup_info *)vi->codec_setup;
if(!ci)return(OV_EFAULT);
vi->version=oggpack_read(opb,32);
if(vi->version!=0)return(OV_EVERSION);
vi->channels=oggpack_read(opb,8);
vi->rate=oggpack_read(opb,32);
vi->bitrate_upper=oggpack_read(opb,32);
vi->bitrate_nominal=oggpack_read(opb,32);
vi->bitrate_lower=oggpack_read(opb,32);
ci->blocksizes[0]=1<<oggpack_read(opb,4);
ci->blocksizes[1]=1<<oggpack_read(opb,4);
if(vi->rate<1)goto err_out;
if(vi->channels<1)goto err_out;
if(ci->blocksizes[0]<64)goto err_out;
if(ci->blocksizes[1]<ci->blocksizes[0])goto err_out;
if(ci->blocksizes[1]>8192)goto err_out;
if(oggpack_read(opb,1)!=1)goto err_out; /* EOP check */
return(0);
err_out:
vorbis_info_clear(vi);
return(OV_EBADHEADER);
}
static int _vorbis_unpack_comment(vorbis_comment *vc,oggpack_buffer *opb){
int i;
int vendorlen=oggpack_read(opb,32);
if(vendorlen<0)goto err_out;
vc->vendor=(char *)_ogg_calloc(vendorlen+1,1);
_v_readstring(opb,vc->vendor,vendorlen);
vc->comments=oggpack_read(opb,32);
if(vc->comments<0)goto err_out;
vc->user_comments=(char **)_ogg_calloc(vc->comments+1,sizeof(*vc->user_comments));
vc->comment_lengths=(int *)_ogg_calloc(vc->comments+1, sizeof(*vc->comment_lengths));
for(i=0;i<vc->comments;i++){
int len=oggpack_read(opb,32);
if(len<0)goto err_out;
vc->comment_lengths[i]=len;
vc->user_comments[i]=(char *)_ogg_calloc(len+1,1);
_v_readstring(opb,vc->user_comments[i],len);
}
if(oggpack_read(opb,1)!=1)goto err_out; /* EOP check */
return(0);
err_out:
vorbis_comment_clear(vc);
return(OV_EBADHEADER);
}
/* all of the real encoding details are here. The modes, books,
everything */
static int _vorbis_unpack_books(vorbis_info *vi,oggpack_buffer *opb){
codec_setup_info *ci=(codec_setup_info *)vi->codec_setup;
int i;
if(!ci)return(OV_EFAULT);
/* codebooks */
ci->books=oggpack_read(opb,8)+1;
/*ci->book_param=_ogg_calloc(ci->books,sizeof(*ci->book_param));*/
for(i=0;i<ci->books;i++){
ci->book_param[i]=(static_codebook *)_ogg_calloc(1,sizeof(*ci->book_param[i]));
if(vorbis_staticbook_unpack(opb,ci->book_param[i]))goto err_out;
}
/* time backend settings */
ci->times=oggpack_read(opb,6)+1;
/*ci->time_type=_ogg_malloc(ci->times*sizeof(*ci->time_type));*/
/*ci->time_param=_ogg_calloc(ci->times,sizeof(void *));*/
for(i=0;i<ci->times;i++){
ci->time_type[i]=oggpack_read(opb,16);
if(ci->time_type[i]<0 || ci->time_type[i]>=VI_TIMEB)goto err_out;
/* ci->time_param[i]=_time_P[ci->time_type[i]]->unpack(vi,opb);
Vorbis I has no time backend */
/*if(!ci->time_param[i])goto err_out;*/
}
/* floor backend settings */
ci->floors=oggpack_read(opb,6)+1;
/*ci->floor_type=_ogg_malloc(ci->floors*sizeof(*ci->floor_type));*/
/*ci->floor_param=_ogg_calloc(ci->floors,sizeof(void *));*/
for(i=0;i<ci->floors;i++){
ci->floor_type[i]=oggpack_read(opb,16);
if(ci->floor_type[i]<0 || ci->floor_type[i]>=VI_FLOORB)goto err_out;
ci->floor_param[i]=_floor_P[ci->floor_type[i]]->unpack(vi,opb);
if(!ci->floor_param[i])goto err_out;
}
/* residue backend settings */
ci->residues=oggpack_read(opb,6)+1;
/*ci->residue_type=_ogg_malloc(ci->residues*sizeof(*ci->residue_type));*/
/*ci->residue_param=_ogg_calloc(ci->residues,sizeof(void *));*/
for(i=0;i<ci->residues;i++){
ci->residue_type[i]=oggpack_read(opb,16);
if(ci->residue_type[i]<0 || ci->residue_type[i]>=VI_RESB)goto err_out;
ci->residue_param[i]=_residue_P[ci->residue_type[i]]->unpack(vi,opb);
if(!ci->residue_param[i])goto err_out;
}
/* map backend settings */
ci->maps=oggpack_read(opb,6)+1;
/*ci->map_type=_ogg_malloc(ci->maps*sizeof(*ci->map_type));*/
/*ci->map_param=_ogg_calloc(ci->maps,sizeof(void *));*/
for(i=0;i<ci->maps;i++){
ci->map_type[i]=oggpack_read(opb,16);
if(ci->map_type[i]<0 || ci->map_type[i]>=VI_MAPB)goto err_out;
ci->map_param[i]=_mapping_P[ci->map_type[i]]->unpack(vi,opb);
if(!ci->map_param[i])goto err_out;
}
/* mode settings */
ci->modes=oggpack_read(opb,6)+1;
/*vi->mode_param=_ogg_calloc(vi->modes,sizeof(void *));*/
for(i=0;i<ci->modes;i++){
ci->mode_param[i]=(vorbis_info_mode *)_ogg_calloc(1,sizeof(*ci->mode_param[i]));
ci->mode_param[i]->blockflag=oggpack_read(opb,1);
ci->mode_param[i]->windowtype=oggpack_read(opb,16);
ci->mode_param[i]->transformtype=oggpack_read(opb,16);
ci->mode_param[i]->mapping=oggpack_read(opb,8);
if(ci->mode_param[i]->windowtype>=VI_WINDOWB)goto err_out;
if(ci->mode_param[i]->transformtype>=VI_WINDOWB)goto err_out;
if(ci->mode_param[i]->mapping>=ci->maps)goto err_out;
}
if(oggpack_read(opb,1)!=1)goto err_out; /* top level EOP check */
return(0);
err_out:
vorbis_info_clear(vi);
return(OV_EBADHEADER);
}
diff --git a/noncore/apps/opie-write/qrichtext.cpp b/noncore/apps/opie-write/qrichtext.cpp
index f040f1e..768da44 100644
--- a/noncore/apps/opie-write/qrichtext.cpp
+++ b/noncore/apps/opie-write/qrichtext.cpp
@@ -1,427 +1,436 @@
/****************************************************************************
** $Id$
**
** Implementation of the internal Qt classes dealing with rich text
**
** Created : 990101
**
** Copyright (C) 1992-2000 Trolltech AS. All rights reserved.
**
** This file is part of the kernel module of the Qt GUI Toolkit.
**
** This file may be distributed under the terms of the Q Public License
** as defined by Trolltech AS of Norway and appearing in the file
** LICENSE.QPL included in the packaging of this file.
**
** 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.
**
** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition
** licenses may use this file in accordance with the Qt Commercial License
** Agreement provided with the Software.
**
** 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/pricing.html or email sales@trolltech.com for
** information about Qt Commercial License Agreements.
** See http://www.trolltech.com/qpl/ for QPL licensing information.
** 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.
**
**********************************************************************/
#include "qrichtext_p.h"
/* OPIE */
#include <opie2/odebug.h>
using namespace Opie::Core;
/* QT */
#include "qdragobject.h"
#include "qpaintdevicemetrics.h"
#include "qdrawutil.h"
#include "qcleanuphandler.h"
/* STD */
#include <stdlib.h>
using namespace Qt3;
static QTextCursor* richTextExportStart = 0;
static QTextCursor* richTextExportEnd = 0;
static QTextFormatCollection *qFormatCollection = 0;
const int border_tolerance = 2;
#ifdef Q_WS_WIN
#include "qt_windows.h"
#endif
#define QChar_linesep QChar(0x2028U)
static inline bool is_printer( QPainter *p )
{
if ( !p || !p->device() )
return FALSE;
return p->device()->devType() == QInternal::Printer;
}
static inline int scale( int value, QPainter *painter )
{
if ( is_printer( painter ) ) {
QPaintDeviceMetrics metrics( painter->device() );
#if defined(Q_WS_X11)
value = value * metrics.logicalDpiY() / QPaintDevice::x11AppDpiY();
#elif defined (Q_WS_WIN)
HDC hdc = GetDC( 0 );
int gdc = GetDeviceCaps( hdc, LOGPIXELSY );
if ( gdc )
value = value * metrics.logicalDpiY() / gdc;
ReleaseDC( 0, hdc );
#elif defined (Q_WS_MAC)
value = value * metrics.logicalDpiY() / 75; // ##### FIXME
#elif defined (Q_WS_QWS)
value = value * metrics.logicalDpiY() / 75;
#endif
}
return value;
}
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
void QTextCommandHistory::addCommand( QTextCommand *cmd )
{
if ( current < (int)history.count() - 1 ) {
QPtrList<QTextCommand> commands;
commands.setAutoDelete( FALSE );
for( int i = 0; i <= current; ++i ) {
commands.insert( i, history.at( 0 ) );
history.take( 0 );
}
commands.append( cmd );
history.clear();
history = commands;
history.setAutoDelete( TRUE );
} else {
history.append( cmd );
}
if ( (int)history.count() > steps )
history.removeFirst();
else
++current;
}
QTextCursor *QTextCommandHistory::undo( QTextCursor *c )
{
if ( current > -1 ) {
QTextCursor *c2 = history.at( current )->unexecute( c );
--current;
return c2;
}
return 0;
}
QTextCursor *QTextCommandHistory::redo( QTextCursor *c )
{
if ( current > -1 ) {
if ( current < (int)history.count() - 1 ) {
++current;
return history.at( current )->execute( c );
}
} else {
if ( history.count() > 0 ) {
++current;
return history.at( current )->execute( c );
}
}
return 0;
}
bool QTextCommandHistory::isUndoAvailable()
{
return current > -1;
}
bool QTextCommandHistory::isRedoAvailable()
{
return current > -1 && current < (int)history.count() - 1 || current == -1 && history.count() > 0;
}
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
QTextDeleteCommand::QTextDeleteCommand( QTextDocument *d, int i, int idx, const QMemArray<QTextStringChar> &str,
const QByteArray& oldStyleInfo )
: QTextCommand( d ), id( i ), index( idx ), parag( 0 ), text( str ), styleInformation( oldStyleInfo )
{
for ( int j = 0; j < (int)text.size(); ++j ) {
if ( text[ j ].format() )
text[ j ].format()->addRef();
}
}
QTextDeleteCommand::QTextDeleteCommand( QTextParagraph *p, int idx, const QMemArray<QTextStringChar> &str )
: QTextCommand( 0 ), id( -1 ), index( idx ), parag( p ), text( str )
{
for ( int i = 0; i < (int)text.size(); ++i ) {
if ( text[ i ].format() )
text[ i ].format()->addRef();
}
}
QTextDeleteCommand::~QTextDeleteCommand()
{
for ( int i = 0; i < (int)text.size(); ++i ) {
if ( text[ i ].format() )
text[ i ].format()->removeRef();
}
text.resize( 0 );
}
QTextCursor *QTextDeleteCommand::execute( QTextCursor *c )
{
QTextParagraph *s = doc ? doc->paragAt( id ) : parag;
- if ( !s ) {
+ if ( !s && doc ) {
owarn << "can't locate parag at " << id << ", last parag: " << doc->lastParagraph()->paragId() << "" << oendl;
return 0;
+ } else if ( !doc ) {
+ owarn << "No valid doc" << oendl;
+ return 0;
}
cursor.setParagraph( s );
cursor.setIndex( index );
int len = text.size();
if ( c )
*c = cursor;
if ( doc ) {
doc->setSelectionStart( QTextDocument::Temp, cursor );
for ( int i = 0; i < len; ++i )
cursor.gotoNextLetter();
doc->setSelectionEnd( QTextDocument::Temp, cursor );
doc->removeSelectedText( QTextDocument::Temp, &cursor );
if ( c )
*c = cursor;
} else {
s->remove( index, len );
}
return c;
}
QTextCursor *QTextDeleteCommand::unexecute( QTextCursor *c )
{
QTextParagraph *s = doc ? doc->paragAt( id ) : parag;
- if ( !s ) {
+ if ( !s && doc ) {
owarn << "can't locate parag at " << id << ", last parag: " << doc->lastParagraph()->paragId() << "" << oendl;
return 0;
+ } else if ( !doc ) {
+ owarn << "No valid doc" << oendl;
+ return 0;
}
cursor.setParagraph( s );
cursor.setIndex( index );
QString str = QTextString::toString( text );
cursor.insert( str, TRUE, &text );
cursor.setParagraph( s );
cursor.setIndex( index );
if ( c ) {
c->setParagraph( s );
c->setIndex( index );
for ( int i = 0; i < (int)text.size(); ++i )
c->gotoNextLetter();
+ } else {
+ owarn << "No valid cursor" << oendl;
+ return 0;
}
if ( !styleInformation.isEmpty() ) {
QDataStream styleStream( styleInformation, IO_ReadOnly );
int num;
styleStream >> num;
QTextParagraph *p = s;
while ( num-- && p ) {
p->readStyleInformation( styleStream );
p = p->next();
}
}
s = cursor.paragraph();
while ( s ) {
s->format();
s->setChanged( TRUE );
if ( s == c->paragraph() )
break;
s = s->next();
}
return &cursor;
}
QTextFormatCommand::QTextFormatCommand( QTextDocument *d, int sid, int sidx, int eid, int eidx,
const QMemArray<QTextStringChar> &old, QTextFormat *f, int fl )
: QTextCommand( d ), startId( sid ), startIndex( sidx ), endId( eid ), endIndex( eidx ), format( f ), oldFormats( old ), flags( fl )
{
format = d->formatCollection()->format( f );
for ( int j = 0; j < (int)oldFormats.size(); ++j ) {
if ( oldFormats[ j ].format() )
oldFormats[ j ].format()->addRef();
}
}
QTextFormatCommand::~QTextFormatCommand()
{
format->removeRef();
for ( int j = 0; j < (int)oldFormats.size(); ++j ) {
if ( oldFormats[ j ].format() )
oldFormats[ j ].format()->removeRef();
}
}
QTextCursor *QTextFormatCommand::execute( QTextCursor *c )
{
QTextParagraph *sp = doc->paragAt( startId );
QTextParagraph *ep = doc->paragAt( endId );
if ( !sp || !ep )
return c;
QTextCursor start( doc );
start.setParagraph( sp );
start.setIndex( startIndex );
QTextCursor end( doc );
end.setParagraph( ep );
end.setIndex( endIndex );
doc->setSelectionStart( QTextDocument::Temp, start );
doc->setSelectionEnd( QTextDocument::Temp, end );
doc->setFormat( QTextDocument::Temp, format, flags );
doc->removeSelection( QTextDocument::Temp );
if ( endIndex == ep->length() )
end.gotoLeft();
*c = end;
return c;
}
QTextCursor *QTextFormatCommand::unexecute( QTextCursor *c )
{
QTextParagraph *sp = doc->paragAt( startId );
QTextParagraph *ep = doc->paragAt( endId );
if ( !sp || !ep )
return 0;
int idx = startIndex;
int fIndex = 0;
for ( ;; ) {
if ( oldFormats.at( fIndex ).c == '\n' ) {
if ( idx > 0 ) {
if ( idx < sp->length() && fIndex > 0 )
sp->setFormat( idx, 1, oldFormats.at( fIndex - 1 ).format() );
if ( sp == ep )
break;
sp = sp->next();
idx = 0;
}
fIndex++;
}
if ( oldFormats.at( fIndex ).format() )
sp->setFormat( idx, 1, oldFormats.at( fIndex ).format() );
idx++;
fIndex++;
if ( fIndex >= (int)oldFormats.size() )
break;
if ( idx >= sp->length() ) {
if ( sp == ep )
break;
sp = sp->next();
idx = 0;
}
}
QTextCursor end( doc );
end.setParagraph( ep );
end.setIndex( endIndex );
if ( endIndex == ep->length() )
end.gotoLeft();
*c = end;
return c;
}
QTextStyleCommand::QTextStyleCommand( QTextDocument *d, int fParag, int lParag, const QByteArray& beforeChange )
: QTextCommand( d ), firstParag( fParag ), lastParag( lParag ), before( beforeChange )
{
after = readStyleInformation( d, fParag, lParag );
}
QByteArray QTextStyleCommand::readStyleInformation( QTextDocument* doc, int fParag, int lParag )
{
QByteArray style;
QTextParagraph *p = doc->paragAt( fParag );
if ( !p )
return style;
QDataStream styleStream( style, IO_WriteOnly );
int num = lParag - fParag + 1;
styleStream << num;
while ( num -- && p ) {
p->writeStyleInformation( styleStream );
p = p->next();
}
return style;
}
void QTextStyleCommand::writeStyleInformation( QTextDocument* doc, int fParag, const QByteArray& style )
{
QTextParagraph *p = doc->paragAt( fParag );
if ( !p )
return;
QDataStream styleStream( style, IO_ReadOnly );
int num;
styleStream >> num;
while ( num-- && p ) {
p->readStyleInformation( styleStream );
p = p->next();
}
}
QTextCursor *QTextStyleCommand::execute( QTextCursor *c )
{
writeStyleInformation( doc, firstParag, after );
return c;
}
QTextCursor *QTextStyleCommand::unexecute( QTextCursor *c )
{
writeStyleInformation( doc, firstParag, before );
return c;
}
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
QTextCursor::QTextCursor( QTextDocument *d )
: idx( 0 ), tmpIndex( -1 ), ox( 0 ), oy( 0 ),
valid( TRUE )
{
para = d ? d->firstParagraph() : 0;
}
QTextCursor::QTextCursor( const QTextCursor &c )
{
ox = c.ox;
oy = c.oy;
idx = c.idx;
para = c.para;
tmpIndex = c.tmpIndex;
indices = c.indices;
paras = c.paras;
xOffsets = c.xOffsets;
yOffsets = c.yOffsets;
valid = c.valid;
}
QTextCursor &QTextCursor::operator=( const QTextCursor &c )
{
ox = c.ox;
oy = c.oy;
idx = c.idx;
para = c.para;
tmpIndex = c.tmpIndex;
indices = c.indices;
@@ -1203,402 +1212,413 @@ void QTextDocument::init()
backBrush = 0;
buf_pixmap = 0;
nextDoubleBuffered = FALSE;
if ( par )
withoutDoubleBuffer = par->withoutDoubleBuffer;
else
withoutDoubleBuffer = FALSE;
lParag = fParag = createParagraph( this, 0, 0 );
cx = 0;
cy = 2;
if ( par )
cx = cy = 0;
cw = 600;
vw = 0;
flow_ = new QTextFlow;
flow_->setWidth( cw );
leftmargin = rightmargin = 4;
scaleFontsFactor = 1;
selectionColors[ Standard ] = QApplication::palette().color( QPalette::Active, QColorGroup::Highlight );
selectionText[ Standard ] = TRUE;
commandHistory = new QTextCommandHistory( 100 );
tStopWidth = formatCollection()->defaultFormat()->width( 'x' ) * 8;
}
QTextDocument::~QTextDocument()
{
if ( par )
par->removeChild( this );
clear();
delete commandHistory;
delete flow_;
if ( !par )
delete pFormatter;
delete fCollection;
delete pProcessor;
delete buf_pixmap;
delete indenter;
delete backBrush;
if ( tArray )
delete [] tArray;
}
void QTextDocument::clear( bool createEmptyParag )
{
if ( flow_ )
flow_->clear();
while ( fParag ) {
QTextParagraph *p = fParag->next();
delete fParag;
fParag = p;
}
fParag = lParag = 0;
if ( createEmptyParag )
fParag = lParag = createParagraph( this );
selections.clear();
oText = QString::null;
oTextValid = TRUE;
}
int QTextDocument::widthUsed() const
{
return wused + border_tolerance;
}
int QTextDocument::height() const
{
int h = 0;
if ( lParag )
h = lParag->rect().top() + lParag->rect().height() + 1;
int fh = flow_->boundingRect().bottom();
return QMAX( h, fh );
}
QTextParagraph *QTextDocument::createParagraph( QTextDocument *d, QTextParagraph *pr, QTextParagraph *nx, bool updateIds )
{
return new QTextParagraph( d, pr, nx, updateIds );
}
bool QTextDocument::setMinimumWidth( int needed, int used, QTextParagraph *p )
{
if ( needed == -1 ) {
minw = 0;
wused = 0;
p = 0;
}
if ( p == minwParag ) {
minw = needed;
emit minimumWidthChanged( minw );
} else if ( needed > minw ) {
minw = needed;
minwParag = p;
emit minimumWidthChanged( minw );
}
wused = QMAX( wused, used );
wused = QMAX( wused, minw );
cw = QMAX( minw, cw );
return TRUE;
}
void QTextDocument::setPlainText( const QString &text )
{
clear();
preferRichText = FALSE;
oTextValid = TRUE;
oText = text;
int lastNl = 0;
int nl = text.find( '\n' );
if ( nl == -1 ) {
lParag = createParagraph( this, lParag, 0 );
if ( !fParag )
fParag = lParag;
QString s = text;
if ( !s.isEmpty() ) {
if ( s[ (int)s.length() - 1 ] == '\r' )
s.remove( s.length() - 1, 1 );
lParag->append( s );
}
} else {
for (;;) {
lParag = createParagraph( this, lParag, 0 );
if ( !fParag )
fParag = lParag;
QString s = text.mid( lastNl, nl - lastNl );
if ( !s.isEmpty() ) {
if ( s[ (int)s.length() - 1 ] == '\r' )
s.remove( s.length() - 1, 1 );
lParag->append( s );
}
if ( nl == 0xffffff )
break;
lastNl = nl + 1;
nl = text.find( '\n', nl + 1 );
if ( nl == -1 )
nl = 0xffffff;
}
}
if ( !lParag )
lParag = fParag = createParagraph( this, 0, 0 );
}
struct Q_EXPORT QTextDocumentTag {
QTextDocumentTag(){}
QTextDocumentTag( const QString&n, const QStyleSheetItem* s, const QTextFormat& f )
:name(n),style(s), format(f), alignment(Qt3::AlignAuto), direction(QChar::DirON),liststyle(QStyleSheetItem::ListDisc) {
wsm = QStyleSheetItem::WhiteSpaceNormal;
}
QString name;
const QStyleSheetItem* style;
QString anchorHref;
QStyleSheetItem::WhiteSpaceMode wsm;
QTextFormat format;
int alignment : 16;
int direction : 5;
QStyleSheetItem::ListStyle liststyle;
QTextDocumentTag( const QTextDocumentTag& t ) {
name = t.name;
style = t.style;
anchorHref = t.anchorHref;
wsm = t.wsm;
format = t.format;
alignment = t.alignment;
direction = t.direction;
liststyle = t.liststyle;
}
QTextDocumentTag& operator=(const QTextDocumentTag& t) {
name = t.name;
style = t.style;
anchorHref = t.anchorHref;
wsm = t.wsm;
format = t.format;
alignment = t.alignment;
direction = t.direction;
liststyle = t.liststyle;
return *this;
}
#if defined(Q_FULL_TEMPLATE_INSTANTIATION)
bool operator==( const QTextDocumentTag& ) const { return FALSE; }
#endif
};
-#define NEWPAR do{ if ( !hasNewPar) { \
- if ( !textEditMode && curpar && curpar->length()>1 && curpar->at( curpar->length()-2)->c == QChar_linesep ) \
- curpar->remove( curpar->length()-2, 1 ); \
- curpar = createParagraph( this, curpar, curpar->next() ); styles.append( vec ); vec = 0;} \
- hasNewPar = TRUE; \
- curpar->rtext = TRUE; \
- curpar->align = curtag.alignment; \
- curpar->lstyle = curtag.liststyle; \
- curpar->litem = ( curtag.style->displayMode() == QStyleSheetItem::DisplayListItem ); \
- curpar->str->setDirection( (QChar::Direction)curtag.direction ); \
- space = TRUE; \
- delete vec; vec = new QPtrVector<QStyleSheetItem>( (uint)tags.count() + 1); \
- int i = 0; \
- for ( QValueStack<QTextDocumentTag>::Iterator it = tags.begin(); it != tags.end(); ++it ) \
- vec->insert( i++, (*it).style ); \
- vec->insert( i, curtag.style ); \
- }while(FALSE)
-
+#define NEWPAR do { \
+ if ( !hasNewPar) { \
+ if ( !curpar ) { \
+ owarn << "no current paragraph" << oendl; \
+ return; \
+ } \
+ if ( !textEditMode && curpar && curpar->length()>1 && curpar->at( curpar->length()-2)->c == QChar_linesep ) \
+ curpar->remove( curpar->length()-2, 1 ); \
+ curpar = createParagraph( this, curpar, curpar->next() ); styles.append( vec ); \
+ if ( !curpar ) { \
+ owarn << "failed in creating a new paragraph" << oendl; \
+ return; \
+ } \
+ vec = 0; \
+ } \
+ hasNewPar = TRUE; \
+ curpar->rtext = TRUE; \
+ curpar->align = curtag.alignment; \
+ curpar->lstyle = curtag.liststyle; \
+ curpar->litem = ( curtag.style->displayMode() == QStyleSheetItem::DisplayListItem ); \
+ curpar->str->setDirection( (QChar::Direction)curtag.direction ); \
+ space = TRUE; \
+ delete vec; \
+ vec = new QPtrVector<QStyleSheetItem>( (uint)tags.count() + 1); \
+ int i = 0; \
+ for ( QValueStack<QTextDocumentTag>::Iterator it = tags.begin(); it != tags.end(); ++it ) \
+ vec->insert( i++, (*it).style ); \
+ vec->insert( i, curtag.style ); \
+ } while ( FALSE )
void QTextDocument::setRichText( const QString &text, const QString &context )
{
if ( !context.isEmpty() )
setContext( context );
clear();
fParag = lParag = createParagraph( this );
oTextValid = TRUE;
oText = text;
setRichTextInternal( text );
fParag->rtext = TRUE;
}
void QTextDocument::setRichTextInternal( const QString &text, QTextCursor* cursor )
{
QTextParagraph* curpar = lParag;
int pos = 0;
QValueStack<QTextDocumentTag> tags;
QTextDocumentTag initag( "", sheet_->item(""), *formatCollection()->defaultFormat() );
QTextDocumentTag curtag = initag;
bool space = TRUE;
bool canMergeLi = FALSE;
bool textEditMode = FALSE;
const QChar* doc = text.unicode();
int length = text.length();
bool hasNewPar = curpar->length() <= 1;
QString anchorName;
// style sheet handling for margin and line spacing calculation below
QTextParagraph* stylesPar = curpar;
QPtrVector<QStyleSheetItem>* vec = 0;
QPtrList< QPtrVector<QStyleSheetItem> > styles;
styles.setAutoDelete( TRUE );
if ( cursor ) {
cursor->splitAndInsertEmptyParagraph();
QTextCursor tmp = *cursor;
tmp.gotoPreviousLetter();
stylesPar = curpar = tmp.paragraph();
hasNewPar = TRUE;
textEditMode = TRUE;
} else {
NEWPAR;
}
// set rtext spacing to FALSE for the initial paragraph.
curpar->rtext = FALSE;
QString wellKnownTags = "br hr wsp table qt body meta title";
while ( pos < length ) {
if ( hasPrefix(doc, length, pos, '<' ) ){
if ( !hasPrefix( doc, length, pos+1, QChar('/') ) ) {
// open tag
QMap<QString, QString> attr;
bool emptyTag = FALSE;
QString tagname = parseOpenTag(doc, length, pos, attr, emptyTag);
if ( tagname.isEmpty() )
continue; // nothing we could do with this, probably parse error
const QStyleSheetItem* nstyle = sheet_->item(tagname);
if ( nstyle ) {
// we might have to close some 'forgotten' tags
while ( !nstyle->allowedInContext( curtag.style ) ) {
QString msg;
msg.sprintf( "QText Warning: Document not valid ( '%s' not allowed in '%s' #%d)",
tagname.ascii(), curtag.style->name().ascii(), pos);
sheet_->error( msg );
if ( tags.isEmpty() )
break;
curtag = tags.pop();
}
/* special handling for p and li for HTML
compatibility. We do not want to embed blocks in
p, and we do not want new blocks inside non-empty
lis. Plus we want to merge empty lis sometimes. */
if( nstyle->displayMode() == QStyleSheetItem::DisplayListItem ) {
canMergeLi = TRUE;
} else if ( nstyle->displayMode() == QStyleSheetItem::DisplayBlock ) {
while ( curtag.style->name() == "p" ) {
if ( tags.isEmpty() )
break;
curtag = tags.pop();
}
if ( curtag.style->displayMode() == QStyleSheetItem::DisplayListItem ) {
// we are in a li and a new block comes along
if ( nstyle->name() == "ul" || nstyle->name() == "ol" )
hasNewPar = FALSE; // we want an empty li (like most browsers)
if ( !hasNewPar ) {
/* do not add new blocks inside
non-empty lis */
while ( curtag.style->displayMode() == QStyleSheetItem::DisplayListItem ) {
if ( tags.isEmpty() )
break;
curtag = tags.pop();
}
} else if ( canMergeLi ) {
/* we have an empty li and a block
comes along, merge them */
nstyle = curtag.style;
}
canMergeLi = FALSE;
}
}
}
QTextCustomItem* custom = 0;
// some well-known tags, some have a nstyle, some not
if ( wellKnownTags.find( tagname ) != -1 ) {
if ( tagname == "br" ) {
emptyTag = space = TRUE;
int index = QMAX( curpar->length(),1) - 1;
QTextFormat format = curtag.format.makeTextFormat( nstyle, attr, scaleFontsFactor );
curpar->append( QChar_linesep );
curpar->setFormat( index, 1, &format );
} else if ( tagname == "hr" ) {
emptyTag = space = TRUE;
custom = sheet_->tag( tagname, attr, contxt, *factory_ , emptyTag, this );
NEWPAR;
} else if ( tagname == "table" ) {
emptyTag = space = TRUE;
QTextFormat format = curtag.format.makeTextFormat( nstyle, attr, scaleFontsFactor );
curpar->setAlignment( curtag.alignment );
custom = parseTable( attr, format, doc, length, pos, curpar );
} else if ( tagname == "qt" || tagname == "body" ) {
if ( attr.contains( "bgcolor" ) ) {
QBrush *b = new QBrush( QColor( attr["bgcolor"] ) );
setPaper( b );
}
if ( attr.contains( "background" ) ) {
QImage img;
QString bg = attr["background"];
const QMimeSource* m = factory_->data( bg, contxt );
if ( !m ) {
owarn << "QRichText: no mimesource for " << bg.latin1() << "" << oendl;
} else {
if ( !QImageDrag::decode( m, img ) ) {
owarn << "QTextImage: cannot decode " << bg.latin1() << "" << oendl;
}
}
if ( !img.isNull() ) {
QPixmap pm;
pm.convertFromImage( img );
QBrush *b = new QBrush( QColor(), pm );
setPaper( b );
}
}
if ( attr.contains( "text" ) ) {
QColor c( attr["text"] );
if ( formatCollection()->defaultFormat()->color() != c ) {
QDict<QTextFormat> formats = formatCollection()->dict();
QDictIterator<QTextFormat> it( formats );
while ( it.current() ) {
if ( it.current() == formatCollection()->defaultFormat() ) {
++it;
continue;
}
it.current()->setColor( c );
++it;
}
formatCollection()->defaultFormat()->setColor( c );
curtag.format.setColor( c );
}
}
if ( attr.contains( "link" ) )
linkColor = QColor( attr["link"] );
if ( attr.contains( "title" ) )
attribs.replace( "title", attr["title"] );
if ( textEditMode ) {
if ( attr.contains("style" ) ) {
QString a = attr["style"];
for ( int s = 0; s < a.contains(';')+1; s++ ) {
QString style = QTextDocument::section( a, ";", s, s );
if ( style.startsWith("font-size:" ) && QTextDocument::endsWith(style, "pt") ) {
scaleFontsFactor = double( formatCollection()->defaultFormat()->fn.pointSize() ) /
style.mid( 10, style.length() - 12 ).toInt();
}
}
}
nstyle = 0; // ignore body in textEditMode
}
// end qt- and body-tag handling
} else if ( tagname == "meta" ) {
if ( attr["name"] == "qrichtext" && attr["content"] == "1" )
textEditMode = TRUE;
@@ -1706,386 +1726,389 @@ void QTextDocument::setRichTextInternal( const QString &text, QTextCursor* curso
xMargin() functions we restrict ourselves to
<ol>. Once we calculate the margins in the
parser rathern than later, the unelegance of
this approach goes awy
*/
if ( nstyle->name() == "ul" )
curtag.style = sheet_->item( "ol" );
if ( attr.contains( "align" ) ) {
QString align = attr["align"];
if ( align == "center" )
curtag.alignment = Qt::AlignCenter;
else if ( align == "right" )
curtag.alignment = Qt::AlignRight;
else if ( align == "justify" )
curtag.alignment = Qt3::AlignJustify;
}
if ( attr.contains( "dir" ) ) {
QString dir = attr["dir"];
if ( dir == "rtl" )
curtag.direction = QChar::DirR;
else if ( dir == "ltr" )
curtag.direction = QChar::DirL;
}
NEWPAR;
if ( curtag.style->displayMode() == QStyleSheetItem::DisplayListItem ) {
if ( attr.contains( "value " ) )
curpar->setListValue( attr["value"].toInt() );
}
if ( attr.contains( "style" ) ) {
QString a = attr["style"];
bool ok = TRUE;
for ( int s = 0; ok && s < a.contains(';')+1; s++ ) {
QString style = QTextDocument::section( a, ";", s, s );
if ( style.startsWith("margin-top:" ) && QTextDocument::endsWith(style, "px") )
curpar->utm = 1+style.mid(11, style.length() - 13).toInt(&ok);
else if ( style.startsWith("margin-bottom:" ) && QTextDocument::endsWith(style, "px") )
curpar->ubm = 1+style.mid(14, style.length() - 16).toInt(&ok);
else if ( style.startsWith("margin-left:" ) && QTextDocument::endsWith(style, "px") )
curpar->ulm = 1+style.mid(12, style.length() - 14).toInt(&ok);
else if ( style.startsWith("margin-right:" ) && QTextDocument::endsWith(style, "px") )
curpar->urm = 1+style.mid(13, style.length() - 15).toInt(&ok);
else if ( style.startsWith("text-indent:" ) && QTextDocument::endsWith(style, "px") )
curpar->uflm = 1+style.mid(12, style.length() - 14).toInt(&ok);
}
if ( !ok ) // be pressmistic
curpar->utm = curpar->ubm = curpar->urm = curpar->ulm = 0;
}
}
}
} else {
QString tagname = parseCloseTag( doc, length, pos );
if ( tagname.isEmpty() )
continue; // nothing we could do with this, probably parse error
if ( !sheet_->item( tagname ) ) // ignore unknown tags
continue;
// we close a block item. Since the text may continue, we need to have a new paragraph
bool needNewPar = curtag.style->displayMode() == QStyleSheetItem::DisplayBlock
|| curtag.style->displayMode() == QStyleSheetItem::DisplayListItem;
// html slopiness: handle unbalanched tag closing
while ( curtag.name != tagname ) {
QString msg;
msg.sprintf( "QText Warning: Document not valid ( '%s' not closed before '%s' #%d)",
curtag.name.ascii(), tagname.ascii(), pos);
sheet_->error( msg );
if ( tags.isEmpty() )
break;
curtag = tags.pop();
}
// close the tag
if ( !tags.isEmpty() )
curtag = tags.pop();
else
curtag = initag;
if ( needNewPar ) {
if ( textEditMode && tagname == "p" ) // preserve empty paragraphs
hasNewPar = FALSE;
NEWPAR;
}
}
} else {
// normal contents
QString s;
QChar c;
while ( pos < length && !hasPrefix(doc, length, pos, QChar('<') ) ){
if ( textEditMode ) {
// text edit mode: we handle all white space but ignore newlines
c = parseChar( doc, length, pos, QStyleSheetItem::WhiteSpacePre );
if ( c == QChar_linesep )
break;
} else {
int l = pos;
c = parseChar( doc, length, pos, curtag.wsm );
// in white space pre mode: treat any space as non breakable
if ( c == ' ' && curtag.wsm == QStyleSheetItem::WhiteSpacePre )
c = QChar::nbsp;
if ( c == ' ' || c == QChar_linesep ) {
/* avoid overlong paragraphs by forcing a new
paragraph after 4096 characters. This case can
occur when loading undiscovered plain text
documents in rich text mode. Instead of hanging
forever, we do the trick.
*/
if ( curtag.wsm == QStyleSheetItem::WhiteSpaceNormal && s.length() > 4096 ) do {
if ( doc[l] == '\n' ) {
hasNewPar = FALSE; // for a new paragraph ...
NEWPAR;
hasNewPar = FALSE; // ... and make it non-reusable
c = '\n'; // make sure we break below
break;
}
} while ( ++l < pos );
}
}
if ( c == '\n' )
break; // break on newlines, pre delievers a QChar_linesep
bool c_isSpace = c.isSpace() && c.unicode() != 0x00a0U && !textEditMode;
if ( curtag.wsm == QStyleSheetItem::WhiteSpaceNormal && c_isSpace && space )
continue;
if ( c == '\r' )
continue;
space = c_isSpace;
s += c;
}
if ( !s.isEmpty() && curtag.style->displayMode() != QStyleSheetItem::DisplayNone ) {
hasNewPar = FALSE;
int index = QMAX( curpar->length(),1) - 1;
curpar->append( s );
QTextFormat* f = formatCollection()->format( &curtag.format );
curpar->setFormat( index, s.length(), f, FALSE ); // do not use collection because we have done that already
f->ref += s.length() -1; // that what friends are for...
if ( !curtag.anchorHref.isEmpty() ) {
for ( int i = 0; i < int(s.length()); i++ )
curpar->at(index + i)->setAnchor( QString::null, curtag.anchorHref );
}
if ( !anchorName.isEmpty() ) {
curpar->at(index)->setAnchor( anchorName, curpar->at(index)->anchorHref() );
anchorName = QString::null;
}
}
}
}
if ( hasNewPar && curpar != fParag && !cursor ) {
// cleanup unused last paragraphs
curpar = curpar->p;
delete curpar->n;
}
if ( !anchorName.isEmpty() ) {
curpar->at(curpar->length() - 1)->setAnchor( anchorName, curpar->at( curpar->length() - 1 )->anchorHref() );
anchorName = QString::null;
}
setRichTextMarginsInternal( styles, stylesPar );
if ( cursor ) {
cursor->gotoPreviousLetter();
cursor->remove();
}
}
void QTextDocument::setRichTextMarginsInternal( QPtrList< QPtrVector<QStyleSheetItem> >& styles, QTextParagraph* stylesPar )
{
// margin and line spacing calculation
QPtrVector<QStyleSheetItem>* prevStyle = 0;
QPtrVector<QStyleSheetItem>* curStyle = styles.first();
QPtrVector<QStyleSheetItem>* nextStyle = styles.next();
while ( stylesPar ) {
if ( !curStyle ) {
stylesPar = stylesPar->next();
prevStyle = curStyle;
curStyle = nextStyle;
nextStyle = styles.next();
continue;
}
int i, mar;
- QStyleSheetItem* mainStyle = curStyle->size() ? (*curStyle)[curStyle->size()-1] : 0;
- if ( mainStyle && mainStyle->displayMode() == QStyleSheetItem::DisplayListItem )
+ QStyleSheetItem* mainStyle = (*curStyle)[curStyle->size()-1];
+ if ( !mainStyle )
+ return;
+
+ if ( mainStyle->displayMode() == QStyleSheetItem::DisplayListItem )
stylesPar->setListItem( TRUE );
int numLists = 0;
for ( i = 0; i < (int)curStyle->size(); ++i ) {
if ( (*curStyle)[ i ]->displayMode() == QStyleSheetItem::DisplayBlock
&& int((*curStyle)[ i ]->listStyle()) != QStyleSheetItem::Undefined )
numLists++;
}
stylesPar->ldepth = numLists;
if ( stylesPar->next() && nextStyle ) {
// also set the depth of the next paragraph, required for the margin calculation
numLists = 0;
for ( i = 0; i < (int)nextStyle->size(); ++i ) {
if ( (*nextStyle)[ i ]->displayMode() == QStyleSheetItem::DisplayBlock
&& int((*nextStyle)[ i ]->listStyle()) != QStyleSheetItem::Undefined )
numLists++;
}
stylesPar->next()->ldepth = numLists;
}
// do the top margin
QStyleSheetItem* item = mainStyle;
int m;
if (stylesPar->utm > 0 ) {
m = stylesPar->utm-1;
stylesPar->utm = 0;
} else {
m = QMAX(0, item->margin( QStyleSheetItem::MarginTop ) );
if ( item->displayMode() == QStyleSheetItem::DisplayListItem
&& stylesPar->ldepth )
m /= stylesPar->ldepth;
}
for ( i = (int)curStyle->size() - 2 ; i >= 0; --i ) {
item = (*curStyle)[ i ];
if ( prevStyle && i < (int) prevStyle->size() &&
( item->displayMode() == QStyleSheetItem::DisplayBlock &&
(*prevStyle)[ i ] == item ) )
break;
// emulate CSS2' standard 0 vertical margin for multiple ul or ol tags
if ( int(item->listStyle()) != QStyleSheetItem::Undefined &&
( ( i> 0 && (*curStyle)[ i-1 ] == item ) || (*curStyle)[i+1] == item ) )
continue;
mar = QMAX( 0, item->margin( QStyleSheetItem::MarginTop ) );
m = QMAX( m, mar );
}
stylesPar->utm = m - stylesPar->topMargin();
// do the bottom margin
item = mainStyle;
if (stylesPar->ubm > 0 ) {
m = stylesPar->ubm-1;
stylesPar->ubm = 0;
} else {
m = QMAX(0, item->margin( QStyleSheetItem::MarginBottom ) );
if ( item->displayMode() == QStyleSheetItem::DisplayListItem
&& stylesPar->ldepth )
m /= stylesPar->ldepth;
}
for ( i = (int)curStyle->size() - 2 ; i >= 0; --i ) {
item = (*curStyle)[ i ];
if ( nextStyle && i < (int) nextStyle->size() &&
( item->displayMode() == QStyleSheetItem::DisplayBlock &&
(*nextStyle)[ i ] == item ) )
break;
// emulate CSS2' standard 0 vertical margin for multiple ul or ol tags
if ( int(item->listStyle()) != QStyleSheetItem::Undefined &&
( ( i> 0 && (*curStyle)[ i-1 ] == item ) || (*curStyle)[i+1] == item ) )
continue;
mar = QMAX(0, item->margin( QStyleSheetItem::MarginBottom ) );
m = QMAX( m, mar );
}
stylesPar->ubm = m - stylesPar->bottomMargin();
// do the left margin, simplyfied
item = mainStyle;
if (stylesPar->ulm > 0 ) {
m = stylesPar->ulm-1;
stylesPar->ulm = 0;
} else {
m = QMAX( 0, item->margin( QStyleSheetItem::MarginLeft ) );
}
for ( i = (int)curStyle->size() - 2 ; i >= 0; --i ) {
item = (*curStyle)[ i ];
m += QMAX( 0, item->margin( QStyleSheetItem::MarginLeft ) );
}
stylesPar->ulm = m - stylesPar->leftMargin();
// do the right margin, simplyfied
item = mainStyle;
if (stylesPar->urm > 0 ) {
m = stylesPar->urm-1;
stylesPar->urm = 0;
} else {
m = QMAX( 0, item->margin( QStyleSheetItem::MarginRight ) );
}
for ( i = (int)curStyle->size() - 2 ; i >= 0; --i ) {
item = (*curStyle)[ i ];
m += QMAX( 0, item->margin( QStyleSheetItem::MarginRight ) );
}
stylesPar->urm = m - stylesPar->rightMargin();
// do the first line margin, which really should be called text-indent
item = mainStyle;
if (stylesPar->uflm > 0 ) {
m = stylesPar->uflm-1;
stylesPar->uflm = 0;
} else {
m = QMAX( 0, item->margin( QStyleSheetItem::MarginFirstLine ) );
}
for ( i = (int)curStyle->size() - 2 ; i >= 0; --i ) {
item = (*curStyle)[ i ];
mar = QMAX( 0, item->margin( QStyleSheetItem::MarginFirstLine ) );
m = QMAX( m, mar );
}
stylesPar->uflm =m - stylesPar->firstLineMargin();
// do the bogus line "spacing", which really is just an extra margin
item = mainStyle;
for ( i = (int)curStyle->size() - 1 ; i >= 0; --i ) {
item = (*curStyle)[ i ];
if ( item->lineSpacing() != QStyleSheetItem::Undefined ) {
stylesPar->ulinespacing = item->lineSpacing();
if ( formatCollection() &&
stylesPar->ulinespacing < formatCollection()->defaultFormat()->height() )
stylesPar->ulinespacing += formatCollection()->defaultFormat()->height();
break;
}
}
stylesPar = stylesPar->next();
prevStyle = curStyle;
curStyle = nextStyle;
nextStyle = styles.next();
}
}
void QTextDocument::setText( const QString &text, const QString &context )
{
focusIndicator.parag = 0;
selections.clear();
if ( txtFormat == Qt::AutoText && QStyleSheet::mightBeRichText( text ) ||
txtFormat == Qt::RichText )
setRichText( text, context );
else
setPlainText( text );
}
QString QTextDocument::plainText() const
{
QString buffer;
QString s;
QTextParagraph *p = fParag;
while ( p ) {
if ( !p->mightHaveCustomItems ) {
s = p->string()->toString();
} else {
for ( int i = 0; i < p->length() - 1; ++i ) {
if ( p->at( i )->isCustom() ) {
if ( p->at( i )->customItem()->isNested() ) {
s += "\n";
QTextTable *t = (QTextTable*)p->at( i )->customItem();
QPtrList<QTextTableCell> cells = t->tableCells();
for ( QTextTableCell *c = cells.first(); c; c = cells.next() )
s += c->richText()->plainText() + "\n";
s += "\n";
}
} else {
s += p->at( i )->c;
}
}
}
s.remove( s.length() - 1, 1 );
if ( p->next() )
s += "\n";
buffer += s;
p = p->next();
}
return buffer;
}
static QString align_to_string( int a )
{
if ( a & Qt::AlignRight )
return " align=\"right\"";
if ( a & Qt::AlignHCenter )
return " align=\"center\"";
if ( a & Qt3::AlignJustify )
return " align=\"justify\"";
return QString::null;
}
static QString direction_to_string( int d )
{
@@ -5152,385 +5175,385 @@ int QTextFormatter::formatVertically( QTextDocument* doc, QTextParagraph* parag
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
QTextFormatterBreakInWords::QTextFormatterBreakInWords()
{
}
#define SPACE(s) doc?(s>0?s:0):s
int QTextFormatterBreakInWords::format( QTextDocument *doc,QTextParagraph *parag,
int start, const QMap<int, QTextLineStart*> & )
{
QTextStringChar *c = 0;
QTextStringChar *firstChar = 0;
int left = doc ? parag->leftMargin() + doc->leftMargin() : 0;
int x = left + ( doc ? parag->firstLineMargin() : 0 );
int dw = parag->documentVisibleWidth() - ( doc ? doc->rightMargin() : 0 );
int y = parag->prev() ? QMAX(parag->prev()->bottomMargin(),parag->topMargin()) / 2: 0;
int h = y;
int len = parag->length();
if ( doc )
x = doc->flow()->adjustLMargin( y + parag->rect().y(), parag->rect().height(), x, 4 );
int rm = parag->rightMargin();
int w = dw - ( doc ? doc->flow()->adjustRMargin( y + parag->rect().y(), parag->rect().height(), rm, 4 ) : 0 );
bool fullWidth = TRUE;
int minw = 0;
int wused = 0;
bool wrapEnabled = isWrapEnabled( parag );
start = 0; //######### what is the point with start?! (Matthias)
if ( start == 0 )
c = &parag->string()->at( 0 );
int i = start;
QTextLineStart *lineStart = new QTextLineStart( y, y, 0 );
insertLineStart( parag, 0, lineStart );
QPainter *painter = QTextFormat::painter();
int col = 0;
int ww = 0;
QChar lastChr;
for ( ; i < len; ++i, ++col ) {
if ( c )
lastChr = c->c;
c = &parag->string()->at( i );
c->rightToLeft = FALSE;
// ### the lines below should not be needed
if ( painter )
c->format()->setPainter( painter );
if ( i > 0 ) {
c->lineStart = 0;
} else {
c->lineStart = 1;
firstChar = c;
}
if ( c->c.unicode() >= 32 || c->isCustom() ) {
ww = parag->string()->width( i );
} else if ( c->c == '\t' ) {
int nx = parag->nextTab( i, x - left ) + left;
if ( nx < x )
ww = w - x;
else
ww = nx - x;
} else {
ww = c->format()->width( ' ' );
}
if ( c->isCustom() && c->customItem()->ownLine() ) {
x = doc ? doc->flow()->adjustLMargin( y + parag->rect().y(), parag->rect().height(), left, 4 ) : left;
w = dw - ( doc ? doc->flow()->adjustRMargin( y + parag->rect().y(), parag->rect().height(), rm, 4 ) : 0 );
c->customItem()->resize( w - x );
w = dw;
y += h;
h = c->height();
lineStart = new QTextLineStart( y, h, h );
insertLineStart( parag, i, lineStart );
c->lineStart = 1;
firstChar = c;
x = 0xffffff;
continue;
}
if ( wrapEnabled &&
( wrapAtColumn() == -1 && x + ww > w ||
wrapAtColumn() != -1 && col >= wrapAtColumn() ) ) {
x = doc ? parag->document()->flow()->adjustLMargin( y + parag->rect().y(), parag->rect().height(), left, 4 ) : left;
w = dw;
y += h;
h = c->height();
lineStart = formatLine( parag, parag->string(), lineStart, firstChar, SPACE(c-1) );
lineStart->y = y;
insertLineStart( parag, i, lineStart );
lineStart->baseLine = c->ascent();
lineStart->h = c->height();
c->lineStart = 1;
firstChar = c;
col = 0;
if ( wrapAtColumn() != -1 )
minw = QMAX( minw, w );
} else if ( lineStart ) {
lineStart->baseLine = QMAX( lineStart->baseLine, c->ascent() );
h = QMAX( h, c->height() );
lineStart->h = h;
}
c->x = x;
x += ww;
wused = QMAX( wused, x );
}
int m = parag->bottomMargin();
if ( !parag->next() )
m = 0;
else
m = QMAX(m, parag->next()->topMargin() ) / 2;
parag->setFullWidth( fullWidth );
y += h + m;
if ( doc )
minw += doc->rightMargin();
if ( !wrapEnabled )
minw = QMAX(minw, wused);
thisminw = minw;
thiswused = wused;
return y;
}
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
QTextFormatterBreakWords::QTextFormatterBreakWords()
{
}
#define DO_FLOW( lineStart ) do{ if ( doc && doc->isPageBreakEnabled() ) { \
int yflow = lineStart->y + parag->rect().y();\
int shift = doc->flow()->adjustFlow( yflow, dw, lineStart->h ); \
lineStart->y += shift;\
y += shift;\
}}while(FALSE)
int QTextFormatterBreakWords::format( QTextDocument *doc, QTextParagraph *parag,
int start, const QMap<int, QTextLineStart*> & )
{
QTextStringChar *c = 0;
QTextStringChar *firstChar = 0;
QTextString *string = parag->string();
int left = doc ? parag->leftMargin() + doc->leftMargin() : 0;
int x = left + ( doc ? parag->firstLineMargin() : 0 );
int y = parag->prev() ? QMAX(parag->prev()->bottomMargin(),parag->topMargin()) / 2: 0;
int h = y;
int len = parag->length();
if ( doc )
x = doc->flow()->adjustLMargin( y + parag->rect().y(), parag->rect().height(), x, 0 );
int dw = parag->documentVisibleWidth() - ( doc ? ( left != x ? 0 : doc->rightMargin() ) : 0 );
int curLeft = x;
int rm = parag->rightMargin();
int rdiff = doc ? doc->flow()->adjustRMargin( y + parag->rect().y(), parag->rect().height(), rm, 0 ) : 0;
int w = dw - rdiff;
bool fullWidth = TRUE;
int marg = left + rdiff;
int minw = 0;
int wused = 0;
int tminw = marg;
int linespacing = doc ? parag->lineSpacing() : 0;
bool wrapEnabled = isWrapEnabled( parag );
start = 0;
if ( start == 0 )
c = &parag->string()->at( 0 );
int i = start;
QTextLineStart *lineStart = new QTextLineStart( y, y, 0 );
insertLineStart( parag, 0, lineStart );
int lastBreak = -1;
int tmpBaseLine = 0, tmph = 0;
bool lastWasNonInlineCustom = FALSE;
int align = parag->alignment();
if ( align == Qt3::AlignAuto && doc && doc->alignment() != Qt3::AlignAuto )
align = doc->alignment();
align &= Qt3::AlignHorizontal_Mask;
QPainter *painter = QTextFormat::painter();
int col = 0;
int ww = 0;
QChar lastChr;
for ( ; i < len; ++i, ++col ) {
if ( c )
lastChr = c->c;
// ### next line should not be needed
- if ( painter )
+ if ( c && painter )
c->format()->setPainter( painter );
c = &string->at( i );
c->rightToLeft = FALSE;
if ( i > 0 && (x > curLeft || ww == 0) || lastWasNonInlineCustom ) {
c->lineStart = 0;
} else {
c->lineStart = 1;
firstChar = c;
}
if ( c->isCustom() && c->customItem()->placement() != QTextCustomItem::PlaceInline )
lastWasNonInlineCustom = TRUE;
else
lastWasNonInlineCustom = FALSE;
if ( c->c.unicode() >= 32 || c->isCustom() ) {
ww = string->width( i );
} else if ( c->c == '\t' ) {
int nx = parag->nextTab( i, x - left ) + left;
if ( nx < x )
ww = w - x;
else
ww = nx - x;
} else {
ww = c->format()->width( ' ' );
}
// last character ("invisible" space) has no width
if ( i == len - 1 )
ww = 0;
QTextCustomItem* ci = c->customItem();
if ( c->isCustom() && ci->ownLine() ) {
x = doc ? doc->flow()->adjustLMargin( y + parag->rect().y(), parag->rect().height(), left, 4 ) : left;
w = dw - ( doc ? doc->flow()->adjustRMargin( y + parag->rect().y(), parag->rect().height(), rm, 4 ) : 0 );
QTextLineStart *lineStart2 = formatLine( parag, string, lineStart, firstChar, c-1, align, SPACE(w - x) );
ci->resize( w - x);
if ( ci->width < w - x ) {
if ( align & Qt::AlignHCenter )
x = ( w - ci->width ) / 2;
else if ( align & Qt::AlignRight ) {
x = w - ci->width;
}
}
c->x = x;
curLeft = x;
if ( i == 0 || !isBreakable( string, i - 1 ) || string->at( i - 1 ).lineStart == 0 ) {
y += QMAX( h, QMAX( tmph, linespacing ) );
tmph = c->height();
h = tmph;
lineStart = lineStart2;
lineStart->y = y;
insertLineStart( parag, i, lineStart );
c->lineStart = 1;
firstChar = c;
} else {
tmph = c->height();
h = tmph;
delete lineStart2;
}
lineStart->h = h;
lineStart->baseLine = h;
tmpBaseLine = lineStart->baseLine;
lastBreak = -2;
x = 0xffffff;
minw = QMAX( minw, tminw );
int tw = ci->minimumWidth() + ( doc ? doc->leftMargin() : 0 );
if ( tw < QWIDGETSIZE_MAX )
tminw = tw;
else
tminw = marg;
wused = QMAX( wused, ci->width );
continue;
} else if ( c->isCustom() && ci->placement() != QTextCustomItem::PlaceInline ) {
int tw = ci->minimumWidth();
if ( tw < QWIDGETSIZE_MAX )
minw = QMAX( minw, tw );
}
bool lastWasOwnLineCustomItem = lastBreak == -2;
bool hadBreakableChar = lastBreak != -1;
bool lastWasHardBreak = lastChr == QChar_linesep;
// we break if
// 1. the last character was a hard break (QChar_linesep) or
// 2. the last charater was a own-line custom item (eg. table or ruler) or
// 3. wrapping was enabled, it was not a space and following
// condition is true: We either had a breakable character
// previously or we ar allowed to break in words and - either
// we break at w pixels and the current char would exceed that
// or - we break at a column and the current character would
// exceed that.
if ( lastWasHardBreak || lastWasOwnLineCustomItem ||
( wrapEnabled &&
( (!c->c.isSpace() && (hadBreakableChar || allowBreakInWords()) &&
( (wrapAtColumn() == -1 && x + ww > w) ||
(wrapAtColumn() != -1 && col >= wrapAtColumn()) ) ) )
)
) {
if ( wrapAtColumn() != -1 )
minw = QMAX( minw, x + ww );
// if a break was forced (no breakable char, hard break or own line custom item), break immediately....
if ( !hadBreakableChar || lastWasHardBreak || lastWasOwnLineCustomItem ) {
if ( lineStart ) {
lineStart->baseLine = QMAX( lineStart->baseLine, tmpBaseLine );
h = QMAX( h, tmph );
lineStart->h = h;
DO_FLOW( lineStart );
}
lineStart = formatLine( parag, string, lineStart, firstChar, c-1, align, SPACE(w - x) );
x = doc ? doc->flow()->adjustLMargin( y + parag->rect().y(), parag->rect().height(), left, 4 ) : left;
w = dw - ( doc ? doc->flow()->adjustRMargin( y + parag->rect().y(), parag->rect().height(), rm, 4 ) : 0 );
if ( !doc && c->c == '\t' ) { // qt_format_text tab handling
int nx = parag->nextTab( i, x - left ) + left;
if ( nx < x )
ww = w - x;
else
ww = nx - x;
}
curLeft = x;
y += QMAX( h, linespacing );
tmph = c->height();
h = 0;
lineStart->y = y;
insertLineStart( parag, i, lineStart );
lineStart->baseLine = c->ascent();
lineStart->h = c->height();
c->lineStart = 1;
firstChar = c;
tmpBaseLine = lineStart->baseLine;
lastBreak = -1;
col = 0;
} else { // ... otherwise if we had a breakable char, break there
DO_FLOW( lineStart );
i = lastBreak;
lineStart = formatLine( parag, string, lineStart, firstChar, parag->at( lastBreak ),align, SPACE(w - string->at( i ).x) );
x = doc ? doc->flow()->adjustLMargin( y + parag->rect().y(), parag->rect().height(), left, 4 ) : left;
w = dw - ( doc ? doc->flow()->adjustRMargin( y + parag->rect().y(), parag->rect().height(), rm, 4 ) : 0 );
if ( !doc && c->c == '\t' ) { // qt_format_text tab handling
int nx = parag->nextTab( i, x - left ) + left;
if ( nx < x )
ww = w - x;
else
ww = nx - x;
}
curLeft = x;
y += QMAX( h, linespacing );
tmph = c->height();
h = tmph;
lineStart->y = y;
insertLineStart( parag, i + 1, lineStart );
lineStart->baseLine = c->ascent();
lineStart->h = c->height();
c->lineStart = 1;
firstChar = c;
tmpBaseLine = lineStart->baseLine;
lastBreak = -1;
col = 0;
tminw = marg;
continue;
}
} else if ( lineStart && isBreakable( string, i ) ) {
if ( len <= 2 || i < len - 1 ) {
tmpBaseLine = QMAX( tmpBaseLine, c->ascent() );
tmph = QMAX( tmph, c->height() );
}
minw = QMAX( minw, tminw );
tminw = marg + ww;
lineStart->baseLine = QMAX( lineStart->baseLine, tmpBaseLine );
h = QMAX( h, tmph );
lineStart->h = h;
if ( i < len - 2 || c->c != ' ' )
lastBreak = i;
} else {
tminw += ww;
int belowBaseLine = QMAX( tmph - tmpBaseLine, c->height()- c->ascent() );
tmpBaseLine = QMAX( tmpBaseLine, c->ascent() );
tmph = tmpBaseLine + belowBaseLine;
}
c->x = x;
x += ww;
wused = QMAX( wused, x );
}
// ### hack. The last char in the paragraph is always invisible,
// ### and somehow sometimes has a wrong format. It changes
// ### between // layouting and printing. This corrects some
// ### layouting errors in BiDi mode due to this.
if ( len > 1 && !c->isAnchor() ) {
c->format()->removeRef();
diff --git a/noncore/settings/networksettings2/opietooth2/OTSDPAttribute.cpp b/noncore/settings/networksettings2/opietooth2/OTSDPAttribute.cpp
index 9069c09..3fd877f 100644
--- a/noncore/settings/networksettings2/opietooth2/OTSDPAttribute.cpp
+++ b/noncore/settings/networksettings2/opietooth2/OTSDPAttribute.cpp
@@ -106,224 +106,227 @@ OTSDPAttribute::OTSDPAttribute( sdp_data_t * attrib ) {
case SDP_TEXT_STR_UNSPEC :
case SDP_TEXT_STR8 :
case SDP_TEXT_STR16 :
case SDP_TEXT_STR32 :
setString( QString(attrib->val.str) );
break;
case SDP_URL_STR_UNSPEC :
case SDP_URL_STR8 :
case SDP_URL_STR16 :
case SDP_URL_STR32 :
setURL( QString(attrib->val.str) );
break;
case SDP_BOOL:
setBool( attrib->val.int8 != 0);
break;
case SDP_SEQ_UNSPEC :
case SDP_SEQ8 :
case SDP_SEQ16 :
case SDP_SEQ32 :
case SDP_ALT_UNSPEC :
case SDP_ALT8 :
case SDP_ALT16 :
case SDP_ALT32 :
{ AttributeVector subAttribs;
OTSDPAttribute * Attr;
sdp_data_t* subAttrib = attrib->val.dataseq;
for (; subAttrib; subAttrib = subAttrib->next) {
Attr = new OTSDPAttribute(subAttrib);
subAttribs.resize( subAttribs.size() + 1 );
subAttribs.insert( subAttribs.size() - 1, Attr );
}
if( attrib->dtd == SDP_ALT_UNSPEC ||
attrib->dtd == SDP_ALT8 ||
attrib->dtd == SDP_ALT16 ||
attrib->dtd == SDP_ALT32 ) {
setAlternative(subAttribs);
} else {
setSequence(subAttribs);
}
break;
}
} // end case
}
QString OTSDPAttribute::toString( void ) {
QString S;
switch( type ) {
case INVALID :
S = "invalid";
break;
case NIL :
S = "NIL";
break;
case UINT :
S = Value.uintVal->toString();
break;
case INT :
S = Value.intVal->toString();
break;
case UUID :
S = Value.uuidVal->toString();
break;
case BOOLEAN :
S = (Value.boolVal) ? "true" : "false";
break;
case STRING :
S = *(Value.stringVal);
break;
case URL :
S = *(Value.stringVal);
break;
case SEQUENCE :
S.sprintf( "Sequence(%d)", Value.sequenceVal->count() );
break;
case ALTERNATIVE :
S.sprintf( "Alternative(%d)", Value.sequenceVal->count() );
break;
case UNKNOWN :
S = "unknown";
break;
}
return S;
}
void OTSDPAttribute::setNil() {
type = NIL;
}
void OTSDPAttribute::setInt(const OTSDPAttribute::int128_t & val) {
type = INT;
Value.intVal = new int128_t( val );
}
void OTSDPAttribute::setUInt(const uint128_t & val) {
type = UINT;
Value.uintVal = new uint128_t(val);
}
void OTSDPAttribute::setUUID(const OTUUID & val) {
type = UUID;
Value.uuidVal = new OTUUID( val );
}
void OTSDPAttribute::setBool(bool val) {
type = BOOLEAN;
Value.boolVal = val;
}
void OTSDPAttribute::setString( const QString & val) {
type = STRING;
Value.stringVal = new QString( val );
}
void OTSDPAttribute::setURL( const QString & val) {
type = URL;
Value.stringVal = new QString(val);
}
void OTSDPAttribute::setSequence(const AttributeVector& val) {
type = SEQUENCE;
Value.sequenceVal = new AttributeVector();
Value.sequenceVal->setAutoDelete( TRUE );
*Value.sequenceVal = val;
}
void OTSDPAttribute::setAlternative(const AttributeVector& val) {
type = ALTERNATIVE;
Value.sequenceVal = new AttributeVector();
Value.sequenceVal->setAutoDelete( TRUE );
*Value.sequenceVal = val;
}
QString OTSDPAttribute::getString() {
assert(type == STRING);
return *Value.stringVal;
}
QString OTSDPAttribute::getURL() {
assert(type == URL);
return *Value.stringVal;
}
const OTSDPAttribute::int128_t & OTSDPAttribute::getInt() {
assert(type == INT);
return *Value.intVal;
}
const OTSDPAttribute::uint128_t & OTSDPAttribute::getUInt() {
assert(type == UINT);
return *Value.uintVal;
}
const OTUUID & OTSDPAttribute::getUUID() {
assert(type == UUID);
return *Value.uuidVal;
}
bool OTSDPAttribute::getBool() {
assert(type == BOOLEAN);
return Value.boolVal;
}
AttributeVector * OTSDPAttribute::getSequence() {
assert(type == SEQUENCE);
return Value.sequenceVal;
}
AttributeVector * OTSDPAttribute::getAlternative() {
assert(type == ALTERNATIVE);
return Value.sequenceVal;
}
UUIDVector OTSDPAttribute::getAllUUIDs() {
UUIDVector uuids;
if (getType() == UUID) {
uuids.resize( uuids.size()+1 );
uuids[uuids.size()-1] = getUUID();
} else {
AttributeVector * subAttributes = 0 ;
if (getType() == SEQUENCE) {
subAttributes = getSequence();
} else if (getType() == ALTERNATIVE) {
subAttributes = getAlternative();
}
+ if (!subAttributes)
+ return 0;
+
int os;
for( unsigned int i = 0; i < subAttributes->count(); i++ ) {
UUIDVector subUUIDs = (*subAttributes)[i]->getAllUUIDs();
os = uuids.size();
uuids.resize( uuids.size()+subUUIDs.count() );
for( unsigned int k = 0; k < subUUIDs.count(); k++ ) {
uuids[os + k] = subUUIDs[k];
}
}
}
return uuids;
}
static char * Attr2String[] = {
"Invalid",
"Nil",
"UInt",
"int",
"UUID",
"Boolean",
"String",
"Sequence",
"Alternative",
"URL",
"Unknown"
};
const char * OTSDPAttribute::getTypeString() {
return Attr2String[type];
}
diff --git a/noncore/settings/packagemanager/oipkgconfigdlg.cpp b/noncore/settings/packagemanager/oipkgconfigdlg.cpp
index d014378..78a18f7 100644
--- a/noncore/settings/packagemanager/oipkgconfigdlg.cpp
+++ b/noncore/settings/packagemanager/oipkgconfigdlg.cpp
@@ -247,399 +247,401 @@ void OIpkgConfigDlg::initDestinationWidget()
m_destDeleteBtn = new QPushButton( Opie::Core::OResource::loadPixmap( "trash", Opie::Core::OResource::SmallIcon ),
tr( "Delete" ), container );
m_destDeleteBtn->setMinimumHeight( AppLnk::smallIconSize()+4 );
m_destDeleteBtn->setEnabled( false );
QWhatsThis::add( m_destDeleteBtn, tr( "Tap here to delete the entry selected above." ) );
connect( m_destDeleteBtn, SIGNAL(clicked()), this, SLOT(slotDestDelete()) );
layout->addWidget( m_destDeleteBtn, 1, 2 );
}
void OIpkgConfigDlg::initProxyWidget()
{
m_proxyWidget = new QWidget( this );
// Initialize UI
QVBoxLayout *vb = new QVBoxLayout( m_proxyWidget );
QScrollView *sv = new QScrollView( m_proxyWidget );
vb->addWidget( sv, 0, 0 );
sv->setResizePolicy( QScrollView::AutoOneFit );
sv->setFrameStyle( QFrame::NoFrame );
QWidget *container = new QWidget( sv->viewport() );
sv->addChild( container );
QGridLayout *layout = new QGridLayout( container, 4, 2, 2, 4 );
// HTTP proxy server configuration
QGroupBox *grpbox = new QGroupBox( 0, Qt::Vertical, tr( "HTTP Proxy" ), container );
grpbox->layout()->setSpacing( 2 );
grpbox->layout()->setMargin( 4 );
layout->addMultiCellWidget( grpbox, 0, 0, 0, 1 );
QVBoxLayout *grplayout = new QVBoxLayout( grpbox->layout() );
m_proxyHttpServer = new QLineEdit( grpbox );
QWhatsThis::add( m_proxyHttpServer, tr( "Enter the URL address of the HTTP proxy server here." ) );
grplayout->addWidget( m_proxyHttpServer );
m_proxyHttpActive = new QCheckBox( tr( "Enabled" ), grpbox );
QWhatsThis::add( m_proxyHttpActive, tr( "Tap here to enable or disable the HTTP proxy server." ) );
grplayout->addWidget( m_proxyHttpActive );
// FTP proxy server configuration
grpbox = new QGroupBox( 0, Qt::Vertical, tr( "FTP Proxy" ), container );
grpbox->layout()->setSpacing( 2 );
grpbox->layout()->setMargin( 4 );
layout->addMultiCellWidget( grpbox, 1, 1, 0, 1 );
grplayout = new QVBoxLayout( grpbox->layout() );
m_proxyFtpServer = new QLineEdit( grpbox );
QWhatsThis::add( m_proxyFtpServer, tr( "Enter the URL address of the FTP proxy server here." ) );
grplayout->addWidget( m_proxyFtpServer );
m_proxyFtpActive = new QCheckBox( tr( "Enabled" ), grpbox );
QWhatsThis::add( m_proxyFtpActive, tr( "Tap here to enable or disable the FTP proxy server." ) );
grplayout->addWidget( m_proxyFtpActive );
// Proxy server username and password configuration
QLabel *label = new QLabel( tr( "Username:" ), container );
QWhatsThis::add( label, tr( "Enter the username for the proxy servers here." ) );
layout->addWidget( label, 2, 0 );
m_proxyUsername = new QLineEdit( container );
QWhatsThis::add( m_proxyUsername, tr( "Enter the username for the proxy servers here." ) );
layout->addWidget( m_proxyUsername, 2, 1 );
label = new QLabel( tr( "Password:" ), container );
QWhatsThis::add( label, tr( "Enter the password for the proxy servers here." ) );
layout->addWidget( label, 3, 0 );
m_proxyPassword = new QLineEdit( container );
QWhatsThis::add( m_proxyPassword, tr( "Enter the password for the proxy servers here." ) );
layout->addWidget( m_proxyPassword, 3, 1 );
}
void OIpkgConfigDlg::initOptionsWidget()
{
m_optionsWidget = new QWidget( this );
// Initialize UI
QVBoxLayout *vb = new QVBoxLayout( m_optionsWidget );
QScrollView *sv = new QScrollView( m_optionsWidget );
vb->addWidget( sv, 0, 0 );
sv->setResizePolicy( QScrollView::AutoOneFit );
sv->setFrameStyle( QFrame::NoFrame );
QWidget *container = new QWidget( sv->viewport() );
sv->addChild( container );
QGridLayout *layout = new QGridLayout( container, 8, 2, 2, 4 );
m_optForceDepends = new QCheckBox( tr( "Force Depends" ), container );
QWhatsThis::add( m_optForceDepends, tr( "Tap here to enable or disable the '-force-depends' option for Ipkg." ) );
layout->addMultiCellWidget( m_optForceDepends, 0, 0, 0, 1 );
m_optForceReinstall = new QCheckBox( tr( "Force Reinstall" ), container );
QWhatsThis::add( m_optForceReinstall, tr( "Tap here to enable or disable the '-force-reinstall' option for Ipkg." ) );
layout->addMultiCellWidget( m_optForceReinstall, 1, 1, 0, 1 );
m_optForceRemove = new QCheckBox( tr( "Force Remove" ), container );
QWhatsThis::add( m_optForceRemove, tr( "Tap here to enable or disable the '-force-removal-of-dependent-packages' option for Ipkg." ) );
layout->addMultiCellWidget( m_optForceRemove, 2, 2, 0, 1 );
m_optForceOverwrite = new QCheckBox( tr( "Force Overwrite" ), container );
QWhatsThis::add( m_optForceOverwrite, tr( "Tap here to enable or disable the '-force-overwrite' option for Ipkg." ) );
layout->addMultiCellWidget( m_optForceOverwrite, 3, 3, 0, 1 );
m_optForceRecursive = new QCheckBox( tr( "Force Recursive" ), container );
QWhatsThis::add( m_optForceRecursive, tr( "Tap here to enable or disable the '-recursive' option for Ipkg." ) );
layout->addMultiCellWidget( m_optForceRecursive, 4, 4, 0, 1 );
m_optVerboseWget = new QCheckBox( tr( "Verbose fetch" ), container );
QWhatsThis::add( m_optVerboseWget, tr( "Tap here to enable or disable the '-verbose_wget' option for Ipkg." ) );
layout->addMultiCellWidget( m_optVerboseWget, 5, 5, 0, 1 );
QLabel *l = new QLabel( tr( "Information level:" ), container );
QWhatsThis::add( l, tr( "Select information level for Ipkg." ) );
layout->addMultiCellWidget( l, 6, 6, 0, 1 );
m_optVerboseIpkg = new QComboBox( container );
QWhatsThis::add( m_optVerboseIpkg, tr( "Select information level for Ipkg." ) );
m_optVerboseIpkg->insertItem( tr( "Errors only" ) );
m_optVerboseIpkg->insertItem( tr( "Normal messages" ) );
m_optVerboseIpkg->insertItem( tr( "Informative messages" ) );
m_optVerboseIpkg->insertItem( tr( "Troubleshooting output" ) );
layout->addMultiCellWidget( m_optVerboseIpkg, 7, 7, 0, 1 );
l = new QLabel( tr( "Package source lists directory:" ), container );
QWhatsThis::add( l, tr( "Enter the directory where package source feed information is stored." ) );
layout->addMultiCellWidget( l, 8, 8, 0, 1 );
m_optSourceLists = new QLineEdit( container );
QWhatsThis::add( m_optSourceLists, tr( "Enter the directory where package source feed information is stored." ) );
layout->addWidget( m_optSourceLists, 9, 0 );
QPushButton *btn = new QPushButton( Opie::Core::OResource::loadPixmap( "folder", Opie::Core::OResource::SmallIcon ),
QString::null, container );
btn->setMinimumHeight( AppLnk::smallIconSize()+4 );
btn->setMaximumWidth( btn->height() );
QWhatsThis::add( btn, tr( "Tap here to select the directory where package source feed information is stored." ) );
connect( btn, SIGNAL(clicked()), this, SLOT(slotOptSelectSourceListsPath()) );
layout->addWidget( btn, 9, 1 );
layout->addItem( new QSpacerItem( 1, 1, QSizePolicy::Minimum, QSizePolicy::Expanding ) );
}
void OIpkgConfigDlg::initData()
{
// Read ipkg configuration (server/destination/proxy) information
if ( m_ipkg && !m_installOptions )
{
m_configs = m_ipkg->configItems();
if ( m_configs )
{
for ( OConfItemListIterator configIt( *m_configs ); configIt.current(); ++configIt )
{
OConfItem *config = configIt.current();
// Add configuration item to the appropriate dialog controls
if ( config )
{
switch ( config->type() )
{
case OConfItem::Source : m_serverList->insertItem( config->name() ); break;
case OConfItem::Destination : m_destList->insertItem( config->name() ); break;
case OConfItem::Option :
{
if ( config->name() == "http_proxy" )
{
m_proxyHttpServer->setText( config->value() );
m_proxyHttpActive->setChecked( config->active() );
}
else if ( config->name() == "ftp_proxy" )
{
m_proxyFtpServer->setText( config->value() );
m_proxyFtpActive->setChecked( config->active() );
}
else if ( config->name() == "proxy_username" )
{
m_proxyUsername->setText( config->value() );
}
else if ( config->name() == "proxy_password" )
{
m_proxyPassword->setText( config->value() );
}
}
break;
case OConfItem::Other :
{
if ( config->name() == "lists_dir" )
m_optSourceLists->setText( config->value() );
else // TODO - use proper libipkg define
m_optSourceLists->setText( "/usr/lib/ipkg/lists" );
}
break;
default : break;
};
}
}
}
}
// Get Ipkg execution options
- int options = m_ipkg->ipkgExecOptions();
+ int options = 0;
+ if ( m_ipkg )
+ options = m_ipkg->ipkgExecOptions();
if ( options & FORCE_DEPENDS )
m_optForceDepends->setChecked( true );
if ( options & FORCE_REINSTALL )
m_optForceReinstall->setChecked( true );
if ( options & FORCE_REMOVE )
m_optForceRemove->setChecked( true );
if ( options & FORCE_OVERWRITE )
m_optForceOverwrite->setChecked( true );
if ( options & FORCE_RECURSIVE )
m_optForceRecursive->setChecked( true );
if ( options & FORCE_VERBOSE_WGET )
m_optVerboseWget->setChecked( true );
- m_optVerboseIpkg->setCurrentItem( m_ipkg->ipkgExecVerbosity() );
+ m_optVerboseIpkg->setCurrentItem( ( m_ipkg ? m_ipkg->ipkgExecVerbosity() : 0 ) );
}
void OIpkgConfigDlg::slotServerSelected( int index )
{
m_serverCurrent = index;
// Enable Edit and Delete buttons
m_serverEditBtn->setEnabled( true );
m_serverDeleteBtn->setEnabled( true );
}
void OIpkgConfigDlg::slotServerNew()
{
OConfItem *server = new OConfItem( OConfItem::Source );
OIpkgServerDlg dlg( server, this );
if ( QPEApplication::execDialog( &dlg ) == QDialog::Accepted )
{
// Add to configuration option list
m_configs->append( server );
m_configs->sort();
// Add to server list
m_serverList->insertItem( server->name() );
m_serverList->setCurrentItem( m_serverList->count() );
}
else
delete server;
}
void OIpkgConfigDlg::slotServerEdit()
{
// Find selected server in list
OConfItem *server = m_ipkg->findConfItem( OConfItem::Source, m_serverList->currentText() );
// Edit server
if ( server )
{
QString origName = server->name();
OIpkgServerDlg dlg( server, this );
if ( QPEApplication::execDialog( &dlg ) == QDialog::Accepted )
{
// Check to see if name has changed, if so update the server list
if ( server->name() != origName )
m_serverList->changeItem( server->name(), m_serverCurrent );
}
}
}
void OIpkgConfigDlg::slotServerDelete()
{
// Find selected server in list
OConfItem *server = m_ipkg->findConfItem( OConfItem::Source, m_serverList->currentText() );
// Delete server
if ( server )
{
m_configs->removeRef( server );
m_serverList->removeItem( m_serverCurrent );
}
}
void OIpkgConfigDlg::slotDestSelected( int index )
{
m_destCurrent = index;
// Enable Edit and Delete buttons
m_destEditBtn->setEnabled( true );
m_destDeleteBtn->setEnabled( true );
}
void OIpkgConfigDlg::slotDestNew()
{
OConfItem *dest = new OConfItem( OConfItem::Destination );
OIpkgDestDlg dlg( dest, this );
if ( QPEApplication::execDialog( &dlg ) == QDialog::Accepted )
{
// Add to configuration option list
m_configs->append( dest );
m_configs->sort();
// Add to destination list
m_destList->insertItem( dest->name() );
m_destList->setCurrentItem( m_destList->count() );
}
else
delete dest;
}
void OIpkgConfigDlg::slotDestEdit()
{
// Find selected destination in list
OConfItem *dest = m_ipkg->findConfItem( OConfItem::Destination, m_destList->currentText() );
// Edit destination
if ( dest )
{
QString origName = dest->name();
OIpkgDestDlg dlg( dest, this );
if ( QPEApplication::execDialog( &dlg ) == QDialog::Accepted )
{
// Check to see if name has changed, if so update the dest list
if ( dest->name() != origName )
m_destList->changeItem( dest->name(), m_destCurrent );
}
}
}
void OIpkgConfigDlg::slotDestDelete()
{
// Find selected destination in list
OConfItem *destination = m_ipkg->findConfItem( OConfItem::Destination, m_destList->currentText() );
// Delete destination
if ( destination )
{
m_configs->removeRef( destination );
m_destList->removeItem( m_destCurrent );
}
}
void OIpkgConfigDlg::slotOptSelectSourceListsPath()
{
QString path = Opie::Ui::OFileDialog::getDirectory( 0, m_optSourceLists->text() );
if ( path.at( path.length() - 1 ) == '/' )
path.truncate( path.length() - 1 );
if ( !path.isNull() )
m_optSourceLists->setText( path );
}
OIpkgServerDlg::OIpkgServerDlg( OConfItem *server, QWidget *parent )
: QDialog( parent, QString::null, true, WStyle_ContextHelp )
, m_server( server )
{
setCaption( tr( "Edit Server" ) );
// Initialize UI
QVBoxLayout *layout = new QVBoxLayout( this, 2, 4 );
m_active = new QCheckBox( tr( "Active" ), this );
QWhatsThis::add( m_active, tr( "Tap here to indicate whether this entry is active or not." ) );
layout->addWidget( m_active );
layout->addStretch();
QLabel *label = new QLabel( tr( "Name:" ), this );
QWhatsThis::add( label, tr( "Enter the name of this entry here." ) );
layout->addWidget( label );
m_name = new QLineEdit( this );
QWhatsThis::add( m_name, tr( "Enter the name of this entry here." ) );
layout->addWidget( m_name );
layout->addStretch();
label = new QLabel( tr( "Address:" ), this );
QWhatsThis::add( label, tr( "Enter the URL address of this entry here." ) );
layout->addWidget( label );
m_location = new QLineEdit( this );
QWhatsThis::add( m_location, tr( "Enter the URL address of this entry here." ) );
layout->addWidget( m_location );
layout->addStretch();
m_compressed = new QCheckBox( tr( "Compressed server feed" ), this );
QWhatsThis::add( m_compressed, tr( "Tap here to indicate whether the server support compressed archives or not." ) );
layout->addWidget( m_compressed );
// Populate initial information
if ( m_server )
{
m_name->setText( m_server->name() );
m_location->setText( m_server->value() );
m_compressed->setChecked( m_server->features().contains( "Compressed" ) );
m_active->setChecked( m_server->active() );
}
}
void OIpkgServerDlg::accept()
{
// Save information entered
QString name = m_name->text();
name.replace( QRegExp( " " ), "_" );
m_server->setName( name );
m_server->setValue( m_location->text() );
m_compressed->isChecked() ? m_server->setFeatures( "Compressed" )
: m_server->setFeatures( QString::null );
m_server->setActive( m_active->isChecked() );
QDialog::accept();
}