summaryrefslogtreecommitdiffstats
path: root/ktnef/gui
diff options
context:
space:
mode:
Diffstat (limited to 'ktnef/gui')
-rw-r--r--ktnef/gui/Makefile.am26
-rw-r--r--ktnef/gui/attachpropertydialog.cpp187
-rw-r--r--ktnef/gui/attachpropertydialog.h51
-rw-r--r--ktnef/gui/attachpropertydialogbase.ui281
-rw-r--r--ktnef/gui/ktnef.desktop109
-rw-r--r--ktnef/gui/ktnefmain.cpp409
-rw-r--r--ktnef/gui/ktnefmain.h81
-rw-r--r--ktnef/gui/ktnefui.rc36
-rw-r--r--ktnef/gui/ktnefview.cpp136
-rw-r--r--ktnef/gui/ktnefview.h52
-rw-r--r--ktnef/gui/main.cpp57
-rw-r--r--ktnef/gui/messagepropertydialog.cpp46
-rw-r--r--ktnef/gui/messagepropertydialog.h40
-rw-r--r--ktnef/gui/metafuncs.h90
-rw-r--r--ktnef/gui/ms-tnef.desktop62
-rw-r--r--ktnef/gui/pics/Makefile.am4
-rw-r--r--ktnef/gui/pics/hi22-action-ktnef_extract_all_to.pngbin0 -> 1110 bytes
-rw-r--r--ktnef/gui/pics/hi22-action-ktnef_extract_to.pngbin0 -> 1207 bytes
-rw-r--r--ktnef/gui/pics/hi48-app-ktnef.pngbin0 -> 4799 bytes
-rw-r--r--ktnef/gui/pics/lo16-action-ktnef_extract_all_to.pngbin0 -> 361 bytes
-rw-r--r--ktnef/gui/pics/lo16-action-ktnef_extract_to.pngbin0 -> 419 bytes
-rw-r--r--ktnef/gui/pics/lo16-app-ktnef.pngbin0 -> 465 bytes
-rw-r--r--ktnef/gui/pics/lo32-app-ktnef.pngbin0 -> 737 bytes
-rw-r--r--ktnef/gui/qwmf.cpp1258
-rw-r--r--ktnef/gui/qwmf.h228
-rw-r--r--ktnef/gui/wmfstruct.h107
26 files changed, 3260 insertions, 0 deletions
diff --git a/ktnef/gui/Makefile.am b/ktnef/gui/Makefile.am
new file mode 100644
index 00000000..1a967461
--- /dev/null
+++ b/ktnef/gui/Makefile.am
@@ -0,0 +1,26 @@
+INCLUDES = -I$(top_srcdir)/ktnef $(all_includes)
+
+SUBDIRS = pics
+
+bin_PROGRAMS = ktnef
+
+ktnef_LDFLAGS = $(KDE_RPATH) $(all_libraries)
+ktnef_LDADD = $(LIB_KFILE) $(top_builddir)/ktnef/lib/libktnef.la
+ktnef_SOURCES = ktnefmain.cpp ktnefview.cpp attachpropertydialogbase.ui \
+ attachpropertydialog.cpp messagepropertydialog.cpp \
+ qwmf.cpp main.cpp
+ktnef_METASOURCES = AUTO
+
+noinst_HEADERS = ktnefmain.h ktnefview.h attachpropertydialog.h \
+ qwmf.h wmfstruct.h metafuncs.h
+
+rcdir = $(kde_datadir)/ktnef
+rc_DATA = ktnefui.rc
+
+#messages: rc.cpp
+# $(XGETTEXT) -C -ki18n -x $(includedir)/kde.pot $(ktnef_SOURCES) && mv messages.po ../po/ktnef.pot
+
+xdg_apps_DATA = ktnef.desktop
+
+mime_DATA = ms-tnef.desktop
+mimedir = $(kde_mimedir)/application
diff --git a/ktnef/gui/attachpropertydialog.cpp b/ktnef/gui/attachpropertydialog.cpp
new file mode 100644
index 00000000..8675b6ba
--- /dev/null
+++ b/ktnef/gui/attachpropertydialog.cpp
@@ -0,0 +1,187 @@
+/*
+ attachpropertydialog.cpp
+
+ Copyright (C) 2002 Michael Goffioul <kdeprint@swing.be>
+
+ This file is part of KTNEF, the KDE TNEF support library/program.
+
+ 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.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software Foundation,
+ Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include "attachpropertydialog.h"
+#include <ktnef/ktnefattach.h>
+#include <ktnef/ktnefproperty.h>
+#include <ktnef/ktnefpropertyset.h>
+#include <ktnef/ktnefdefs.h>
+#include "qwmf.h"
+
+#include <qlabel.h>
+#include <klistview.h>
+#include <kmimetype.h>
+#include <kdebug.h>
+#include <klocale.h>
+#include <kmessagebox.h>
+#include <kfiledialog.h>
+#include <qbuffer.h>
+#include <qdatastream.h>
+#include <qpicture.h>
+
+AttachPropertyDialog::AttachPropertyDialog(QWidget *parent, const char *name)
+ : AttachPropertyDialogBase(parent, name, true)
+{
+}
+
+AttachPropertyDialog::~AttachPropertyDialog()
+{
+}
+
+void AttachPropertyDialog::setAttachment(KTNEFAttach *attach)
+{
+ QString s = (attach->fileName().isEmpty() ? attach->name() : attach->fileName());
+ filename_->setText("<b>"+s+"</b>");
+ setCaption(s);
+ display_->setText(attach->displayName());
+ mime_->setText(attach->mimeTag());
+ s.setNum(attach->size());
+ s.append(" bytes");
+ size_->setText(s);
+ KMimeType::Ptr mimetype = KMimeType::mimeType(attach->mimeTag());
+ QPixmap pix = loadRenderingPixmap( attach, colorGroup().background() );
+ if ( !pix.isNull() )
+ icon_->setPixmap( pix );
+ else
+ icon_->setPixmap(mimetype->pixmap(KIcon::Small));
+ description_->setText(mimetype->comment());
+ s.setNum(attach->index());
+ index_->setText(s);
+
+ formatPropertySet( attach, properties_ );
+ m_attach = attach;
+}
+
+void AttachPropertyDialog::saveClicked()
+{
+ saveProperty( properties_, m_attach, this );
+}
+
+void formatProperties( const QMap<int,KTNEFProperty*>& props, QListView *lv, QListViewItem *item, const QString& prefix )
+{
+ for ( QMap<int,KTNEFProperty*>::ConstIterator it=props.begin(); it!=props.end(); ++it )
+ {
+ QListViewItem *newItem = 0;
+ if ( lv )
+ newItem = new QListViewItem( lv, ( *it )->keyString() );
+ else if ( item )
+ newItem = new QListViewItem( item, ( *it )->keyString() );
+ else
+ {
+ kdWarning() << "formatProperties() called with no listview and no item" << endl;
+ return;
+ }
+
+ QVariant value = ( *it )->value();
+ if ( value.type() == QVariant::List )
+ {
+ newItem->setOpen( true );
+ newItem->setText( 0, newItem->text( 0 ) + " [" + QString::number( value.asList().count() ) + "]" );
+ int i = 0;
+ for ( QValueList<QVariant>::ConstIterator lit=value.listBegin(); lit!=value.listEnd(); ++lit, i++ )
+ new QListViewItem( newItem, "[" + QString::number( i ) + "]", KTNEFProperty::formatValue( *lit ) );
+ }
+ else if ( value.type() == QVariant::DateTime )
+ newItem->setText( 1, value.asDateTime().toString() );
+ else
+ {
+ newItem->setText( 1, ( *it )->valueString() );
+ newItem->setText( 2, prefix + "_" + QString::number( it.key() ) );
+ }
+ }
+}
+
+void formatPropertySet( KTNEFPropertySet *pSet, QListView *lv )
+{
+ formatProperties( pSet->properties(), lv, 0, "prop" );
+ QListViewItem *item = new QListViewItem( lv, i18n( "TNEF Attributes" ) );
+ item->setOpen( true );
+ formatProperties( pSet->attributes(), 0, item, "attr" );
+}
+
+void saveProperty( QListView *lv, KTNEFPropertySet *pSet, QWidget *parent )
+{
+ QListViewItem *item = lv->selectedItem();
+ if ( !item )
+ KMessageBox::error( parent, i18n( "Select an item." ) );
+ else if ( item->text( 2 ).isEmpty() )
+ KMessageBox::error( parent, i18n( "The selected item cannot be saved." ) );
+ else
+ {
+ QString tag = item->text( 2 );
+ int key = tag.mid( 5 ).toInt();
+ QVariant prop = ( tag.startsWith( "attr_" ) ? pSet->attribute( key ) : pSet->property( key ) );
+ QString filename = KFileDialog::getSaveFileName( tag, QString::null, parent );
+ if ( !filename.isEmpty() )
+ {
+ QFile f( filename );
+ if ( f.open( IO_WriteOnly ) )
+ {
+ switch ( prop.type() )
+ {
+ case QVariant::ByteArray:
+ f.writeBlock( prop.asByteArray().data(), prop.asByteArray().size() );
+ break;
+ default:
+ {
+ QTextStream t( &f );
+ t << prop.toString();
+ break;
+ }
+ }
+ f.close();
+ }
+ else
+ KMessageBox::error( parent, i18n( "Unable to open file for writing, check file permissions." ) );
+ }
+ }
+}
+
+QPixmap loadRenderingPixmap( KTNEFPropertySet *pSet, const QColor& bgColor )
+{
+ QPixmap pix;
+ QVariant rendData = pSet->attribute( attATTACHRENDDATA ), wmf = pSet->attribute( attATTACHMETAFILE );
+ if ( !rendData.isNull() && !wmf.isNull() )
+ {
+ // Get rendering size
+ QBuffer rendBuffer( rendData.asByteArray() );
+ rendBuffer.open( IO_ReadOnly );
+ QDataStream rendStream( &rendBuffer );
+ rendStream.setByteOrder( QDataStream::LittleEndian );
+ Q_UINT16 type, w, h;
+ rendStream >> type >> w >> w; // read type and skip 4 bytes
+ rendStream >> w >> h;
+ rendBuffer.close();
+
+ if ( type == 1 && w > 0 && h > 0 )
+ {
+ // Load WMF data
+ QWinMetaFile wmfLoader;
+ QBuffer wmfBuffer( wmf.asByteArray() );
+ wmfBuffer.open( IO_ReadOnly );
+ wmfLoader.setBbox( QRect( 0, 0, w, h ) );
+ if ( wmfLoader.load( wmfBuffer ) )
+ {
+ pix.resize( w, h );
+ pix.fill( bgColor );
+ wmfLoader.paint( &pix );
+ }
+ wmfBuffer.close();
+ }
+ }
+ return pix;
+}
diff --git a/ktnef/gui/attachpropertydialog.h b/ktnef/gui/attachpropertydialog.h
new file mode 100644
index 00000000..a731572e
--- /dev/null
+++ b/ktnef/gui/attachpropertydialog.h
@@ -0,0 +1,51 @@
+/*
+ attachpropertydialog.h
+
+ Copyright (C) 2002 Michael Goffioul <kdeprint@swing.be>
+
+ This file is part of KTNEF, the KDE TNEF support library/program.
+
+ 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.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software Foundation,
+ Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef ATTACHPROPERTYDLG_H
+#define ATTACHPROPERTYDLG_H
+
+#include "attachpropertydialogbase.h"
+#include <qmap.h>
+#include <qpixmap.h>
+
+class KTNEFAttach;
+class KTNEFProperty;
+class KTNEFPropertySet;
+class QListView;
+class QListViewItem;
+
+class AttachPropertyDialog : public AttachPropertyDialogBase
+{
+public:
+ AttachPropertyDialog(QWidget *parent = 0, const char *name = 0);
+ ~AttachPropertyDialog();
+
+ void setAttachment(KTNEFAttach *attach);
+
+protected slots:
+ void saveClicked();
+
+private:
+ KTNEFAttach *m_attach;
+};
+
+void formatProperties( const QMap<int,KTNEFProperty*>&, QListView*, QListViewItem*, const QString& = "prop" );
+void formatPropertySet( KTNEFPropertySet*, QListView* );
+void saveProperty( QListView*, KTNEFPropertySet*, QWidget* );
+QPixmap loadRenderingPixmap( KTNEFPropertySet*, const QColor& );
+
+#endif
diff --git a/ktnef/gui/attachpropertydialogbase.ui b/ktnef/gui/attachpropertydialogbase.ui
new file mode 100644
index 00000000..0d68c3ac
--- /dev/null
+++ b/ktnef/gui/attachpropertydialogbase.ui
@@ -0,0 +1,281 @@
+<!DOCTYPE UI><UI version="3.1" stdsetdef="1">
+<class>AttachPropertyDialogBase</class>
+<widget class="QDialog">
+ <property name="name">
+ <cstring>AttachPropertyDialogBase</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>376</width>
+ <height>426</height>
+ </rect>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="margin">
+ <number>11</number>
+ </property>
+ <property name="spacing">
+ <number>6</number>
+ </property>
+ <widget class="QLabel" row="1" column="1" rowspan="1" colspan="2">
+ <property name="name">
+ <cstring>display_</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>3</hsizetype>
+ <vsizetype>1</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ </widget>
+ <widget class="QLabel" row="2" column="1" rowspan="1" colspan="2">
+ <property name="name">
+ <cstring>description_</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>3</hsizetype>
+ <vsizetype>1</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ </widget>
+ <widget class="QLabel" row="3" column="1" rowspan="1" colspan="2">
+ <property name="name">
+ <cstring>mime_</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>3</hsizetype>
+ <vsizetype>1</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ </widget>
+ <widget class="QLabel" row="4" column="1" rowspan="1" colspan="2">
+ <property name="name">
+ <cstring>size_</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>3</hsizetype>
+ <vsizetype>1</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ </widget>
+ <widget class="QLabel" row="5" column="1" rowspan="1" colspan="2">
+ <property name="name">
+ <cstring>index_</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>3</hsizetype>
+ <vsizetype>1</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ </widget>
+ <widget class="Line" row="6" column="0" rowspan="1" colspan="3">
+ <property name="name">
+ <cstring>Line2</cstring>
+ </property>
+ <property name="frameShape">
+ <enum>HLine</enum>
+ </property>
+ <property name="frameShadow">
+ <enum>Sunken</enum>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ </widget>
+ <widget class="QLabel" row="1" column="0">
+ <property name="name">
+ <cstring>displayLabel_</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>1</hsizetype>
+ <vsizetype>1</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>Comment:</string>
+ </property>
+ </widget>
+ <widget class="QLabel" row="2" column="0">
+ <property name="name">
+ <cstring>descriptionLabel_</cstring>
+ </property>
+ <property name="text">
+ <string>Description:</string>
+ </property>
+ </widget>
+ <widget class="QLabel" row="3" column="0">
+ <property name="name">
+ <cstring>mimeLabel_</cstring>
+ </property>
+ <property name="text">
+ <string>Mime type:</string>
+ </property>
+ </widget>
+ <widget class="QLabel" row="4" column="0">
+ <property name="name">
+ <cstring>sizeLabel_</cstring>
+ </property>
+ <property name="text">
+ <string>File size:</string>
+ </property>
+ </widget>
+ <widget class="QLabel" row="5" column="0">
+ <property name="name">
+ <cstring>indexLabel_</cstring>
+ </property>
+ <property name="text">
+ <string>Index:</string>
+ </property>
+ </widget>
+ <widget class="QLabel" row="0" column="0" rowspan="1" colspan="2">
+ <property name="name">
+ <cstring>filename_</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>3</hsizetype>
+ <vsizetype>1</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="textFormat">
+ <enum>RichText</enum>
+ </property>
+ </widget>
+ <widget class="QLabel" row="0" column="2">
+ <property name="name">
+ <cstring>icon_</cstring>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>16</width>
+ <height>16</height>
+ </size>
+ </property>
+ </widget>
+ <widget class="KListView" row="7" column="0" rowspan="1" colspan="3">
+ <column>
+ <property name="text">
+ <string>Name</string>
+ </property>
+ <property name="clickable">
+ <bool>true</bool>
+ </property>
+ <property name="resizable">
+ <bool>true</bool>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>Value</string>
+ </property>
+ <property name="clickable">
+ <bool>true</bool>
+ </property>
+ <property name="resizable">
+ <bool>true</bool>
+ </property>
+ </column>
+ <property name="name">
+ <cstring>properties_</cstring>
+ </property>
+ <property name="allColumnsShowFocus">
+ <bool>true</bool>
+ </property>
+ <property name="resizeMode">
+ <enum>AllColumns</enum>
+ </property>
+ </widget>
+ <widget class="QLayoutWidget" row="8" column="0" rowspan="1" colspan="3">
+ <property name="name">
+ <cstring>layout2</cstring>
+ </property>
+ <hbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <spacer>
+ <property name="name">
+ <cstring>Spacer1</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>150</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ <widget class="QPushButton">
+ <property name="name">
+ <cstring>save_</cstring>
+ </property>
+ <property name="text">
+ <string>&amp;Save</string>
+ </property>
+ </widget>
+ <widget class="QPushButton">
+ <property name="name">
+ <cstring>close_</cstring>
+ </property>
+ <property name="text">
+ <string>&amp;Close</string>
+ </property>
+ <property name="default">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </hbox>
+ </widget>
+ </grid>
+</widget>
+<connections>
+ <connection>
+ <sender>close_</sender>
+ <signal>clicked()</signal>
+ <receiver>AttachPropertyDialogBase</receiver>
+ <slot>accept()</slot>
+ </connection>
+ <connection>
+ <sender>save_</sender>
+ <signal>clicked()</signal>
+ <receiver>AttachPropertyDialogBase</receiver>
+ <slot>saveClicked()</slot>
+ </connection>
+</connections>
+<slots>
+ <slot access="protected">saveClicked()</slot>
+</slots>
+<layoutdefaults spacing="6" margin="11"/>
+<includehints>
+ <includehint>klistview.h</includehint>
+</includehints>
+</UI>
diff --git a/ktnef/gui/ktnef.desktop b/ktnef/gui/ktnef.desktop
new file mode 100644
index 00000000..b2d75f8d
--- /dev/null
+++ b/ktnef/gui/ktnef.desktop
@@ -0,0 +1,109 @@
+[Desktop Entry]
+Name=KTnef
+Name[sv]=Ktnef
+GenericName=TNEF File Viewer
+GenericName[af]=TNEF lêer leser
+GenericName[bg]=Преглед на файлове TNEF
+GenericName[br]=Gweler restr TNEF
+GenericName[ca]=Visor de fitxers TNEF
+GenericName[cs]=Prohlížeč TNEF souborů
+GenericName[cy]=Syllwr Ffeil TNEF
+GenericName[da]=TNEF Fil-fremviser
+GenericName[de]=TNEF-Dateibetrachter
+GenericName[el]=Προβολέας αρχείων TNEF
+GenericName[eo]=TNEF-dosierorigardilo
+GenericName[es]=Visor de archivos TNEF
+GenericName[et]=TNEF-failide näitaja
+GenericName[eu]=TNEF fitxategi ikustailea
+GenericName[fa]=مشاهده‌گر پروندۀ TNEF
+GenericName[fi]=TNEF-tiedostonäytin
+GenericName[fr]=Afficheur de fichiers TNEF
+GenericName[fy]=TNEF-triemwerjefte
+GenericName[ga]=Amharcán Comhad TNEF
+GenericName[gl]=Visor de Ficheiros TNEF
+GenericName[hu]=TNEF-fájlnézegető
+GenericName[is]=TNEF skráarskoðari
+GenericName[it]=Visualizzatore file TNEF
+GenericName[ja]=TNEF ファイルビュー
+GenericName[ka]=TNEF ფაილების დამთვალიერებელი
+GenericName[kk]=TNEF файлды қарау құралы
+GenericName[km]=កម្មវិធី​មើល​ឯកសារ TNEF
+GenericName[lt]=TNEF bylų žiūryklė
+GenericName[mk]=Прегледувач на TNEF-датотеки
+GenericName[ms]=Pemapar Fail TNEF
+GenericName[nb]=TNEF-filvisning
+GenericName[nds]=TNEF-Dateikieker
+GenericName[ne]=TNEF फाइल दर्शक
+GenericName[nl]=TNEF-bestandsweergave
+GenericName[nn]=TNEF filvisar
+GenericName[pl]=Przeglądarka plików TNEF
+GenericName[pt]=Visualizador de Ficheiros TNEF
+GenericName[pt_BR]=Visualizador de Arquivos TNEF
+GenericName[ru]=Просмотр файлов TNEF
+GenericName[sk]=Prehliadač súborov TNEF
+GenericName[sl]=Pregledovalnik datotek TNEF
+GenericName[sr]=Приказивач TNEF фајлова
+GenericName[sr@Latn]=Prikazivač TNEF fajlova
+GenericName[sv]=TNEF-filvisning
+GenericName[ta]=TNEF கோப்பு காட்சியாளன்
+GenericName[tr]=TNEF Dosya Göstericisi
+GenericName[uk]=Переглядач файлів TNEF
+GenericName[zh_CN]=TNEF 文件查看器
+GenericName[zh_TW]=TNEF 檔案檢視器
+Exec=ktnef %i %m -caption "%c"
+Icon=ktnef
+Type=Application
+DocPath=ktnef/index.html
+Comment=A viewer/extractor for TNEF files
+Comment[af]='n Leeser en data onttrekker vir TNEF lêers
+Comment[bg]=Програма за преглед и извличане на файлове TNEF
+Comment[bs]=Preglednik/ekstraktor za TNEF datoteke
+Comment[ca]=Un visor/extractor per a fitxers TNEF
+Comment[cs]=Prohlížeč TNEF souborů
+Comment[cy]=Gwelydd/echdynnydd i ffeiliau TNEF
+Comment[da]=En fremviser/udpakker for TNEF-filer
+Comment[de]=Betrachten und Extrahieren von TNEF-Dateien
+Comment[el]=Ένας προβολέας/εξαγωγέας για αρχεία TNEF
+Comment[es]=A visor/extractor para archivos TNEF
+Comment[et]=TNEF-failide näitaja/ekstraktija
+Comment[eu]=TNEF fitxategien ikustaile/erauzlea
+Comment[fa]=یک مشاهده‌گر/استخراج‌گر برای پرونده‌های TNEF
+Comment[fi]=Näytin/purkaja TNEF-tiedostoille
+Comment[fr]=Pour afficher / extraire des fichiers TNEF
+Comment[fy]=In werjefteprogramma/útpakker foar TNEF-triemmen
+Comment[gl]=Un visor/extractor para ficheiros TNEF
+Comment[hi]=टीएनईएफ फ़ाइलों के लिए एक प्रदर्शक/एक्सट्रेक्टर
+Comment[hr]=Prikazivač/izdvajač za TNEF datoteke
+Comment[hu]=Nézegetőprogram TNEF-fájlokhoz
+Comment[is]=Sýnir/lesari fyrir TNEF skrár
+Comment[it]=Un visualizzatore/estrattore di file TNEF
+Comment[ja]=TNEF ファイルのためのビューア/展開ツール
+Comment[ka]= TNEF ფაილების ექსტრაქტორი/დამთვალიერებელი
+Comment[kk]=TNEF файдарды қарау/тарқату
+Comment[km]=កម្មវិធី​មើល និង​ស្រង់​ឯកសារ TNEF
+Comment[lt]=TNEF bylų žiūryklė - išpakuotojas
+Comment[ms]=Pemapar/pengekstrak untuk fail TNEF
+Comment[nb]=En utpakker/fremviser for TNEF-filer
+Comment[nds]=TNEF-Dateien ankieken un Delen ruttrecken
+Comment[ne]=TNEF फाइलका लागि दर्शक/निष्कासक
+Comment[nl]=Een weergaveprogramma/uitpakker voor TNEF-bestanden
+Comment[nn]=Ein framvisar/utpakkar for TNEF-filer
+Comment[pl]=Przeglądarka/program wyciągający zawartość plików TNEF
+Comment[pt]=Um visualizador/extractor de ficheiros TNEF
+Comment[pt_BR]=Um visualizador/extrator para arquivos TNEF
+Comment[ro]=Un vizualizor/extractor pentru fişiere TNEF
+Comment[ru]=Просмотр и распаковка файлов TNEF
+Comment[sk]=Prehliadač/extraktor pre TNEF súbory
+Comment[sl]=Pregledovalnik/izvlečevalnik za datoteke TNEF
+Comment[sr]=Приказивач/издвајач за TNEF фајлове
+Comment[sr@Latn]=Prikazivač/izdvajač za TNEF fajlove
+Comment[sv]=Visning och uppackning av TNEF-filer
+Comment[ta]=TNEF கோப்புகளுக்கான காட்சியகம்/பிரித்தெடுப்பாளர்
+Comment[tg]=Намоиш ва боз кардани файлҳои TNEF
+Comment[tr]=TNEF dosyaları için gösterici/çıkarıcı
+Comment[uk]=Переглядач/розпаковувач файлів TNEF
+Comment[zh_CN]=TNEF 文件的查看/提取器
+Comment[zh_TW]=TNEF 檔案檢視器
+Terminal=false
+MimeType=application/ms-tnef;
+Categories=Qt;KDE;X-KDE-Utilities-PIM;Office;Network;Email;
diff --git a/ktnef/gui/ktnefmain.cpp b/ktnef/gui/ktnefmain.cpp
new file mode 100644
index 00000000..a31d4016
--- /dev/null
+++ b/ktnef/gui/ktnefmain.cpp
@@ -0,0 +1,409 @@
+/*
+ ktnefmain.cpp
+
+ Copyright (C) 2002 Michael Goffioul <kdeprint@swing.be>
+
+ This file is part of KTNEF, the KDE TNEF support library/program.
+
+ 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.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software Foundation,
+ Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <kdebug.h>
+#include "ktnefmain.h"
+#include <ktnef/ktnefparser.h>
+#include "ktnefview.h"
+#include <ktnef/ktnefattach.h>
+#include <ktnef/ktnefproperty.h>
+#include <ktnef/ktnefmessage.h>
+#include "attachpropertydialog.h"
+#include "messagepropertydialog.h"
+
+#include <qpopupmenu.h>
+#include <klistview.h>
+#include <klocale.h>
+#include <kapplication.h>
+#include <kiconloader.h>
+#include <qpixmap.h>
+#include <kstdaccel.h>
+#include <qmessagebox.h>
+#include <kfiledialog.h>
+#include <qdir.h>
+#include <kprocess.h>
+#include <kglobal.h>
+#include <kstandarddirs.h>
+#include <kaction.h>
+#include <kstdaction.h>
+#include <kdialogbase.h>
+#include <ktempfile.h>
+#include <kkeydialog.h>
+
+#ifdef KDE_NO_COMPAT
+#undef KDE_NO_COMPAT
+#endif
+
+#include <krun.h>
+#include <kopenwith.h>
+#include <kedittoolbar.h>
+#include <kstatusbar.h>
+#include <kurldrag.h>
+
+
+#define NOT_IMPLEMENTED QMessageBox::information(this, "ktnef", "Not implemented yet", QMessageBox::Ok|QMessageBox::Default, 0)
+
+KTNEFMain::KTNEFMain(QWidget *parent, const char *name)
+ : KMainWindow(parent, name)
+{
+ setupActions();
+ setupStatusbar();
+
+ setupTNEF();
+
+ KGlobal::config()->setGroup("Settings");
+ defaultdir_ = KGlobal::config()->readPathEntry("defaultdir", "/tmp/");
+ lastdir_ = defaultdir_;
+
+ // create personale temo extract dir
+ KStandardDirs::makeDir(KGlobal::dirs()->localkdedir() + "/share/apps/ktnef/tmp");
+
+ resize(430,350);
+ setAutoSaveSettings( "MainWindow" );
+}
+
+KTNEFMain::~KTNEFMain()
+{
+ delete parser_;
+ cleanup();
+}
+
+void KTNEFMain::setupActions()
+{
+ // File menu
+ KStdAction::open(this, SLOT(openFile()), actionCollection());
+ KStdAction::quit(kapp, SLOT(quit()), actionCollection());
+
+ // Action menu
+ new KAction(i18n("View"), QString("viewmag"), 0, this, SLOT(viewFile()), actionCollection(), "view_file");
+ new KAction(i18n("View With..."), QString("package_applications"), 0, this, SLOT(viewFileAs()), actionCollection(), "view_file_as");
+ new KAction(i18n("Extract"), 0, this, SLOT(extractFile()), actionCollection(), "extract_file");
+ new KAction(i18n("Extract To..."), QString("ktnef_extract_to"), 0, this, SLOT(extractFileTo()), actionCollection(), "extract_file_to");
+ new KAction(i18n("Extract All To..."), QString("ktnef_extract_all_to"), 0, this, SLOT(extractAllFiles()), actionCollection(), "extract_all_files");
+ new KAction( i18n( "Message Properties" ), "help", 0, this, SLOT( slotShowMessageProperties() ), actionCollection(), "msg_properties" );
+ new KAction(i18n("Properties"), QString("contents"), 0, this, SLOT(propertiesFile()), actionCollection(), "properties_file");
+ new KAction( i18n( "Show Message Text" ), "mail_generic", 0, this, SLOT( slotShowMessageText() ), actionCollection(), "msg_text" );
+ new KAction( i18n( "Save Message Text As..." ), "filesave", 0, this, SLOT( slotSaveMessageText() ), actionCollection(), "msg_save" );
+ actionCollection()->action("view_file")->setEnabled(false);
+ actionCollection()->action("view_file_as")->setEnabled(false);
+ actionCollection()->action("extract_file")->setEnabled(false);
+ actionCollection()->action("extract_file_to")->setEnabled(false);
+ actionCollection()->action("extract_all_files")->setEnabled(false);
+ actionCollection()->action("properties_file")->setEnabled(false);
+
+ // Option menu
+ new KAction(i18n("Default Folder..."), QString("folder_open"), 0, this, SLOT(optionDefaultDir()), actionCollection(), "options_default_dir");
+
+ createStandardStatusBarAction();
+ setStandardToolBarMenuEnabled(true);
+ KStdAction::configureToolbars(this, SLOT(slotEditToolbars()), actionCollection());
+ KStdAction::keyBindings( this, SLOT( slotConfigureKeys() ), actionCollection() );
+
+ createGUI();
+}
+
+void KTNEFMain::slotConfigureKeys()
+{
+ KKeyDialog::configure( actionCollection(), this );
+}
+
+
+void KTNEFMain::setupStatusbar()
+{
+ statusBar()->insertItem(i18n("100 attachments found"), 0);
+ statusBar()->changeItem(i18n("No file loaded"), 0);
+}
+
+void KTNEFMain::setupTNEF()
+{
+ view_ = new KTNEFView(this);
+ view_->setAllColumnsShowFocus( true );
+ parser_ = new KTNEFParser;
+
+ setCentralWidget(view_);
+ connect(view_, SIGNAL(selectionChanged()), SLOT(viewSelectionChanged()));
+ connect(view_, SIGNAL(rightButtonPressed(QListViewItem*,const QPoint&,int)), SLOT(viewRightButtonPressed(QListViewItem*,const QPoint&,int)));
+ connect(view_, SIGNAL(doubleClicked(QListViewItem*)), SLOT(viewDoubleClicked(QListViewItem*)));
+ connect(view_, SIGNAL(dragRequested(const QValueList<KTNEFAttach*>&)), SLOT(viewDragRequested(const QValueList<KTNEFAttach*>&)));
+}
+
+void KTNEFMain::loadFile(const QString& filename)
+{
+ filename_ = filename;
+ setCaption(filename_);
+ if (!parser_->openFile(filename))
+ {
+ QMessageBox::critical(this, i18n("Error"), i18n("Unable to open file."), QMessageBox::Ok|QMessageBox::Default, 0);
+ view_->setAttachments(0);
+ enableExtractAll(false);
+ }
+ else
+ {
+ QPtrList<KTNEFAttach> list = parser_->message()->attachmentList();
+ QString msg;
+ msg = i18n( "%n attachment found", "%n attachments found", list.count() );
+ statusBar()->changeItem(msg, 0);
+ view_->setAttachments(&list);
+ enableExtractAll((list.count() > 0));
+ enableSingleAction(false);
+ }
+}
+
+void KTNEFMain::openFile()
+{
+ QString filename = KFileDialog::getOpenFileName(0,0,this,0);
+ if (!filename.isEmpty()) loadFile(filename);
+}
+
+void KTNEFMain::viewFile()
+{
+ KTNEFAttach *attach = view_->getSelection()->first();
+ KURL url("file:"+extractTemp(attach));
+ QString mimename(attach->mimeTag());
+
+ if (mimename.isEmpty() || mimename == "application/octet-stream")
+ {
+ kdDebug() << "No mime type found in attachment object, trying to guess..." << endl;
+ mimename = KMimeType::findByURL(url, 0, true)->name();
+ kdDebug() << "Detected mime type: " << mimename << endl;
+ }
+ else
+ kdDebug() << "Mime type from attachment object: " << mimename << endl;
+
+ KRun::runURL(url, mimename);
+}
+
+QString KTNEFMain::extractTemp(KTNEFAttach *att)
+{
+ QString dir = KGlobal::dirs()->localkdedir() + "/share/apps/ktnef/tmp/";
+ parser_->extractFileTo(att->name(), dir);
+ dir.append(att->name());
+ return dir;
+}
+
+void KTNEFMain::viewFileAs()
+{
+ KURL::List list;
+ list.append(KURL::fromPathOrURL( extractTemp(view_->getSelection()->first()) ));
+
+ KRun::displayOpenWithDialog(list);
+}
+
+void KTNEFMain::extractFile()
+{
+ extractTo(defaultdir_);
+}
+
+void KTNEFMain::extractFileTo()
+{
+ QString dir = KFileDialog::getExistingDirectory(lastdir_, this);
+ if (!dir.isEmpty())
+ {
+ extractTo(dir);
+ lastdir_ = dir;
+ }
+}
+
+void KTNEFMain::extractAllFiles()
+{
+ QString dir = KFileDialog::getExistingDirectory(lastdir_, this);
+ if (!dir.isEmpty())
+ {
+ lastdir_ = dir;
+ dir.append("/");
+ QPtrList<KTNEFAttach> list = parser_->message()->attachmentList();
+ QPtrListIterator<KTNEFAttach> it(list);
+ for (;it.current();++it)
+ if (!parser_->extractFileTo(it.current()->name(), dir))
+ {
+ QString msg = i18n( "Unable to extract file \"%1\"" ).arg( it.current()->name() );
+ QMessageBox::critical(this,i18n("Error"),msg,QMessageBox::Ok|QMessageBox::Default,0);
+ return;
+ }
+ }
+}
+
+void KTNEFMain::propertiesFile()
+{
+ KTNEFAttach *attach = view_->getSelection()->first();
+ AttachPropertyDialog dlg(this);
+ dlg.setAttachment(attach);
+ dlg.exec();
+}
+
+void KTNEFMain::optionDefaultDir()
+{
+ QString dirname = KFileDialog::getExistingDirectory(defaultdir_, this);
+ if (!dirname.isEmpty())
+ {
+ defaultdir_ = dirname;
+ KGlobal::config()->setGroup("Settings");
+ KGlobal::config()->writePathEntry("defaultdir",defaultdir_);
+ }
+}
+
+void KTNEFMain::viewSelectionChanged()
+{
+ QPtrList<KTNEFAttach> *list = view_->getSelection();
+ bool on1 = (list->count() == 1u), on2 = (list->count() > 0u);
+ actionCollection()->action("view_file")->setEnabled(on1);
+ actionCollection()->action("view_file_as")->setEnabled(on1);
+ actionCollection()->action("properties_file")->setEnabled(on1);
+
+ actionCollection()->action("extract_file")->setEnabled(on2);
+ actionCollection()->action("extract_file_to")->setEnabled(on2);
+}
+
+void KTNEFMain::enableExtractAll(bool on)
+{
+ if (!on) enableSingleAction(false);
+ actionCollection()->action("extract_all_files")->setEnabled(on);
+}
+
+void KTNEFMain::enableSingleAction(bool on)
+{
+ actionCollection()->action("extract_file")->setEnabled(on);
+ actionCollection()->action("extract_file_to")->setEnabled(on);
+ actionCollection()->action("view_file")->setEnabled(on);
+ actionCollection()->action("view_file_as")->setEnabled(on);
+ actionCollection()->action("properties_file")->setEnabled(on);
+}
+
+void KTNEFMain::cleanup()
+{
+ QDir d(KGlobal::dirs()->localkdedir() + "/share/apps/ktnef/tmp/");
+ const QFileInfoList *list = d.entryInfoList(QDir::Files|QDir::Hidden,QDir::Unsorted);
+ QFileInfoListIterator it(*list);
+ for (;it.current();++it)
+ d.remove(it.current()->absFilePath());
+}
+
+void KTNEFMain::extractTo(const QString& dirname)
+{
+ QString dir = dirname;
+ if (dir.right(1) != "/") dir.append("/");
+ QPtrList<KTNEFAttach> *list = view_->getSelection();
+ QPtrListIterator<KTNEFAttach> it(*list);
+ for (;it.current();++it)
+ if (!parser_->extractFileTo(it.current()->name(), dir))
+ {
+ QString msg = i18n("Unable to extract file \"%1\"").arg( it.current()->name() );
+ QMessageBox::critical(this,i18n("Error"),msg,QMessageBox::Ok|QMessageBox::Default,0);
+ return;
+ }
+}
+
+/* This breaks the saveMainWindowSettings stuff....
+ void KTNEFMain::closeEvent(QCloseEvent *e)
+{
+ e->accept();
+}*/
+
+void KTNEFMain::viewRightButtonPressed(QListViewItem*, const QPoint& p, int)
+{
+ QPtrList<KTNEFAttach> *list = view_->getSelection();
+ QPopupMenu m;
+ if (list->count() > 0u)
+ {
+ if (list->count() == 1u)
+ {
+ m.insertItem(SmallIcon("viewmag"), i18n("View"), this, SLOT(viewFile()));
+ m.insertItem(SmallIcon("package_applications"), i18n("View With..."), this, SLOT(viewFileAs()));
+ m.insertSeparator();
+ }
+ m.insertItem(i18n("Extract"), this, SLOT(extractFile()));
+ m.insertItem(SmallIcon("ktnef_extract_to"), i18n("Extract To..."), this, SLOT(extractFileTo()));
+ if (list->count() == 1u)
+ {
+ m.insertSeparator();
+ m.insertItem(SmallIcon("contents"), i18n("Properties"), this, SLOT(propertiesFile()));
+ }
+ }
+ else if ( list->count() == 0 )
+ actionCollection()->action( "msg_properties" )->plug( &m );
+ m.exec( p );
+}
+
+void KTNEFMain::viewDoubleClicked(QListViewItem *item)
+{
+ if (item && item->isSelected())
+ viewFile();
+}
+
+void KTNEFMain::viewDragRequested( const QValueList<KTNEFAttach*>& list )
+{
+ KURL::List urlList;
+ for ( QValueList<KTNEFAttach*>::ConstIterator it=list.constBegin(); it!=list.constEnd(); ++it )
+ urlList << KURL( extractTemp( *it ) );
+ if ( !list.isEmpty() )
+ {
+ KURLDrag *urlDrag = new KURLDrag( urlList, this );
+ urlDrag->dragCopy();
+ }
+}
+
+void KTNEFMain::slotEditToolbars()
+{
+ saveMainWindowSettings( KGlobal::config(), QString::fromLatin1("MainWindow") );
+ KEditToolbar dlg(actionCollection());
+ connect(&dlg, SIGNAL( newToolbarConfig() ), this, SLOT( slotNewToolbarConfig() ));
+ dlg.exec();
+}
+
+void KTNEFMain::slotNewToolbarConfig()
+{
+ createGUI();
+ applyMainWindowSettings( KGlobal::config(), QString::fromLatin1("MainWindow") );
+}
+
+void KTNEFMain::slotShowMessageProperties()
+{
+ MessagePropertyDialog dlg( this, parser_->message() );
+ dlg.exec();
+}
+
+void KTNEFMain::slotShowMessageText()
+{
+ QString rtf = parser_->message()->rtfString();
+ qDebug( "%s", rtf.latin1() );
+ KTempFile tmpFile( KGlobal::dirs()->localkdedir() + "/share/apps/ktnef/tmp/", "rtf");
+ *( tmpFile.textStream() ) << rtf;
+ tmpFile.close();
+
+ KRun::runURL( KURL::fromPathOrURL( tmpFile.name() ), "text/rtf", true );
+}
+
+void KTNEFMain::slotSaveMessageText()
+{
+ QString rtf = parser_->message()->rtfString();
+ QString filename = KFileDialog::getSaveFileName( QString::null, QString::null, this );
+ if ( !filename.isEmpty() )
+ {
+ QFile f( filename );
+ if ( f.open( IO_WriteOnly ) )
+ {
+ QTextStream t( &f );
+ t << rtf;
+ }
+ else
+ QMessageBox::critical( this, i18n( "Error" ),
+ i18n( "Unable to open file for writing, check file permissions." ),
+ QMessageBox::Ok|QMessageBox::Default, 0);
+ }
+}
+
+#include "ktnefmain.moc"
diff --git a/ktnef/gui/ktnefmain.h b/ktnef/gui/ktnefmain.h
new file mode 100644
index 00000000..30f5a171
--- /dev/null
+++ b/ktnef/gui/ktnefmain.h
@@ -0,0 +1,81 @@
+/*
+ ktnefmain.h
+
+ Copyright (C) 2002 Michael Goffioul <kdeprint@swing.be>
+
+ This file is part of KTNEF, the KDE TNEF support library/program.
+
+ 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.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software Foundation,
+ Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef KTNEFMAIN_H
+#define KTNEFMAIN_H
+
+#include <kmainwindow.h>
+#include <qstring.h>
+#include <qlistview.h>
+
+class KTNEFView;
+class KTNEFParser;
+class KTNEFAttach;
+
+class KTNEFMain : public KMainWindow
+{
+ Q_OBJECT
+
+public:
+ KTNEFMain(QWidget *parent = 0, const char *name = 0);
+ ~KTNEFMain();
+
+ void loadFile(const QString& filename);
+
+protected slots:
+ void openFile();
+ void viewFile();
+ void viewFileAs();
+ void extractFile();
+ void extractFileTo();
+ void propertiesFile();
+ void optionDefaultDir();
+ void extractAllFiles();
+ void slotEditToolbars();
+ void slotNewToolbarConfig();
+ void slotShowMessageProperties();
+ void slotShowMessageText();
+ void slotSaveMessageText();
+
+ void viewSelectionChanged();
+ void viewRightButtonPressed(QListViewItem *item, const QPoint& p, int c);
+ void viewDoubleClicked(QListViewItem*);
+ void viewDragRequested( const QValueList<KTNEFAttach*>& list );
+ void slotConfigureKeys();
+//protected:
+// void closeEvent(QCloseEvent *e);
+
+private:
+ void setupStatusbar();
+ void setupActions();
+ void setupTNEF();
+ void enableExtractAll(bool on = true);
+ void enableSingleAction(bool on = true);
+ void cleanup();
+
+ void extractTo(const QString& dirname);
+ QString extractTemp(KTNEFAttach *att);
+
+private:
+ KTNEFView *view_;
+ KTNEFParser *parser_;
+ QString filename_;
+ QString defaultdir_;
+ QString lastdir_;
+};
+
+#endif
diff --git a/ktnef/gui/ktnefui.rc b/ktnef/gui/ktnefui.rc
new file mode 100644
index 00000000..c08cf136
--- /dev/null
+++ b/ktnef/gui/ktnefui.rc
@@ -0,0 +1,36 @@
+<!DOCTYPE kpartgui>
+<kpartgui name="kups" version="2">
+<MenuBar>
+ <Menu name="action"><text>&amp;Action</text>
+ <Action name="view_file" />
+ <Action name="view_file_as" />
+ <Separator/>
+ <Action name="extract_file" />
+ <Action name="extract_file_to" />
+ <Separator/>
+ <Action name="extract_all_files" />
+ <Separator/>
+ <Action name="properties_file" />
+ <Separator/>
+ <Action name="msg_properties" />
+ <Action name="msg_text" />
+ <Action name="msg_save" />
+ </Menu>
+ <Menu name="settings"><text>&amp;Settings</text>
+ <Action name="options_default_dir" append="save_merge"/>
+ </Menu>
+</MenuBar>
+<ToolBar name="mainToolBar" noMerge="1">
+ <text>Main Toolbar</text>
+ <Action name="file_open" />
+ <Separator/>
+ <Action name="view_file" />
+ <Action name="properties_file" />
+ <Separator/>
+ <Action name="extract_file_to" />
+ <Action name="extract_all_files" />
+ <Separator/>
+ <Action name="msg_properties" />
+ <Action name="msg_text" />
+</ToolBar>
+</kpartgui>
diff --git a/ktnef/gui/ktnefview.cpp b/ktnef/gui/ktnefview.cpp
new file mode 100644
index 00000000..abee5a73
--- /dev/null
+++ b/ktnef/gui/ktnefview.cpp
@@ -0,0 +1,136 @@
+/*
+ ktnefview.cpp
+
+ Copyright (C) 2002 Michael Goffioul <kdeprint@swing.be>
+
+ This file is part of KTNEF, the KDE TNEF support library/program.
+
+ 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.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software Foundation,
+ Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include "ktnefview.h"
+#include <ktnef/ktnefattach.h>
+#include "attachpropertydialog.h"
+
+#include <qheader.h>
+#include <qpixmap.h>
+#include <qtimer.h>
+
+#include <kapplication.h>
+#include <kiconloader.h>
+#include <klocale.h>
+#include <kdebug.h>
+
+#include <kmimetype.h>
+
+class Attachment : public QListViewItem
+{
+public:
+ Attachment(QListView *parent, KTNEFAttach *attach);
+ ~Attachment();
+
+ KTNEFAttach* getAttachment() const { return attach_; }
+
+private:
+ KTNEFAttach *attach_;
+};
+
+Attachment::Attachment(QListView *parent, KTNEFAttach *attach)
+ : QListViewItem(parent, attach->name()), attach_(attach)
+{
+ setText(2, QString::number( attach_->size() ));
+ if (!attach_->fileName().isEmpty()) setText(0, attach_->fileName());
+ KMimeType::Ptr mimeType = KMimeType::mimeType( attach_->mimeTag() );
+ setText(1, mimeType->comment());
+ QPixmap pix = loadRenderingPixmap( attach, parent->colorGroup().base() );
+ if ( !pix.isNull() )
+ setPixmap( 0, pix );
+ else
+ setPixmap(0, mimeType->pixmap(KIcon::Small));
+ setDragEnabled( true );
+}
+
+Attachment::~Attachment()
+{
+}
+
+//------------------------------------------------------------------------------------------------------
+
+KTNEFView::KTNEFView(QWidget *parent, const char *name)
+ : KListView(parent,name)
+{
+ attachments_.setAutoDelete(false);
+ addColumn(i18n("File Name"));
+ addColumn(i18n("File Type"));
+ addColumn(i18n("Size"));
+ setFrameStyle(QFrame::WinPanel|QFrame::Sunken);
+ setLineWidth(1);
+ setSelectionMode(QListView::Extended);
+ setHScrollBarMode(QScrollView::AlwaysOff);
+ setVScrollBarMode(QScrollView::AlwaysOn);
+ QTimer::singleShot( 0, this, SLOT(adjustColumnWidth()) );
+}
+
+KTNEFView::~KTNEFView()
+{
+}
+
+void KTNEFView::setAttachments(QPtrList<KTNEFAttach> *list)
+{
+ clear();
+ if (list)
+ {
+ QPtrListIterator<KTNEFAttach> it(*list);
+ for (;it.current();++it)
+ new Attachment(this, it.current());
+ }
+}
+
+void KTNEFView::resizeEvent(QResizeEvent *e)
+{
+ adjustColumnWidth();
+ resizeContents(visibleWidth(),visibleHeight());
+ if (e) QListView::resizeEvent(e);
+}
+
+QPtrList<KTNEFAttach>* KTNEFView::getSelection()
+{
+ attachments_.clear();
+ QListViewItem *item = firstChild();
+ while (item)
+ {
+ if (item->isSelected()) attachments_.append(((Attachment*)item)->getAttachment());
+ item = item->nextSibling();
+ }
+ return &attachments_;
+}
+
+void KTNEFView::startDrag()
+{
+ QListViewItemIterator it( this, QListViewItemIterator::Selected );
+ QValueList<KTNEFAttach*> list;
+ while ( it.current() )
+ {
+ list << static_cast<Attachment*>( it.current() )->getAttachment();
+ ++it;
+ }
+ if ( !list.isEmpty() )
+ emit dragRequested( list );
+}
+
+void KTNEFView::adjustColumnWidth()
+{
+ int w = visibleWidth()/2;
+ setColumnWidth(0,w);
+ setColumnWidth(1,w/2);
+ setColumnWidth(2,w/2);
+}
+
+#include "ktnefview.moc"
diff --git a/ktnef/gui/ktnefview.h b/ktnef/gui/ktnefview.h
new file mode 100644
index 00000000..00c49b7c
--- /dev/null
+++ b/ktnef/gui/ktnefview.h
@@ -0,0 +1,52 @@
+/*
+ ktnefview.h
+
+ Copyright (C) 2002 Michael Goffioul <kdeprint@swing.be>
+
+ This file is part of KTNEF, the KDE TNEF support library/program.
+
+ 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.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software Foundation,
+ Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef KTNEFWIDGET_H
+#define KTNEFWIDGET_H
+
+#include <klistview.h>
+#include <qptrlist.h>
+#include <kdepimmacros.h>
+
+class KTNEFAttach;
+
+class KDE_EXPORT KTNEFView : public KListView
+{
+ Q_OBJECT
+
+public:
+ KTNEFView(QWidget *parent = 0, const char *name = 0);
+ ~KTNEFView();
+
+ void setAttachments(QPtrList<KTNEFAttach> *list);
+ QPtrList<KTNEFAttach>* getSelection();
+
+signals:
+ void dragRequested( const QValueList<KTNEFAttach*>& list );
+
+protected:
+ void resizeEvent(QResizeEvent *e);
+ void startDrag();
+
+private slots:
+ void adjustColumnWidth();
+
+private:
+ QPtrList<KTNEFAttach> attachments_;
+};
+
+#endif
diff --git a/ktnef/gui/main.cpp b/ktnef/gui/main.cpp
new file mode 100644
index 00000000..e975630d
--- /dev/null
+++ b/ktnef/gui/main.cpp
@@ -0,0 +1,57 @@
+/*
+ main.cpp
+
+ Copyright (C) 2002 Michael Goffioul <kdeprint@swing.be>
+
+ This file is part of KTNEF, the KDE TNEF support library/program.
+
+ 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.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software Foundation,
+ Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <kcmdlineargs.h>
+#include <kaboutdata.h>
+#include <klocale.h>
+#include <kapplication.h>
+
+#include "ktnefmain.h"
+
+static const char description[] =
+ I18N_NOOP("Viewer for mail attachments using TNEF format");
+
+
+static KCmdLineOptions options[] =
+{
+ { "+[file]", I18N_NOOP("An optional argument 'file'"), 0 },
+ KCmdLineLastOption
+ // INSERT YOUR COMMANDLINE OPTIONS HERE
+};
+
+int main(int argc, char *argv[])
+{
+
+ KAboutData aboutData( "ktnef", I18N_NOOP("KTnef"),
+ "1.0", description, KAboutData::License_GPL,
+ "(c) 2000, Michael Goffioul");
+ aboutData.addAuthor("Michael Goffioul",0, "kdeprint@swing.be");
+ KCmdLineArgs::init( argc, argv, &aboutData );
+ KCmdLineArgs::addCmdLineOptions( options ); // Add our own options.
+ KApplication::addCmdLineOptions();
+
+ KApplication a;
+ KTNEFMain *tnef = new KTNEFMain();
+ a.setMainWidget(tnef);
+ tnef->show();
+
+ KCmdLineArgs *args = KCmdLineArgs::parsedArgs();
+ if (args->count() > 0)
+ tnef->loadFile(args->arg(0));
+
+ return a.exec();
+}
diff --git a/ktnef/gui/messagepropertydialog.cpp b/ktnef/gui/messagepropertydialog.cpp
new file mode 100644
index 00000000..0e098c35
--- /dev/null
+++ b/ktnef/gui/messagepropertydialog.cpp
@@ -0,0 +1,46 @@
+/*
+ messagepropertydialog.cpp
+
+ Copyright (C) 2003 Michael Goffioul <kdeprint@swing.be>
+
+ This file is part of KTNEF, the KDE TNEF support library/program.
+
+ 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.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software Foundation,
+ Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include "messagepropertydialog.h"
+#include "attachpropertydialog.h"
+#include "ktnef/ktnefmessage.h"
+
+#include <klistview.h>
+#include <klocale.h>
+
+MessagePropertyDialog::MessagePropertyDialog( QWidget *parent, KTNEFMessage *msg )
+ : KDialogBase( parent, "MessagePropertyDialog", true, i18n( "Message Properties" ),
+ KDialogBase::Close|KDialogBase::User1, KDialogBase::Close, false,
+ KStdGuiItem::save() )
+{
+ m_message = msg;
+
+ m_listview = new KListView( this );
+ m_listview->addColumn( i18n( "Name" ) );
+ m_listview->addColumn( i18n( "Value" ) );
+ m_listview->setAllColumnsShowFocus( true );
+ setMainWidget( m_listview );
+
+ formatPropertySet( m_message, m_listview );
+}
+
+void MessagePropertyDialog::slotUser1()
+{
+ saveProperty( m_listview, m_message, this );
+}
+
+#include "messagepropertydialog.moc"
diff --git a/ktnef/gui/messagepropertydialog.h b/ktnef/gui/messagepropertydialog.h
new file mode 100644
index 00000000..7b357b71
--- /dev/null
+++ b/ktnef/gui/messagepropertydialog.h
@@ -0,0 +1,40 @@
+/*
+ messagepropertydialog.h
+
+ Copyright (C) 2003 Michael Goffioul <kdeprint@swing.be>
+
+ This file is part of KTNEF, the KDE TNEF support library/program.
+
+ 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.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software Foundation,
+ Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef MESSAGEPROPERTYDIALOG_H
+#define MESSAGEPROPERTYDIALOG_H
+
+#include <kdialogbase.h>
+
+class KListView;
+class KTNEFMessage;
+
+class MessagePropertyDialog : public KDialogBase
+{
+ Q_OBJECT
+public:
+ MessagePropertyDialog( QWidget *parent, KTNEFMessage *msg );
+
+protected slots:
+ void slotUser1();
+
+private:
+ KTNEFMessage *m_message;
+ KListView *m_listview;
+};
+
+#endif /* MESSAGEPROPERTYDIALOG_H */
diff --git a/ktnef/gui/metafuncs.h b/ktnef/gui/metafuncs.h
new file mode 100644
index 00000000..8675851e
--- /dev/null
+++ b/ktnef/gui/metafuncs.h
@@ -0,0 +1,90 @@
+/* WMF Metafile Function Description Table
+ * Author: Stefan Taferner <taferner@kde.org>
+ */
+#ifndef metafunc_h
+#define metafunc_h
+
+class QWinMetaFile;
+
+static const struct MetaFuncRec
+{
+ const char* name;
+ unsigned short func;
+ void ( QWinMetaFile::*method )( long, short* );
+} metaFuncTab[] =
+ {
+ { "SETBKCOLOR", 0x0201, &QWinMetaFile::setBkColor },
+ { "SETBKMODE", 0x0102, &QWinMetaFile::setBkMode },
+ { "SETMAPMODE", 0x0103, &QWinMetaFile::noop },
+ { "SETROP2", 0x0104, &QWinMetaFile::setRop },
+ { "SETRELABS", 0x0105, &QWinMetaFile::noop },
+ { "SETPOLYFILLMODE", 0x0106, &QWinMetaFile::setPolyFillMode },
+ { "SETSTRETCHBLTMODE", 0x0107, &QWinMetaFile::noop },
+ { "SETTEXTCHAREXTRA", 0x0108, &QWinMetaFile::noop },
+ { "SETTEXTCOLOR", 0x0209, &QWinMetaFile::setTextColor },
+ { "SETTEXTJUSTIFICATION", 0x020A, &QWinMetaFile::noop },
+ { "SETWINDOWORG", 0x020B, &QWinMetaFile::setWindowOrg },
+ { "SETWINDOWEXT", 0x020C, &QWinMetaFile::setWindowExt },
+ { "SETVIEWPORTORG", 0x020D, &QWinMetaFile::noop },
+ { "SETVIEWPORTEXT", 0x020E, &QWinMetaFile::noop },
+ { "OFFSETWINDOWORG", 0x020F, &QWinMetaFile::noop },
+ { "SCALEWINDOWEXT", 0x0410, &QWinMetaFile::noop },
+ { "OFFSETVIEWPORTORG", 0x0211, &QWinMetaFile::noop },
+ { "SCALEVIEWPORTEXT", 0x0412, &QWinMetaFile::noop },
+ { "LINETO", 0x0213, &QWinMetaFile::lineTo },
+ { "MOVETO", 0x0214, &QWinMetaFile::moveTo },
+ { "EXCLUDECLIPRECT", 0x0415, &QWinMetaFile::excludeClipRect },
+ { "INTERSECTCLIPRECT", 0x0416, &QWinMetaFile::intersectClipRect },
+ { "ARC", 0x0817, &QWinMetaFile::arc },
+ { "ELLIPSE", 0x0418, &QWinMetaFile::ellipse },
+ { "FLOODFILL", 0x0419, &QWinMetaFile::noop },
+ { "PIE", 0x081A, &QWinMetaFile::pie },
+ { "RECTANGLE", 0x041B, &QWinMetaFile::rectangle },
+ { "ROUNDRECT", 0x061C, &QWinMetaFile::roundRect },
+ { "PATBLT", 0x061D, &QWinMetaFile::noop },
+ { "SAVEDC", 0x001E, &QWinMetaFile::saveDC },
+ { "SETPIXEL", 0x041F, &QWinMetaFile::setPixel },
+ { "OFFSETCLIPRGN", 0x0220, &QWinMetaFile::noop },
+ { "TEXTOUT", 0x0521, &QWinMetaFile::textOut },
+ { "BITBLT", 0x0922, &QWinMetaFile::noop },
+ { "STRETCHBLT", 0x0B23, &QWinMetaFile::noop },
+ { "POLYGON", 0x0324, &QWinMetaFile::polygon },
+ { "POLYLINE", 0x0325, &QWinMetaFile::polyline },
+ { "ESCAPE", 0x0626, &QWinMetaFile::noop },
+ { "RESTOREDC", 0x0127, &QWinMetaFile::restoreDC },
+ { "FILLREGION", 0x0228, &QWinMetaFile::noop },
+ { "FRAMEREGION", 0x0429, &QWinMetaFile::noop },
+ { "INVERTREGION", 0x012A, &QWinMetaFile::noop },
+ { "PAINTREGION", 0x012B, &QWinMetaFile::noop },
+ { "SELECTCLIPREGION", 0x012C, &QWinMetaFile::noop },
+ { "SELECTOBJECT", 0x012D, &QWinMetaFile::selectObject },
+ { "SETTEXTALIGN", 0x012E, &QWinMetaFile::setTextAlign },
+ { "CHORD", 0x0830, &QWinMetaFile::chord },
+ { "SETMAPPERFLAGS", 0x0231, &QWinMetaFile::noop },
+ { "EXTTEXTOUT", 0x0a32, &QWinMetaFile::extTextOut },
+ { "SETDIBTODEV", 0x0d33, &QWinMetaFile::noop },
+ { "SELECTPALETTE", 0x0234, &QWinMetaFile::noop },
+ { "REALIZEPALETTE", 0x0035, &QWinMetaFile::noop },
+ { "ANIMATEPALETTE", 0x0436, &QWinMetaFile::noop },
+ { "SETPALENTRIES", 0x0037, &QWinMetaFile::noop },
+ { "POLYPOLYGON", 0x0538, &QWinMetaFile::polyPolygon },
+ { "RESIZEPALETTE", 0x0139, &QWinMetaFile::noop },
+ { "DIBBITBLT", 0x0940, &QWinMetaFile::dibBitBlt },
+ { "DIBSTRETCHBLT", 0x0b41, &QWinMetaFile::dibStretchBlt },
+ { "DIBCREATEPATTERNBRUSH", 0x0142, &QWinMetaFile::dibCreatePatternBrush },
+ { "STRETCHDIB", 0x0f43, &QWinMetaFile::stretchDib },
+ { "EXTFLOODFILL", 0x0548, &QWinMetaFile::noop },
+ { "DELETEOBJECT", 0x01f0, &QWinMetaFile::deleteObject },
+ { "CREATEPALETTE", 0x00f7, &QWinMetaFile::createEmptyObject },
+ { "CREATEPATTERNBRUSH", 0x01F9, &QWinMetaFile::createEmptyObject },
+ { "CREATEPENINDIRECT", 0x02FA, &QWinMetaFile::createPenIndirect },
+ { "CREATEFONTINDIRECT", 0x02FB, &QWinMetaFile::createFontIndirect },
+ { "CREATEBRUSHINDIRECT", 0x02FC, &QWinMetaFile::createBrushIndirect },
+ { "CREATEREGION", 0x06FF, &QWinMetaFile::createEmptyObject },
+ { "END", 0, &QWinMetaFile::end },
+ // always the latest in the table : in case of unknown function
+ { NULL, 0, &QWinMetaFile::noop },
+ };
+
+
+#endif /*metafunc_h*/
diff --git a/ktnef/gui/ms-tnef.desktop b/ktnef/gui/ms-tnef.desktop
new file mode 100644
index 00000000..309bd8cf
--- /dev/null
+++ b/ktnef/gui/ms-tnef.desktop
@@ -0,0 +1,62 @@
+[Desktop Entry]
+Type=MimeType
+MimeType=application/ms-tnef
+Icon=tar
+Patterns=*.tnf;
+Comment=TNEF File
+Comment[af]=TNEF lêer
+Comment[be]=TNEF файл
+Comment[bg]=Файл TNEF
+Comment[br]=Restr TNEF
+Comment[bs]=TNEF datoteka
+Comment[ca]=Fitxer TNEF
+Comment[cs]=TNEF soubor
+Comment[cy]=Ffeil TNEF
+Comment[de]=TNEF-Datei
+Comment[el]=Αρχείο TNEF
+Comment[eo]=TNEF-dosiero
+Comment[es]=Archivo TNEF
+Comment[et]=TNEF-fail
+Comment[eu]=TNEF fitxategia
+Comment[fa]=پروندۀ TNEF
+Comment[fi]=TNEF-tiedosto
+Comment[fr]=Fichier TNEF
+Comment[fy]=TNEF-triem
+Comment[ga]=Comhad TNEF
+Comment[gl]=Ficheiro TNEF
+Comment[he]=קובץ TNEF
+Comment[hi]=टीएनईएफ फ़ाइल
+Comment[hr]=TNEF datoteka
+Comment[hu]=TNEF-fájl
+Comment[is]=TNEF skrá
+Comment[it]=File TNEF
+Comment[ja]=TNEF ファイル
+Comment[ka]=TNEF ფაილი
+Comment[kk]=TNEF файлы
+Comment[km]=ឯកសារ TNEF
+Comment[lt]=TNEF byla
+Comment[mk]=TNEF-датотека
+Comment[ms]=Fail TNEF
+Comment[nb]=TNEF-fil
+Comment[nds]=TNEF-Datei
+Comment[ne]=TNEF फाइल
+Comment[nl]=TNEF-bestand
+Comment[nn]=TNEF-fil
+Comment[pl]=Plik TNEF
+Comment[pt]=Ficheiro TNEF
+Comment[pt_BR]=Arquivo TNEF
+Comment[ro]=Fişier TNEF
+Comment[ru]=Файл TNEF
+Comment[sk]=TNEF súbor
+Comment[sl]=Datoteka TNEF
+Comment[sr]=TNEF фајл
+Comment[sr@Latn]=TNEF fajl
+Comment[sv]=TNEF-fil
+Comment[ta]=TNEF கோப்பு
+Comment[tg]=Файли TNEF
+Comment[tr]=TNEF Dosyası
+Comment[uk]=Файл TNEF
+Comment[uz]=TNEF-fayli
+Comment[uz@cyrillic]=TNEF-файли
+Comment[zh_CN]=TNEF 文件
+Comment[zh_TW]=TNEF 檔案
diff --git a/ktnef/gui/pics/Makefile.am b/ktnef/gui/pics/Makefile.am
new file mode 100644
index 00000000..43938ee0
--- /dev/null
+++ b/ktnef/gui/pics/Makefile.am
@@ -0,0 +1,4 @@
+KDE_ICON = ktnef
+
+icons_ICON = ktnef_extract_all_to ktnef_extract_to
+iconsdir = $(kde_datadir)/ktnef/icons
diff --git a/ktnef/gui/pics/hi22-action-ktnef_extract_all_to.png b/ktnef/gui/pics/hi22-action-ktnef_extract_all_to.png
new file mode 100644
index 00000000..d49470a0
--- /dev/null
+++ b/ktnef/gui/pics/hi22-action-ktnef_extract_all_to.png
Binary files differ
diff --git a/ktnef/gui/pics/hi22-action-ktnef_extract_to.png b/ktnef/gui/pics/hi22-action-ktnef_extract_to.png
new file mode 100644
index 00000000..a52fb6af
--- /dev/null
+++ b/ktnef/gui/pics/hi22-action-ktnef_extract_to.png
Binary files differ
diff --git a/ktnef/gui/pics/hi48-app-ktnef.png b/ktnef/gui/pics/hi48-app-ktnef.png
new file mode 100644
index 00000000..deee685e
--- /dev/null
+++ b/ktnef/gui/pics/hi48-app-ktnef.png
Binary files differ
diff --git a/ktnef/gui/pics/lo16-action-ktnef_extract_all_to.png b/ktnef/gui/pics/lo16-action-ktnef_extract_all_to.png
new file mode 100644
index 00000000..8dc72abc
--- /dev/null
+++ b/ktnef/gui/pics/lo16-action-ktnef_extract_all_to.png
Binary files differ
diff --git a/ktnef/gui/pics/lo16-action-ktnef_extract_to.png b/ktnef/gui/pics/lo16-action-ktnef_extract_to.png
new file mode 100644
index 00000000..c86449ae
--- /dev/null
+++ b/ktnef/gui/pics/lo16-action-ktnef_extract_to.png
Binary files differ
diff --git a/ktnef/gui/pics/lo16-app-ktnef.png b/ktnef/gui/pics/lo16-app-ktnef.png
new file mode 100644
index 00000000..383df318
--- /dev/null
+++ b/ktnef/gui/pics/lo16-app-ktnef.png
Binary files differ
diff --git a/ktnef/gui/pics/lo32-app-ktnef.png b/ktnef/gui/pics/lo32-app-ktnef.png
new file mode 100644
index 00000000..b566ff91
--- /dev/null
+++ b/ktnef/gui/pics/lo32-app-ktnef.png
Binary files differ
diff --git a/ktnef/gui/qwmf.cpp b/ktnef/gui/qwmf.cpp
new file mode 100644
index 00000000..6a10cc00
--- /dev/null
+++ b/ktnef/gui/qwmf.cpp
@@ -0,0 +1,1258 @@
+/* Windows Meta File Loader/Painter Class Implementation
+ *
+ * Copyright ( C ) 1998 Stefan Taferner
+ * Modified 2002 thierry lorthiois
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or ( at your
+ * option ) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABLILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details. You should have received a copy
+ * of the GNU General Public License along with this program; if not, write
+ * to the Free Software Foundation, Inc, 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ */
+
+#include <math.h>
+#include <assert.h>
+#include <qfileinfo.h>
+#include <qpixmap.h>
+#include <qpainter.h>
+#include <qdatastream.h>
+#include <qapplication.h>
+#include <qbuffer.h>
+#include <kdebug.h>
+
+bool qwmfDebug = false;
+
+#include "qwmf.h"
+#include "wmfstruct.h"
+#include "metafuncs.h"
+
+#define QWMF_DEBUG 0
+
+
+class WmfCmd
+{
+public:
+ ~WmfCmd() { if ( next ) delete next; }
+ WmfCmd* next;
+ unsigned short funcIndex;
+ long numParm;
+ short* parm;
+};
+
+
+class WinObjHandle
+{
+public:
+ virtual void apply( QPainter& p ) = 0;
+};
+
+class WinObjBrushHandle: public WinObjHandle
+{
+public:
+ virtual void apply( QPainter& p );
+ QBrush brush;
+ virtual ~WinObjBrushHandle() {};
+};
+
+class WinObjPenHandle: public WinObjHandle
+{
+public:
+ virtual void apply( QPainter& p );
+ QPen pen;
+ virtual ~WinObjPenHandle() {};
+};
+
+class WinObjPatternBrushHandle: public WinObjHandle
+{
+public:
+ virtual void apply( QPainter& p );
+ QBrush brush;
+ QPixmap image;
+ virtual ~WinObjPatternBrushHandle() {};
+};
+
+class WinObjFontHandle: public WinObjHandle
+{
+public:
+ virtual void apply( QPainter& p );
+ QFont font;
+ int rotation;
+ virtual ~WinObjFontHandle() {};
+};
+
+void WinObjBrushHandle::apply( QPainter& p )
+{
+ p.setBrush( brush );
+}
+
+void WinObjPenHandle::apply( QPainter& p )
+{
+ p.setPen( pen );
+}
+
+void WinObjPatternBrushHandle::apply( QPainter& p )
+{
+ p.setBrush( brush );
+}
+
+void WinObjFontHandle::apply( QPainter& p )
+{
+ p.setFont( font );
+}
+
+#define MAX_OBJHANDLE 64
+
+
+
+//-----------------------------------------------------------------------------
+QWinMetaFile::QWinMetaFile()
+{
+ mValid = false;
+ mFirstCmd = NULL;
+ mObjHandleTab = NULL;
+ mDpi = 1000;
+}
+
+
+//-----------------------------------------------------------------------------
+QWinMetaFile::~QWinMetaFile()
+{
+ if ( mFirstCmd ) delete mFirstCmd;
+ if ( mObjHandleTab ) delete[] mObjHandleTab;
+}
+
+
+//-----------------------------------------------------------------------------
+bool QWinMetaFile::load( const QString &filename )
+{
+ QFile file( filename );
+
+ if ( !file.exists() )
+ {
+ kdDebug() << "File " << QFile::encodeName(filename) << " does not exist" << endl;
+ return false;
+ }
+
+ if ( !file.open( IO_ReadOnly ) )
+ {
+ kdDebug() << "Cannot open file " << QFile::encodeName(filename) << endl;
+ return false;
+ }
+
+ QByteArray ba = file.readAll();
+ file.close();
+
+ QBuffer buffer( ba );
+ buffer.open( IO_ReadOnly );
+ return load( buffer );
+}
+
+//-----------------------------------------------------------------------------
+bool QWinMetaFile::load( QBuffer &buffer )
+{
+ QDataStream st;
+ WmfEnhMetaHeader eheader;
+ WmfMetaHeader header;
+ WmfPlaceableHeader pheader;
+ WORD checksum;
+ int filePos, idx, i;
+ WmfCmd *cmd, *last;
+ DWORD rdSize;
+ WORD rdFunc;
+
+ mTextAlign = 0;
+ mRotation = 0;
+ mTextColor = Qt::black;
+ if ( mFirstCmd ) delete mFirstCmd;
+ mFirstCmd = NULL;
+
+ st.setDevice( &buffer );
+ st.setByteOrder( QDataStream::LittleEndian ); // Great, I love Qt !
+
+ //----- Read placeable metafile header
+ st >> pheader.key;
+ mIsPlaceable = ( pheader.key==( DWORD )APMHEADER_KEY );
+ if ( mIsPlaceable )
+ {
+ st >> pheader.hmf;
+ st >> pheader.bbox.left;
+ st >> pheader.bbox.top;
+ st >> pheader.bbox.right;
+ st >> pheader.bbox.bottom;
+ st >> pheader.inch;
+ st >> pheader.reserved;
+ st >> pheader.checksum;
+ checksum = calcCheckSum( &pheader );
+ if ( pheader.checksum!=checksum ) mIsPlaceable = false;
+
+ mDpi = pheader.inch;
+ mBBox.setLeft( pheader.bbox.left );
+ mBBox.setTop( pheader.bbox.top );
+ mBBox.setRight( pheader.bbox.right );
+ mBBox.setBottom( pheader.bbox.bottom );
+ mHeaderBoundingBox = mBBox;
+ if ( QWMF_DEBUG )
+ {
+ kdDebug() << endl << "-------------------------------------------------" << endl;
+ kdDebug() << "WMF Placeable Header ( " << static_cast<int>(sizeof( pheader ) ) << "):" << endl;
+ kdDebug() << " bbox=( " << mBBox.left() << "; " << mBBox.top() << "; " << mBBox.width()
+ << "; " << mBBox.height() << ")" << endl;
+ kdDebug() << " inch=" << pheader.inch << endl;
+ kdDebug() << " checksum=" << pheader.checksum << "( "
+ << (pheader.checksum==checksum?"ok":"wrong") << " )" << endl;
+ }
+ }
+ else buffer.at( 0 );
+
+ //----- Read as enhanced metafile header
+ filePos = buffer.at();
+ st >> eheader.iType;
+ st >> eheader.nSize;
+ st >> eheader.rclBounds.left;
+ st >> eheader.rclBounds.top;
+ st >> eheader.rclBounds.right;
+ st >> eheader.rclBounds.bottom;
+ st >> eheader.rclFrame.left;
+ st >> eheader.rclFrame.top;
+ st >> eheader.rclFrame.right;
+ st >> eheader.rclFrame.bottom;
+ st >> eheader.dSignature;
+ mIsEnhanced = ( eheader.dSignature==ENHMETA_SIGNATURE );
+ if ( mIsEnhanced ) // is it really enhanced ?
+ {
+ st >> eheader.nVersion;
+ st >> eheader.nBytes;
+ st >> eheader.nRecords;
+ st >> eheader.nHandles;
+ st >> eheader.sReserved;
+ st >> eheader.nDescription;
+ st >> eheader.offDescription;
+ st >> eheader.nPalEntries;
+ st >> eheader.szlDevice.width;
+ st >> eheader.szlDevice.height;
+ st >> eheader.szlMillimeters.width;
+ st >> eheader.szlMillimeters.height;
+
+ if ( QWMF_DEBUG )
+ {
+ kdDebug() << endl << "-------------------------------------------------" << endl;
+ kdDebug() << "WMF Extended Header:" << endl;
+ kdDebug() << " iType=" << eheader.iType << endl;
+ kdDebug() << " nSize=" << eheader.nSize << endl;
+ kdDebug() << " rclBounds=( " << eheader.rclBounds.left << "; " << eheader.rclBounds.top << "; "
+ << eheader.rclBounds.right << "; " << eheader.rclBounds.bottom << ")" << endl;
+ kdDebug() << " rclFrame=( " << eheader.rclFrame.left << "; " << eheader.rclFrame.top << "; "
+ << eheader.rclFrame.right << "; " << eheader.rclFrame.bottom << ")" << endl;
+ kdDebug() << " nBytes=" << eheader.nBytes << endl;
+ kdDebug() << "\nNOT YET IMPLEMENTED, SORRY." << endl;
+ }
+ }
+ else // no, not enhanced
+ {
+ //----- Read as standard metafile header
+ buffer.at( filePos );
+ st >> header.mtType;
+ st >> header.mtHeaderSize;
+ st >> header.mtVersion;
+ st >> header.mtSize;
+ st >> header.mtNoObjects;
+ st >> header.mtMaxRecord;
+ st >> header.mtNoParameters;
+ if ( QWMF_DEBUG ) {
+ kdDebug() << "WMF Header: " << "mtSize=" << header.mtSize << endl;
+ }
+ }
+
+ //----- Test header validity
+ mValid = ((header.mtHeaderSize == 9) && (header.mtNoParameters == 0)) || mIsEnhanced || mIsPlaceable;
+ if ( mValid )
+ {
+ //----- Read Metafile Records
+ last = NULL;
+ rdFunc = -1;
+ while ( !st.eof() && (rdFunc != 0) )
+ {
+ st >> rdSize;
+ st >> rdFunc;
+ idx = findFunc( rdFunc );
+ rdSize -= 3;
+
+ cmd = new WmfCmd;
+ cmd->next = NULL;
+ if ( last ) last->next = cmd;
+ else mFirstCmd = cmd;
+
+ cmd->funcIndex = idx;
+ cmd->numParm = rdSize;
+ cmd->parm = new WORD[ rdSize ];
+ last = cmd;
+
+ for ( i=0; i<rdSize && !st.eof(); i++ )
+ st >> cmd->parm[ i ];
+
+
+ if ( rdFunc == 0x020B ) { // SETWINDOWORG: dimensions
+ mBBox.setLeft( cmd->parm[ 1 ] );
+ mBBox.setTop( cmd->parm[ 0 ] );
+ }
+ if ( rdFunc == 0x020C ) { // SETWINDOWEXT: dimensions
+ mBBox.setWidth( cmd->parm[ 1 ] );
+ mBBox.setHeight( cmd->parm[ 0 ] );
+ }
+
+ if ( i<rdSize )
+ {
+ kdDebug() << "WMF : file truncated !" << endl;
+ return false;
+ }
+ }
+ //----- Test records validities
+ mValid = (rdFunc == 0) && (mBBox.width() != 0) && (mBBox.height() != 0);
+ if ( !mValid ) {
+ kdDebug() << "WMF : incorrect file format !" << endl;
+ }
+ }
+ else {
+ kdDebug() << "WMF Header : incorrect header !" << endl;
+ }
+
+ buffer.close();
+ return mValid;
+}
+
+
+//-----------------------------------------------------------------------------
+bool QWinMetaFile::paint( const QPaintDevice* aTarget, bool absolute )
+{
+ int idx, i;
+ WmfCmd* cmd;
+
+ if ( !mValid ) return false;
+
+ assert( aTarget!=NULL );
+ if ( mPainter.isActive() ) return false;
+
+ if ( mObjHandleTab ) delete[] mObjHandleTab;
+ mObjHandleTab = new WinObjHandle* [ MAX_OBJHANDLE ];
+ for ( i=MAX_OBJHANDLE-1; i>=0; i-- )
+ mObjHandleTab[ i ] = NULL;
+
+ mPainter.resetXForm();
+ mWinding = false;
+ mAbsoluteCoord = absolute;
+
+ mPainter.begin( aTarget );
+ if ( QWMF_DEBUG ) {
+ kdDebug() << "Bounding box : " << mBBox.left()
+ << " " << mBBox.top() << " " << mBBox.right() << " " << mBBox.bottom() << endl;
+ }
+
+ if ( mAbsoluteCoord ) {
+ mPainter.setWindow( mBBox.top(), mBBox.left(), mBBox.width(), mBBox.height() );
+ }
+ mInternalWorldMatrix.reset();
+
+ for ( cmd=mFirstCmd; cmd; cmd=cmd->next )
+ {
+ idx = cmd->funcIndex;
+ ( this->*metaFuncTab[ idx ].method )( cmd->numParm, cmd->parm );
+
+ if ( QWMF_DEBUG ) {
+ QString str = "", param;
+ if ( metaFuncTab[ idx ].name == NULL ) {
+ str += "UNKNOWN ";
+ }
+ if ( metaFuncTab[ idx ].method == &QWinMetaFile::noop ) {
+ str += "UNIMPLEMENTED ";
+ }
+ str += metaFuncTab[ idx ].name;
+ str += " : ";
+
+ for ( i=0 ; i < cmd->numParm ; i++ ) {
+ param.setNum( cmd->parm[ i ] );
+ str += param;
+ str += " ";
+ }
+ kdDebug() << str << endl;
+ }
+ }
+/*
+ // TODO: cleanup this code when QPicture::setBoundingBox() is possible in KOClipart (QT31)
+ // because actually QPicture::boundingBox() != mBBox()
+ mWindowsCoord += 1;
+ if ( mWindowsCoord == 2 ) {
+ kdDebug() << "DRAW ANGLES " << endl;
+ mPainter.setPen( Qt::white );
+ mPainter.drawPoint( mBBox.left(), mBBox.top() );
+ mPainter.drawPoint( mBBox.right(), mBBox.bottom() );
+ }
+*/
+ mPainter.end();
+ return true;
+}
+
+
+//----------------s-------------------------------------------------------------
+// Metafile painter methods
+//-----------------------------------------------------------------------------
+void QWinMetaFile::setWindowOrg( long, short* parm )
+{
+ if ( mAbsoluteCoord ) {
+ QRect r = mPainter.window();
+ mPainter.setWindow( parm[ 1 ], parm[ 0 ], r.width(), r.height() );
+ }
+ else {
+ double dx = mInternalWorldMatrix.dx();
+ double dy = mInternalWorldMatrix.dy();
+
+ mInternalWorldMatrix.translate( -dx, -dy );
+ mInternalWorldMatrix.translate( -parm[ 1 ], -parm[ 0 ] );
+ mPainter.translate( -dx, -dy );
+ mPainter.translate( -parm[ 1 ], -parm[ 0 ] );
+ }
+}
+
+
+//-----------------------------------------------------------------------------
+void QWinMetaFile::setWindowExt( long, short* parm )
+{
+ // negative value allowed for width and height : QABS() forbidden
+ if ( mAbsoluteCoord ) {
+ QRect r = mPainter.window();
+ mPainter.setWindow( r.left(), r.top(), parm[ 1 ], parm[ 0 ] );
+ }
+ else {
+ if ( (parm[ 0 ] != 0) && (parm[ 1 ] != 0) ) {
+ QRect r = mPainter.window();
+ double dx = mInternalWorldMatrix.dx();
+ double dy = mInternalWorldMatrix.dy();
+ double sx = mInternalWorldMatrix.m11();
+ double sy = mInternalWorldMatrix.m22();
+
+ mInternalWorldMatrix.translate( -dx, -dy );
+ mInternalWorldMatrix.scale( 1/sx, 1/sy );
+ mPainter.translate( -dx, -dy );
+ mPainter.scale( 1/sx, 1/sy );
+
+ sx = (double)r.width() / (double)parm[ 1 ];
+ sy = (double)r.height() / (double)parm[ 0 ];
+
+ mInternalWorldMatrix.scale( sx, sy );
+ mInternalWorldMatrix.translate( dx, dy );
+ mPainter.scale( sx, sy );
+ mPainter.translate( dx, dy );
+ }
+ }
+}
+
+
+//-----------------------------------------------------------------------------
+// Drawing
+//-----------------------------------------------------------------------------
+void QWinMetaFile::lineTo( long, short* parm )
+{
+ mPainter.lineTo( parm[ 1 ], parm[ 0 ] );
+}
+
+
+//-----------------------------------------------------------------------------
+void QWinMetaFile::moveTo( long, short* parm )
+{
+ mPainter.moveTo( parm[ 1 ], parm[ 0 ] );
+}
+
+
+//-----------------------------------------------------------------------------
+void QWinMetaFile::ellipse( long, short* parm )
+{
+ mPainter.drawEllipse( parm[ 3 ], parm[ 2 ], parm[ 1 ]-parm[ 3 ], parm[ 0 ]-parm[ 2 ] );
+}
+
+
+//-----------------------------------------------------------------------------
+void QWinMetaFile::polygon( long, short* parm )
+{
+ QPointArray* pa;
+
+ pa = pointArray( parm[ 0 ], &parm[ 1 ] );
+ mPainter.drawPolygon( *pa, mWinding );
+}
+
+
+//-----------------------------------------------------------------------------
+void QWinMetaFile::polyPolygon( long, short* parm )
+{
+ QRegion region;
+ int i, j, startPolygon;
+
+ mPainter.save();
+
+ // define clipping region
+ QRect win = bbox();
+ startPolygon = 1+parm[ 0 ];
+ for ( i=0 ; i < parm[ 0 ] ; i++ ) {
+ QPointArray pa1( parm[ 1+i ] );
+ for ( j=0 ; j < parm[ 1+i ] ; j++) {
+ pa1.setPoint ( j, parm[ startPolygon ], parm[ startPolygon+1 ] );
+ startPolygon += 2;
+ }
+ QRegion r( pa1 );
+ region = region.eor( r );
+ }
+ mPainter.setClipRegion( region, QPainter::CoordPainter );
+
+ // fill polygons
+ mPainter.fillRect( win.left(), win.top(), win.width(), win.height(), mPainter.brush() );
+
+ // draw polygon's border if necessary
+ if ( mPainter.pen().style() != Qt::NoPen ) {
+ mPainter.setClipping( false );
+ mPainter.setBrush( Qt::NoBrush );
+
+ QPointArray* pa;
+ int idxPolygon = 1 + parm[ 0 ];
+ for ( i=0 ; i < parm[ 0 ] ; i++ ) {
+ pa = pointArray( parm[ 1+i ], &parm[ idxPolygon ] );
+ mPainter.drawPolygon( *pa );
+ idxPolygon += parm[ 1+i ] * 2;
+ }
+ }
+
+ mPainter.restore();
+}
+
+
+//-----------------------------------------------------------------------------
+void QWinMetaFile::polyline( long, short* parm )
+{
+ QPointArray* pa;
+
+ pa = pointArray( parm[ 0 ], &parm[ 1 ] );
+ mPainter.drawPolyline( *pa );
+}
+
+
+//-----------------------------------------------------------------------------
+void QWinMetaFile::rectangle( long, short* parm )
+{
+ mPainter.drawRect( parm[ 3 ], parm[ 2 ], parm[ 1 ]-parm[ 3 ], parm[ 0 ]-parm[ 2 ] );
+}
+
+
+//-----------------------------------------------------------------------------
+void QWinMetaFile::roundRect( long, short* parm )
+{
+ int xRnd = 0, yRnd = 0;
+
+ // convert (xRound, yRound) in percentage
+ if ( (parm[ 3 ] - parm[ 5 ]) != 0 )
+ xRnd = (parm[ 1 ] * 100) / (parm[ 3 ] - parm[ 5 ]) ;
+ if ( (parm[ 2 ] - parm[ 4 ]) != 0 )
+ yRnd = (parm[ 0 ] * 100) / (parm[ 2 ] - parm[ 4 ]) ;
+
+ mPainter.drawRoundRect( parm[ 5 ], parm[ 4 ], parm[ 3 ]-parm[ 5 ], parm[ 2 ]-parm[ 4 ], xRnd, yRnd );
+}
+
+
+//-----------------------------------------------------------------------------
+void QWinMetaFile::arc( long, short* parm )
+{
+ int xCenter, yCenter, angleStart, aLength;
+
+ xCenter = parm[ 7 ] + ((parm[ 5 ] - parm[ 7 ]) / 2);
+ yCenter = parm[ 6 ] + ((parm[ 4 ] - parm[ 6 ]) / 2);
+
+ xyToAngle ( parm[ 3 ] - xCenter, yCenter - parm[ 2 ], parm[ 1 ] - xCenter, yCenter - parm[ 0 ], angleStart, aLength );
+
+ mPainter.drawArc( parm[ 7 ], parm[ 6 ], parm[ 5 ]-parm[ 7 ], parm[ 4 ]-parm[ 6 ], angleStart, aLength);
+}
+
+
+//-----------------------------------------------------------------------------
+void QWinMetaFile::chord( long, short* parm )
+{
+ int xCenter, yCenter, angleStart, aLength;
+
+ xCenter = parm[ 7 ] + ((parm[ 5 ] - parm[ 7 ]) / 2);
+ yCenter = parm[ 6 ] + ((parm[ 4 ] - parm[ 6 ]) / 2);
+
+ xyToAngle ( parm[ 3 ] - xCenter, yCenter - parm[ 2 ], parm[ 1 ] - xCenter, yCenter - parm[ 0 ], angleStart, aLength );
+
+ mPainter.drawChord( parm[ 7 ], parm[ 6 ], parm[ 5 ]-parm[ 7 ], parm[ 4 ]-parm[ 6 ], angleStart, aLength);
+}
+
+
+//-----------------------------------------------------------------------------
+void QWinMetaFile::pie( long, short* parm )
+{
+ int xCenter, yCenter, angleStart, aLength;
+
+ xCenter = parm[ 7 ] + ((parm[ 5 ] - parm[ 7 ]) / 2);
+ yCenter = parm[ 6 ] + ((parm[ 4 ] - parm[ 6 ]) / 2);
+
+ xyToAngle ( parm[ 3 ] - xCenter, yCenter - parm[ 2 ], parm[ 1 ] - xCenter, yCenter - parm[ 0 ], angleStart, aLength );
+
+ mPainter.drawPie( parm[ 7 ], parm[ 6 ], parm[ 5 ]-parm[ 7 ], parm[ 4 ]-parm[ 6 ], angleStart, aLength);
+}
+
+
+//-----------------------------------------------------------------------------
+void QWinMetaFile::setPolyFillMode( long, short* parm )
+{
+ mWinding = parm[ 0 ];
+}
+
+
+//-----------------------------------------------------------------------------
+void QWinMetaFile::setBkColor( long, short* parm )
+{
+ mPainter.setBackgroundColor( color( parm ) );
+}
+
+
+//-----------------------------------------------------------------------------
+void QWinMetaFile::setBkMode( long, short* parm )
+{
+ if ( parm[ 0 ]==1 ) mPainter.setBackgroundMode( Qt::TransparentMode );
+ else mPainter.setBackgroundMode( Qt::OpaqueMode );
+}
+
+
+//-----------------------------------------------------------------------------
+void QWinMetaFile::setPixel( long, short* parm )
+{
+ QPen pen = mPainter.pen();
+ mPainter.setPen( color( parm ) );
+ mPainter.drawPoint( parm[ 3 ], parm[ 2 ] );
+ mPainter.setPen( pen );
+}
+
+
+//-----------------------------------------------------------------------------
+void QWinMetaFile::setRop( long, short* parm )
+{
+ mPainter.setRasterOp( winToQtRaster( parm[ 0 ] ) );
+}
+
+
+//-----------------------------------------------------------------------------
+void QWinMetaFile::saveDC( long, short* )
+{
+ mPainter.save();
+}
+
+
+//-----------------------------------------------------------------------------
+void QWinMetaFile::restoreDC( long, short *parm )
+{
+ for ( int i=0; i > parm[ 0 ] ; i-- )
+ mPainter.restore();
+}
+
+
+//-----------------------------------------------------------------------------
+void QWinMetaFile::intersectClipRect( long, short* parm )
+{
+/* TODO: better implementation : need QT 3.0.2
+ QRegion region = mPainter.clipRegion();
+ if ( region.isEmpty() )
+ region = bbox();
+*/
+ QRegion region( bbox() );
+
+ QRegion newRegion( parm[ 3 ], parm[ 2 ], parm[ 1 ] - parm[ 3 ], parm[ 0 ] - parm[ 2 ] );
+ region = region.intersect( newRegion );
+
+ mPainter.setClipRegion( region, QPainter::CoordPainter );
+}
+
+
+//-----------------------------------------------------------------------------
+void QWinMetaFile::excludeClipRect( long, short* parm )
+{
+/* TODO: better implementation : need QT 3.0.2
+ QRegion region = mPainter.clipRegion();
+ if ( region.isEmpty() )
+ region = bbox();
+*/
+ QRegion region( bbox() );
+
+ QRegion newRegion( parm[ 3 ], parm[ 2 ], parm[ 1 ] - parm[ 3 ], parm[ 0 ] - parm[ 2 ] );
+ region = region.subtract( newRegion );
+
+ mPainter.setClipRegion( region, QPainter::CoordPainter );
+}
+
+
+//-----------------------------------------------------------------------------
+// Text
+//-----------------------------------------------------------------------------
+void QWinMetaFile::setTextColor( long, short* parm )
+{
+ mTextColor = color( parm );
+}
+
+
+//-----------------------------------------------------------------------------
+void QWinMetaFile::setTextAlign( long, short* parm )
+{
+ mTextAlign = parm[ 0 ];
+}
+
+
+//-----------------------------------------------------------------------------
+void QWinMetaFile::textOut( long num, short* parm )
+{
+
+ short *copyParm = new short[ num + 1 ];
+
+ // re-order parameters
+ int idxOffset = (parm[ 0 ] / 2) + 1 + (parm[ 0 ] & 1);
+ copyParm[ 0 ] = parm[ idxOffset ];
+ copyParm[ 1 ] = parm[ idxOffset + 1 ];
+ copyParm[ 2 ] = parm[ 0 ];
+ copyParm[ 3 ] = 0;
+ memcpy( &copyParm[ 4 ], &parm[ 1 ], parm[ 0 ] );
+
+ extTextOut( num + 1, copyParm );
+ delete [] copyParm;
+}
+
+
+//-----------------------------------------------------------------------------
+void QWinMetaFile::extTextOut( long num, short* parm )
+{
+ char* ptStr;
+ int x, y, width, height;
+ int idxOffset;
+
+ if ( parm[ 3 ] != 0 ) // ETO_CLIPPED flag add 4 parameters
+ ptStr = (char*)&parm[ 8 ];
+ else
+ ptStr = (char*)&parm[ 4 ];
+
+ QCString text( ptStr, parm[ 2 ] + 1 );
+
+ QFontMetrics fm( mPainter.font() );
+ width = fm.width( text ) + fm.descent(); // because fm.width(text) isn't rigth with Italic text
+ height = fm.height();
+
+ mPainter.save();
+
+ if ( mTextAlign & 0x01 ) { // (left, top) position = current logical position
+ QPoint pos = mPainter.pos();
+ x = pos.x();
+ y = pos.y();
+ }
+ else { // (left, top) position = parameters
+ x = parm[ 1 ];
+ y = parm[ 0 ];
+ }
+
+ if ( mRotation ) {
+ mPainter.translate( parm[ 1 ], parm[ 0 ]);
+ mPainter.rotate ( mRotation );
+ mPainter.translate( -parm[ 1 ], -parm[ 0 ] );
+ }
+
+ // alignment
+ if ( mTextAlign & 0x06 )
+ x -= ( width / 2 );
+ if ( mTextAlign & 0x08 )
+ y -= (height - fm.descent());
+
+ mPainter.setPen( mTextColor );
+ idxOffset = (parm[ 2 ] / 2) + 4 + (parm[ 2 ] & 1);
+ if ( ( parm[ 2 ] > 1 ) && ( num >= (idxOffset + parm[ 2 ]) ) && ( parm[ 3 ] == 0 ) ) {
+ // offset for each char
+ int left = x;
+ mPainter.drawText( left, y, width, height, Qt::AlignLeft | Qt::AlignTop, text.mid(0, 1) );
+ for ( int i = 1; i < parm[ 2 ] ; i++ ) {
+ left += parm[ idxOffset + i - 1 ];
+ mPainter.drawText( left, y, width, height, Qt::AlignLeft | Qt::AlignTop, text.mid(i, 1) );
+ }
+ }
+ else {
+ mPainter.drawText( x, y, width, height, Qt::AlignLeft | Qt::AlignTop, text );
+ }
+
+ mPainter.restore();
+
+}
+
+
+
+//-----------------------------------------------------------------------------
+// Bitmap
+//-----------------------------------------------------------------------------
+void QWinMetaFile::dibBitBlt( long num, short* parm )
+{
+ if ( num > 9 ) { // DIB image
+ QImage bmpSrc;
+
+ if ( dibToBmp( bmpSrc, (char*)&parm[ 8 ], (num - 8) * 2 ) ) {
+ long raster = toDWord( parm );
+
+ mPainter.setRasterOp( winToQtRaster( raster ) );
+
+ // wmf file allow negative width or height
+ mPainter.save();
+ if ( parm[ 5 ] < 0 ) { // width < 0 => horizontal flip
+ QWMatrix m( -1.0F, 0.0F, 0.0F, 1.0F, 0.0F, 0.0F );
+ mPainter.setWorldMatrix( m, true );
+ }
+ if ( parm[ 4 ] < 0 ) { // height < 0 => vertical flip
+ QWMatrix m( 1.0F, 0.0F, 0.0F, -1.0F, 0.0F, 0.0F );
+ mPainter.setWorldMatrix( m, true );
+ }
+ mPainter.drawImage( parm[ 7 ], parm[ 6 ], bmpSrc, parm[ 3 ], parm[ 2 ], parm[ 5 ], parm[ 4 ] );
+ mPainter.restore();
+ }
+ }
+ else {
+ kdDebug() << "QWinMetaFile::dibBitBlt without image: not implemented " << endl;
+ }
+}
+
+
+//-----------------------------------------------------------------------------
+void QWinMetaFile::dibStretchBlt( long num, short* parm )
+{
+ QImage bmpSrc;
+
+ if ( dibToBmp( bmpSrc, (char*)&parm[ 10 ], (num - 10) * 2 ) ) {
+ long raster = toDWord( parm );
+
+ mPainter.setRasterOp( winToQtRaster( raster ) );
+
+ // wmf file allow negative width or height
+ mPainter.save();
+ if ( parm[ 7 ] < 0 ) { // width < 0 => horizontal flip
+ QWMatrix m( -1.0F, 0.0F, 0.0F, 1.0F, 0.0F, 0.0F );
+ mPainter.setWorldMatrix( m, true );
+ }
+ if ( parm[ 6 ] < 0 ) { // height < 0 => vertical flip
+ QWMatrix m( 1.0F, 0.0F, 0.0F, -1.0F, 0.0F, 0.0F );
+ mPainter.setWorldMatrix( m, true );
+ }
+ bmpSrc = bmpSrc.copy( parm[ 5 ], parm[ 4 ], parm[ 3 ], parm[ 2 ] );
+ // TODO: scale the bitmap ( QImage::scale(parm[ 7 ], parm[ 6 ]) is actually too slow )
+
+ mPainter.drawImage( parm[ 9 ], parm[ 8 ], bmpSrc );
+ mPainter.restore();
+ }
+}
+
+
+//-----------------------------------------------------------------------------
+void QWinMetaFile::stretchDib( long num, short* parm )
+{
+ QImage bmpSrc;
+
+ if ( dibToBmp( bmpSrc, (char*)&parm[ 11 ], (num - 11) * 2 ) ) {
+ long raster = toDWord( parm );
+
+ mPainter.setRasterOp( winToQtRaster( raster ) );
+
+ // wmf file allow negative width or height
+ mPainter.save();
+ if ( parm[ 8 ] < 0 ) { // width < 0 => horizontal flip
+ QWMatrix m( -1.0F, 0.0F, 0.0F, 1.0F, 0.0F, 0.0F );
+ mPainter.setWorldMatrix( m, true );
+ }
+ if ( parm[ 7 ] < 0 ) { // height < 0 => vertical flip
+ QWMatrix m( 1.0F, 0.0F, 0.0F, -1.0F, 0.0F, 0.0F );
+ mPainter.setWorldMatrix( m, true );
+ }
+ bmpSrc = bmpSrc.copy( parm[ 6 ], parm[ 5 ], parm[ 4 ], parm[ 3 ] );
+ // TODO: scale the bitmap ( QImage::scale(parm[ 8 ], parm[ 7 ]) is actually too slow )
+
+ mPainter.drawImage( parm[ 10 ], parm[ 9 ], bmpSrc );
+ mPainter.restore();
+ }
+}
+
+
+//-----------------------------------------------------------------------------
+void QWinMetaFile::dibCreatePatternBrush( long num, short* parm )
+{
+ WinObjPatternBrushHandle* handle = new WinObjPatternBrushHandle;
+ addHandle( handle );
+ QImage bmpSrc;
+
+ if ( dibToBmp( bmpSrc, (char*)&parm[ 2 ], (num - 2) * 2 ) ) {
+ handle->image = bmpSrc;
+ handle->brush.setPixmap( handle->image );
+ }
+}
+
+
+//-----------------------------------------------------------------------------
+// Object handle
+//-----------------------------------------------------------------------------
+void QWinMetaFile::selectObject( long, short* parm )
+{
+ int idx = parm[ 0 ];
+ if ( idx>=0 && idx < MAX_OBJHANDLE && mObjHandleTab[ idx ] )
+ mObjHandleTab[ idx ]->apply( mPainter );
+}
+
+
+//-----------------------------------------------------------------------------
+void QWinMetaFile::deleteObject( long, short* parm )
+{
+ deleteHandle( parm[ 0 ] );
+}
+
+
+//-----------------------------------------------------------------------------
+void QWinMetaFile::createEmptyObject( long, short* )
+{
+ // allocation of an empty object (to keep object counting in sync)
+ WinObjPenHandle* handle = new WinObjPenHandle;
+ addHandle( handle );
+ kdDebug() << "QWinMetaFile: unimplemented createObject " << endl;
+}
+
+
+//-----------------------------------------------------------------------------
+void QWinMetaFile::createBrushIndirect( long, short* parm )
+{
+ static Qt::BrushStyle hatchedStyleTab[] =
+ {
+ Qt::HorPattern,
+ Qt::FDiagPattern,
+ Qt::BDiagPattern,
+ Qt::CrossPattern,
+ Qt::DiagCrossPattern
+ };
+ static Qt::BrushStyle styleTab[] =
+ { Qt::SolidPattern,
+ Qt::NoBrush,
+ Qt::FDiagPattern, /* hatched */
+ Qt::Dense4Pattern, /* should be custom bitmap pattern */
+ Qt::HorPattern, /* should be BS_INDEXED (?) */
+ Qt::VerPattern, /* should be device-independent bitmap */
+ Qt::Dense6Pattern, /* should be device-independent packed-bitmap */
+ Qt::Dense2Pattern, /* should be BS_PATTERN8x8 */
+ Qt::Dense3Pattern /* should be device-independent BS_DIBPATTERN8x8 */
+ };
+ Qt::BrushStyle style;
+ short arg;
+ WinObjBrushHandle* handle = new WinObjBrushHandle;
+ addHandle( handle );
+
+ arg = parm[ 0 ];
+ if ( arg==2 )
+ {
+ arg = parm[ 3 ];
+ if ( arg>=0 && arg<5 ) style = hatchedStyleTab[ arg ];
+ else
+ {
+ kdDebug() << "QWinMetaFile::createBrushIndirect: invalid hatched brush " << arg << endl;
+ style = Qt::SolidPattern;
+ }
+ }
+ else if ( arg>=0 && arg<9 )
+ style = styleTab[ arg ];
+ else
+ {
+ kdDebug() << "QWinMetaFile::createBrushIndirect: invalid brush " << arg << endl;
+ style = Qt::SolidPattern;
+ }
+ handle->brush.setStyle( style );
+ handle->brush.setColor( color( parm+1 ) );
+}
+
+
+//-----------------------------------------------------------------------------
+void QWinMetaFile::createPenIndirect( long, short* parm )
+{
+ static Qt::PenStyle styleTab[] =
+ { Qt::SolidLine, Qt::DashLine, Qt::DotLine, Qt::DashDotLine, Qt::DashDotDotLine,
+ Qt::NoPen, Qt::SolidLine };
+ Qt::PenStyle style;
+ WinObjPenHandle* handle = new WinObjPenHandle;
+ addHandle( handle );
+
+ if ( parm[ 0 ]>=0 && parm[ 0 ]<6 ) style=styleTab[ parm[ 0 ] ];
+ else
+ {
+ kdDebug() << "QWinMetaFile::createPenIndirect: invalid pen " << parm[ 0 ] << endl;
+ style = Qt::SolidLine;
+ }
+
+ handle->pen.setStyle( style );
+ handle->pen.setColor( color( parm+3 ) );
+ handle->pen.setCapStyle( Qt::RoundCap );
+
+ //int width = 0;
+ // TODO : width of pen proportional to device context width
+ // DOESN'T WORK
+/*
+ QRect devRec;
+ devRec = mPainter.xForm( mBBox );
+ width = ( parm[ 0 ] * devRec.width() ) / mBBox.width() ;
+ kdDebug() << "CreatePenIndirect: " << endl;
+ kdDebug() << " log coord. : " << mBBox.width() << " " << mBBox.height() << endl;
+ kdDebug() << " log. pen : " << parm[ 1 ] << " " << parm[ 2 ] << endl;
+ kdDebug() << " dev. pen : " << width << endl;
+ handle->pen.setWidth( width );
+*/
+}
+
+
+//-----------------------------------------------------------------------------
+void QWinMetaFile::createFontIndirect( long , short* parm)
+{
+ WinObjFontHandle* handle = new WinObjFontHandle;
+ addHandle( handle );
+
+ QString family( (const char*)&parm[ 9 ] );
+
+ mRotation = -parm[ 2 ] / 10; // text rotation (in 1/10 degree)
+ // TODO: memorisation of rotation in object Font
+ handle->font.setFamily( family );
+ handle->font.setFixedPitch( ((parm[ 8 ] & 0x01) == 0) );
+ // TODO: investigation why some test case need -2. (size of font in logical point)
+ handle->font.setPointSize( QABS(parm[ 0 ]) - 2 );
+ handle->font.setWeight( (parm[ 4 ] >> 3) );
+ handle->font.setItalic( (parm[ 5 ] & 0x01) );
+ handle->font.setUnderline( (parm[ 5 ] & 0x100) );
+}
+
+
+//-----------------------------------------------------------------------------
+// Misc
+//-----------------------------------------------------------------------------
+void QWinMetaFile::noop( long, short* )
+{
+}
+
+
+void QWinMetaFile::end( long, short* )
+{
+ // end of file :
+// kdDebug() << "END bbox=( " << mBBox.left() << "; " << mBBox.top() << "; " << mBBox.width() << "; " << mBBox.height() << ")" << endl;
+}
+
+
+//-----------------------------------------------------------------------------
+unsigned short QWinMetaFile::calcCheckSum( WmfPlaceableHeader* apmfh )
+{
+ WORD* lpWord;
+ WORD wResult, i;
+
+ // Start with the first word
+ wResult = *( lpWord = ( WORD* )( apmfh ) );
+ // XOR in each of the other 9 words
+ for( i=1; i<=9; i++ )
+ {
+ wResult ^= lpWord[ i ];
+ }
+ return wResult;
+}
+
+
+//-----------------------------------------------------------------------------
+int QWinMetaFile::findFunc( unsigned short aFunc ) const
+{
+ int i;
+
+ for ( i=0; metaFuncTab[ i ].name; i++ )
+ if ( metaFuncTab[ i ].func == aFunc ) return i;
+
+ // here : unknown function
+ return i;
+}
+
+//-----------------------------------------------------------------------------
+QPointArray* QWinMetaFile::pointArray( short num, short* parm )
+{
+ int i;
+
+ mPoints.resize( num );
+
+ for ( i=0; i<num; i++, parm+=2 )
+ mPoints.setPoint( i, parm[ 0 ], parm[ 1 ] );
+
+ return &mPoints;
+}
+
+//-----------------------------------------------------------------------------
+unsigned int QWinMetaFile::toDWord( short* parm )
+{
+ unsigned int l;
+
+#if !defined( WORDS_BIGENDIAN )
+ l = *( unsigned int* )( parm );
+#else
+ char *bytes;
+ char swap[ 4 ];
+ bytes = ( char* )parm;
+ swap[ 0 ] = bytes[ 2 ];
+ swap[ 1 ] = bytes[ 3 ];
+ swap[ 2 ] = bytes[ 0 ];
+ swap[ 3 ] = bytes[ 1 ];
+ l = *( unsigned int* )( swap );
+#endif
+
+ return l;
+}
+
+
+//-----------------------------------------------------------------------------
+QColor QWinMetaFile::color( short* parm )
+{
+ unsigned int colorRef;
+ int red, green, blue;
+
+ colorRef = toDWord( parm ) & 0xffffff;
+ red = colorRef & 255;
+ green = ( colorRef>>8 ) & 255;
+ blue = ( colorRef>>16 ) & 255;
+
+ return QColor( red, green, blue );
+}
+
+
+//-----------------------------------------------------------------------------
+void QWinMetaFile::xyToAngle( int xStart, int yStart, int xEnd, int yEnd, int& angleStart, int& angleLength )
+{
+ float aStart, aLength;
+
+ aStart = atan2( double(yStart), double(xStart) );
+ aLength = atan2( double(yEnd), double(xEnd) ) - aStart;
+
+ angleStart = (int)(aStart * 2880 / 3.14166);
+ angleLength = (int)(aLength * 2880 / 3.14166);
+ if ( angleLength < 0 ) angleLength = 5760 + angleLength;
+}
+
+
+//-----------------------------------------------------------------------------
+void QWinMetaFile::addHandle( WinObjHandle* handle )
+{
+ int idx;
+
+ for ( idx=0; idx < MAX_OBJHANDLE ; idx++ )
+ if ( mObjHandleTab[ idx ] == NULL ) break;
+
+ if ( idx < MAX_OBJHANDLE )
+ mObjHandleTab[ idx ] = handle;
+ else
+ kdDebug() << "QWinMetaFile error: handle table full !" << endl;
+}
+
+//-----------------------------------------------------------------------------
+void QWinMetaFile::deleteHandle( int idx )
+{
+ if ( idx >= 0 && idx < MAX_OBJHANDLE && mObjHandleTab[ idx ] )
+ {
+ delete mObjHandleTab[ idx ];
+ mObjHandleTab[ idx ] = NULL;
+ }
+}
+
+//-----------------------------------------------------------------------------
+Qt::RasterOp QWinMetaFile::winToQtRaster( short parm ) const
+{
+ static const Qt::RasterOp opTab[] =
+ {
+ Qt::CopyROP,
+ Qt::ClearROP, Qt::NandROP, Qt::NotAndROP, Qt::NotCopyROP,
+ Qt::AndNotROP, Qt::NotROP, Qt::XorROP, Qt::NorROP,
+ Qt::AndROP, Qt::NotXorROP, Qt::NopROP, Qt::NotOrROP,
+ Qt::CopyROP, Qt::OrNotROP, Qt::OrROP, Qt::SetROP
+ };
+
+ if ( parm > 0 && parm <= 16 )
+ return opTab[ parm ];
+ else
+ return Qt::CopyROP;
+}
+
+//-----------------------------------------------------------------------------
+Qt::RasterOp QWinMetaFile::winToQtRaster( long parm ) const
+{
+ /* TODO: Ternary raster operations
+ 0x00C000CA dest = (source AND pattern)
+ 0x00F00021 dest = pattern
+ 0x00FB0A09 dest = DPSnoo
+ 0x005A0049 dest = pattern XOR dest */
+ static const struct OpTab
+ {
+ long winRasterOp;
+ Qt::RasterOp qtRasterOp;
+ } opTab[] =
+ {
+ { 0x00CC0020, Qt::CopyROP },
+ { 0x00EE0086, Qt::OrROP },
+ { 0x008800C6, Qt::AndROP },
+ { 0x00660046, Qt::XorROP },
+ { 0x00440328, Qt::AndNotROP },
+ { 0x00330008, Qt::NotCopyROP },
+ { 0x001100A6, Qt::NandROP },
+ { 0x00C000CA, Qt::CopyROP },
+ { 0x00BB0226, Qt::NotOrROP },
+ { 0x00F00021, Qt::CopyROP },
+ { 0x00FB0A09, Qt::CopyROP },
+ { 0x005A0049, Qt::CopyROP },
+ { 0x00550009, Qt::NotROP },
+ { 0x00000042, Qt::ClearROP },
+ { 0x00FF0062, Qt::SetROP }
+ };
+
+ int i;
+ for ( i=0 ; i < 15 ; i++ )
+ if ( opTab[ i ].winRasterOp == parm )
+ break;
+
+ if ( i < 15 )
+ return opTab[ i ].qtRasterOp;
+ else
+ return Qt::CopyROP;
+}
+
+//-----------------------------------------------------------------------------
+bool QWinMetaFile::dibToBmp( QImage& bmp, const char* dib, long size )
+{
+ typedef struct _BMPFILEHEADER {
+ WORD bmType;
+ DWORD bmSize;
+ WORD bmReserved1;
+ WORD bmReserved2;
+ DWORD bmOffBits;
+ } BMPFILEHEADER;
+
+ int sizeBmp = size + 14;
+
+ QByteArray pattern( sizeBmp ); // BMP header and DIB data
+ pattern.fill(0);
+ memcpy( &pattern[ 14 ], dib, size );
+
+ // add BMP header
+ BMPFILEHEADER* bmpHeader;
+ bmpHeader = (BMPFILEHEADER*)((const char*)pattern);
+ bmpHeader->bmType = 0x4D42;
+ bmpHeader->bmSize = sizeBmp;
+
+ if ( !bmp.loadFromData( (const uchar*)bmpHeader, pattern.size(), "BMP" ) ) {
+ kdDebug() << "QWinMetaFile::dibToBmp: invalid bitmap " << endl;
+ return false;
+ }
+ else {
+// if ( bmp.save("/home/software/kde-cvs/qt/examples/wmf/test.bmp", "BMP") )
+// if ( bmp.load( "/home/software/kde-cvs/qt/examples/wmf/test.bmp", "BMP" ) )
+// fprintf(stderr, "Bitmap ok \n");
+ return true;
+ }
+}
+
diff --git a/ktnef/gui/qwmf.h b/ktnef/gui/qwmf.h
new file mode 100644
index 00000000..b655a3fd
--- /dev/null
+++ b/ktnef/gui/qwmf.h
@@ -0,0 +1,228 @@
+/* Windows Meta File Loader
+ *
+ * Copyright ( C ) 1998 Stefan Taferner
+ * Modified 2002 thierry lorthiois
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or ( at your
+ * option ) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABLILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details. You should have received a copy
+ * of the GNU General Public License along with this program; if not, write
+ * to the Free Software Foundation, Inc, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+ * USA.
+ */
+#ifndef qwmf_h
+#define qwmf_h
+
+#include <qstring.h>
+#include <qpainter.h>
+#include <qwmatrix.h>
+#include <qpointarray.h>
+#include <qpen.h>
+#include <qcolor.h>
+#include <qimage.h>
+#include <qrect.h>
+
+class QBuffer;
+class QString;
+class WmfCmd;
+class WinObjHandle;
+class WinObjPenHandle;
+class WinObjBrushHandle;
+struct WmfPlaceableHeader;
+
+/**
+ * QWinMetaFile is a WMF viewer based on QT toolkit
+ * How to use QWinMetaFile :
+ *#include "qwmf.h"
+ * QWinMetaFile wmf;
+ * QPicture pic; // or QImage pic;
+ * if ( wmf.load( filename )
+ * wmf.paint( &pic );
+ */
+
+
+class QWinMetaFile
+{
+public:
+ QWinMetaFile();
+ virtual ~QWinMetaFile();
+
+ /**
+ * Load WMF file. Returns true on success.
+ */
+ virtual bool load( const QString &fileName );
+ virtual bool load( QBuffer &buffer );
+
+ /**
+ * Paint metafile to given paint-device using absolute or relative coordinate.
+ * abosute coord. reset the world transfomation Matrix
+ * relative coord. use the existing world transfomation Matrix
+ * Returns true on success.
+ */
+ virtual bool paint( const QPaintDevice* target, bool absolute=false );
+
+ /**
+ * Returns true if the metafile is placeable.
+ */
+ bool isPlaceable( void ) const { return mIsPlaceable; }
+
+ /**
+ * Returns true if the metafile is enhanced.
+ */
+ bool isEnhanced( void ) const { return mIsEnhanced; }
+
+ /**
+ * Returns bounding rectangle
+ */
+ QRect bbox( void ) const { return mBBox; }
+ void setBbox( QRect r ) { mBBox = r; }
+
+public: // should be protected but cannot
+ /** Metafile painter methods */
+
+ // set window origin
+ void setWindowOrg( long num, short* parms );
+ // set window extents
+ void setWindowExt( long num, short* parms );
+
+ /****************** Drawing *******************/
+ // draw line to coord
+ void lineTo( long num, short* parms );
+ // move pen to coord
+ void moveTo( long num, short* parms );
+ // draw ellipse
+ void ellipse( long num, short* parms );
+ // draw polygon
+ void polygon( long num, short* parms );
+ /* draw a list of polygons */
+ void polyPolygon( long num, short* parms );
+ // draw series of lines
+ void polyline( long num, short* parms );
+ /* draw a rectangle */
+ void rectangle( long num, short* parms );
+ /* draw round rectangle */
+ void roundRect( long num, short* parms );
+ /* draw arc */
+ void arc( long num, short* parms );
+ /* draw chord */
+ void chord( long num, short* parms );
+ /* draw pie */
+ void pie( long num, short* parms );
+ // set polygon fill mode
+ void setPolyFillMode( long num, short* parms );
+ // set background pen color
+ void setBkColor( long num, short* parms );
+ // set background pen mode
+ void setBkMode( long num, short* parms );
+ /* set a pixel */
+ void setPixel( long num, short* parms );
+ // Set raster operation mode
+ void setRop( long num, short* parms );
+ /* save device context */
+ void saveDC( long num, short* parms );
+ /* restore device context */
+ void restoreDC( long num, short* parms );
+ /* clipping region is the intersection of this region and the original region */
+ void intersectClipRect( long num, short* parms );
+ /* delete a clipping rectangle of the original region */
+ void excludeClipRect( long num, short* parms );
+
+ /****************** Text *******************/
+ /* set text color */
+ void setTextColor( long num, short* parms );
+ /* set text alignment */
+ void setTextAlign( long num, short* parms );
+ /* draw text */
+ void textOut( long num, short* parms );
+ void extTextOut( long num, short* parms );
+
+ /****************** Bitmap *******************/
+ /* copies a DIB into a dest location */
+ void dibBitBlt( long num, short* parms );
+ /* stretches a DIB into a dest location */
+ void dibStretchBlt( long num, short* parms );
+ void stretchDib( long num, short* parms );
+ /* create a pattern brush */
+ void dibCreatePatternBrush( long num, short* parms );
+
+ /****************** Object handle *******************/
+ // Activate object handle
+ void selectObject( long num, short* parms );
+ // Free object handle
+ void deleteObject( long num, short* parms );
+ /* create an empty object in the object list */
+ void createEmptyObject( long num, short* parms );
+ // create a logical brush
+ void createBrushIndirect( long num, short* parms );
+ // create a logical pen
+ void createPenIndirect( long num, short* parms );
+ /* create a logical font */
+ void createFontIndirect( long num, short* parms );
+
+ /****************** misc *******************/
+ // nothing to do
+ void noop( long , short* );
+ // end of meta file
+ void end( long /*num*/, short* /*parms*/ );
+ // Resolution of the image in dots per inch
+ int dpi( void ) const { return mDpi; }
+
+protected:
+ /** Calculate header checksum */
+ unsigned short calcCheckSum( WmfPlaceableHeader* );
+
+ /** Find function in metafunc table by metafile-function.
+ Returns index or -1 if not found. */
+ virtual int findFunc( unsigned short aFunc ) const;
+
+ /** Fills given parms into mPoints. */
+ QPointArray* pointArray( short num, short* parms );
+
+ /** Returns color given by the two parameters */
+ QColor color( short* parm );
+
+ /** Converts two parameters to long */
+ unsigned int toDWord( short* parm );
+
+ /** Convert (x1,y1) and (x2, y2) positions in angle and angleLength */
+ void xyToAngle( int xStart, int yStart, int xEnd, int yEnd, int& angle, int& aLength );
+
+ /** Handle win-object-handles */
+ void addHandle( WinObjHandle* );
+ void deleteHandle( int );
+
+ /** Convert windows rasterOp in QT rasterOp */
+ Qt::RasterOp winToQtRaster( short parm ) const;
+ Qt::RasterOp winToQtRaster( long parm ) const;
+
+ /** Converts DIB to BMP */
+ bool dibToBmp( QImage& bmp, const char* dib, long size);
+
+protected:
+ QPainter mPainter;
+ bool mIsPlaceable, mIsEnhanced, mValid;
+
+ // coordinate system
+ bool mAbsoluteCoord;
+ QWMatrix mInternalWorldMatrix; // memorisation of WMF matrix transformation
+ QRect mHeaderBoundingBox;
+ QRect mBBox;
+
+ // informtion shared between Metafile Functions
+ QColor mTextColor;
+ int mTextAlign, mRotation;
+ bool mWinding;
+
+ WmfCmd* mFirstCmd;
+ WinObjHandle** mObjHandleTab;
+ QPointArray mPoints;
+ int mDpi;
+};
+
+#endif /*qwmf_h*/
diff --git a/ktnef/gui/wmfstruct.h b/ktnef/gui/wmfstruct.h
new file mode 100644
index 00000000..ca4f1f7d
--- /dev/null
+++ b/ktnef/gui/wmfstruct.h
@@ -0,0 +1,107 @@
+/* WMF Metafile Structures
+ * Author: Stefan Taferner <taferner@kde.org>
+ */
+#ifndef wmfstruct_h
+#define wmfstruct_h
+
+typedef short WORD;
+typedef int DWORD;
+typedef Q_INT32 LONG;
+typedef void* _HANDLE;
+
+typedef struct _RECT
+{
+ WORD left;
+ WORD top;
+ WORD right;
+ WORD bottom;
+} RECT;
+
+typedef struct _RECTL
+{
+ LONG left;
+ LONG top;
+ LONG right;
+ LONG bottom;
+} RECTL;
+
+typedef struct _SIZE
+{
+ WORD width;
+ WORD height;
+} SIZE;
+
+typedef struct _SIZEL
+{
+ LONG width;
+ LONG height;
+} SIZEL;
+
+
+struct WmfEnhMetaHeader
+{
+ DWORD iType; // Record type EMR_HEADER
+ DWORD nSize; // Record size in bytes. This may be greater
+ // than the sizeof( ENHMETAHEADER ).
+ RECTL rclBounds; // Inclusive-inclusive bounds in device units
+ RECTL rclFrame; // Inclusive-inclusive Picture Frame of metafile
+ // in .01 mm units
+ DWORD dSignature; // Signature. Must be ENHMETA_SIGNATURE.
+ DWORD nVersion; // Version number
+ DWORD nBytes; // Size of the metafile in bytes
+ DWORD nRecords; // Number of records in the metafile
+ WORD nHandles; // Number of handles in the handle table
+ // Handle index zero is reserved.
+ WORD sReserved; // Reserved. Must be zero.
+ DWORD nDescription; // Number of chars in the unicode description string
+ // This is 0 if there is no description string
+ DWORD offDescription; // Offset to the metafile description record.
+ // This is 0 if there is no description string
+ DWORD nPalEntries; // Number of entries in the metafile palette.
+ SIZEL szlDevice; // Size of the reference device in pels
+ SIZEL szlMillimeters; // Size of the reference device in millimeters
+};
+#define ENHMETA_SIGNATURE 0x464D4520
+
+
+struct WmfMetaHeader
+{
+ WORD mtType;
+ WORD mtHeaderSize;
+ WORD mtVersion;
+ DWORD mtSize;
+ WORD mtNoObjects;
+ DWORD mtMaxRecord;
+ WORD mtNoParameters;
+};
+
+
+struct WmfPlaceableHeader
+{
+ DWORD key;
+ WORD hmf;
+ RECT bbox;
+ WORD inch;
+ DWORD reserved;
+ WORD checksum;
+};
+#define APMHEADER_KEY 0x9AC6CDD7
+
+
+struct WmfMetaRecord
+{
+ DWORD rdSize; // Record size ( in words ) of the function
+ WORD rdFunction; // Record function number
+ WORD rdParm[ 1 ]; // WORD array of parameters
+};
+
+
+struct WmfEnhMetaRecord
+{
+ DWORD iType; // Record type EMR_xxx
+ DWORD nSize; // Record size in bytes
+ DWORD dParm[ 1 ]; // DWORD array of parameters
+};
+
+
+#endif /*wmfstruct_h*/