Merge pull request #71 from metgem/master

Add PyQt5 bindings
This commit is contained in:
githubuser0xFFFF 2019-10-18 07:31:04 +02:00 committed by GitHub
commit f6174faebb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
23 changed files with 2426 additions and 1 deletions

8
.gitignore vendored
View File

@ -1,5 +1,5 @@
*.pro.user *.pro.user
/ build /build
*.o *.o
*.dylib *.dylib
*.app *.app
@ -10,3 +10,9 @@ Makefile
# IDEs # IDEs
.idea .idea
# Python
.eggs
*.pyc
*.pyd
__pycache__

10
PyQtAds/QtAds/__init__.py Normal file
View File

@ -0,0 +1,10 @@
from .ads import ads
from ._version import *
import inspect
for name, member in inspect.getmembers(ads):
if not name.startswith('_'):
globals()[name] = member
del ads

1
PyQtAds/__init__.py Normal file
View File

@ -0,0 +1 @@
from .rc import *

9
PyQtAds/_version.py Normal file
View File

@ -0,0 +1,9 @@
# THIS FILE IS GENERATED FROM PyQtAds SETUP.PY
short_version = '2.5.1'
version = '2.5.1'
full_version = '2.5.1'
git_revision = 'c10ff7c688fb50fe9157bad3982164e0f955f9e4'
release = True
if not release:
version = full_version

670
PyQtAds/rc.py Normal file
View File

@ -0,0 +1,670 @@
# -*- coding: utf-8 -*-
# Resource object code
#
# Created by: The Resource Compiler for PyQt5 (Qt v5.9.7)
#
# WARNING! All changes made in this file will be lost!
from PyQt5 import QtCore
qt_resource_data = b"\
\x00\x00\x0b\x04\
\x3c\
\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\
\x30\x22\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x22\x55\x54\x46\
\x2d\x38\x22\x20\x73\x74\x61\x6e\x64\x61\x6c\x6f\x6e\x65\x3d\x22\
\x6e\x6f\x22\x3f\x3e\x0d\x0a\x3c\x21\x2d\x2d\x20\x47\x65\x6e\x65\
\x72\x61\x74\x6f\x72\x3a\x20\x41\x64\x6f\x62\x65\x20\x49\x6c\x6c\
\x75\x73\x74\x72\x61\x74\x6f\x72\x20\x31\x36\x2e\x30\x2e\x30\x2c\
\x20\x53\x56\x47\x20\x45\x78\x70\x6f\x72\x74\x20\x50\x6c\x75\x67\
\x2d\x49\x6e\x20\x2e\x20\x53\x56\x47\x20\x56\x65\x72\x73\x69\x6f\
\x6e\x3a\x20\x36\x2e\x30\x30\x20\x42\x75\x69\x6c\x64\x20\x30\x29\
\x20\x20\x2d\x2d\x3e\x0d\x0a\x0d\x0a\x3c\x73\x76\x67\x0d\x0a\x20\
\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x64\x63\x3d\x22\x68\x74\x74\x70\
\x3a\x2f\x2f\x70\x75\x72\x6c\x2e\x6f\x72\x67\x2f\x64\x63\x2f\x65\
\x6c\x65\x6d\x65\x6e\x74\x73\x2f\x31\x2e\x31\x2f\x22\x0d\x0a\x20\
\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x63\x63\x3d\x22\x68\x74\x74\x70\
\x3a\x2f\x2f\x63\x72\x65\x61\x74\x69\x76\x65\x63\x6f\x6d\x6d\x6f\
\x6e\x73\x2e\x6f\x72\x67\x2f\x6e\x73\x23\x22\x0d\x0a\x20\x20\x20\
\x78\x6d\x6c\x6e\x73\x3a\x72\x64\x66\x3d\x22\x68\x74\x74\x70\x3a\
\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x31\x39\x39\
\x39\x2f\x30\x32\x2f\x32\x32\x2d\x72\x64\x66\x2d\x73\x79\x6e\x74\
\x61\x78\x2d\x6e\x73\x23\x22\x0d\x0a\x20\x20\x20\x78\x6d\x6c\x6e\
\x73\x3a\x73\x76\x67\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\
\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\
\x67\x22\x0d\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3d\x22\x68\x74\
\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\
\x32\x30\x30\x30\x2f\x73\x76\x67\x22\x0d\x0a\x20\x20\x20\x78\x6d\
\x6c\x6e\x73\x3a\x73\x6f\x64\x69\x70\x6f\x64\x69\x3d\x22\x68\x74\
\x74\x70\x3a\x2f\x2f\x73\x6f\x64\x69\x70\x6f\x64\x69\x2e\x73\x6f\
\x75\x72\x63\x65\x66\x6f\x72\x67\x65\x2e\x6e\x65\x74\x2f\x44\x54\
\x44\x2f\x73\x6f\x64\x69\x70\x6f\x64\x69\x2d\x30\x2e\x64\x74\x64\
\x22\x0d\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x69\x6e\x6b\x73\
\x63\x61\x70\x65\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\
\x2e\x69\x6e\x6b\x73\x63\x61\x70\x65\x2e\x6f\x72\x67\x2f\x6e\x61\
\x6d\x65\x73\x70\x61\x63\x65\x73\x2f\x69\x6e\x6b\x73\x63\x61\x70\
\x65\x22\x0d\x0a\x20\x20\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\
\x31\x2e\x31\x22\x0d\x0a\x20\x20\x20\x69\x64\x3d\x22\x43\x61\x70\
\x61\x5f\x31\x22\x0d\x0a\x20\x20\x20\x78\x3d\x22\x30\x70\x78\x22\
\x0d\x0a\x20\x20\x20\x79\x3d\x22\x30\x70\x78\x22\x0d\x0a\x20\x20\
\x20\x77\x69\x64\x74\x68\x3d\x22\x35\x31\x32\x22\x0d\x0a\x20\x20\
\x20\x68\x65\x69\x67\x68\x74\x3d\x22\x35\x31\x32\x22\x0d\x0a\x20\
\x20\x20\x76\x69\x65\x77\x42\x6f\x78\x3d\x22\x30\x20\x30\x20\x35\
\x31\x32\x20\x35\x31\x32\x22\x0d\x0a\x20\x20\x20\x78\x6d\x6c\x3a\
\x73\x70\x61\x63\x65\x3d\x22\x70\x72\x65\x73\x65\x72\x76\x65\x22\
\x0d\x0a\x20\x20\x20\x73\x6f\x64\x69\x70\x6f\x64\x69\x3a\x64\x6f\
\x63\x6e\x61\x6d\x65\x3d\x22\x63\x6c\x6f\x73\x65\x2d\x62\x75\x74\
\x74\x6f\x6e\x2e\x73\x76\x67\x22\x0d\x0a\x20\x20\x20\x69\x6e\x6b\
\x73\x63\x61\x70\x65\x3a\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x30\
\x2e\x39\x32\x2e\x33\x20\x28\x32\x34\x30\x35\x35\x34\x36\x2c\x20\
\x32\x30\x31\x38\x2d\x30\x33\x2d\x31\x31\x29\x22\x3e\x3c\x6d\x65\
\x74\x61\x64\x61\x74\x61\x0d\x0a\x20\x20\x20\x69\x64\x3d\x22\x6d\
\x65\x74\x61\x64\x61\x74\x61\x38\x39\x37\x22\x3e\x3c\x72\x64\x66\
\x3a\x52\x44\x46\x3e\x3c\x63\x63\x3a\x57\x6f\x72\x6b\x0d\x0a\x20\
\x20\x20\x20\x20\x20\x20\x72\x64\x66\x3a\x61\x62\x6f\x75\x74\x3d\
\x22\x22\x3e\x3c\x64\x63\x3a\x66\x6f\x72\x6d\x61\x74\x3e\x69\x6d\
\x61\x67\x65\x2f\x73\x76\x67\x2b\x78\x6d\x6c\x3c\x2f\x64\x63\x3a\
\x66\x6f\x72\x6d\x61\x74\x3e\x3c\x64\x63\x3a\x74\x79\x70\x65\x0d\
\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x72\x64\x66\x3a\x72\x65\
\x73\x6f\x75\x72\x63\x65\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x70\
\x75\x72\x6c\x2e\x6f\x72\x67\x2f\x64\x63\x2f\x64\x63\x6d\x69\x74\
\x79\x70\x65\x2f\x53\x74\x69\x6c\x6c\x49\x6d\x61\x67\x65\x22\x20\
\x2f\x3e\x3c\x64\x63\x3a\x74\x69\x74\x6c\x65\x3e\x3c\x2f\x64\x63\
\x3a\x74\x69\x74\x6c\x65\x3e\x3c\x2f\x63\x63\x3a\x57\x6f\x72\x6b\
\x3e\x3c\x2f\x72\x64\x66\x3a\x52\x44\x46\x3e\x3c\x2f\x6d\x65\x74\
\x61\x64\x61\x74\x61\x3e\x3c\x64\x65\x66\x73\x0d\x0a\x20\x20\x20\
\x69\x64\x3d\x22\x64\x65\x66\x73\x38\x39\x35\x22\x20\x2f\x3e\x3c\
\x73\x6f\x64\x69\x70\x6f\x64\x69\x3a\x6e\x61\x6d\x65\x64\x76\x69\
\x65\x77\x0d\x0a\x20\x20\x20\x70\x61\x67\x65\x63\x6f\x6c\x6f\x72\
\x3d\x22\x23\x66\x66\x66\x66\x66\x66\x22\x0d\x0a\x20\x20\x20\x62\
\x6f\x72\x64\x65\x72\x63\x6f\x6c\x6f\x72\x3d\x22\x23\x36\x36\x36\
\x36\x36\x36\x22\x0d\x0a\x20\x20\x20\x62\x6f\x72\x64\x65\x72\x6f\
\x70\x61\x63\x69\x74\x79\x3d\x22\x31\x22\x0d\x0a\x20\x20\x20\x6f\
\x62\x6a\x65\x63\x74\x74\x6f\x6c\x65\x72\x61\x6e\x63\x65\x3d\x22\
\x31\x30\x22\x0d\x0a\x20\x20\x20\x67\x72\x69\x64\x74\x6f\x6c\x65\
\x72\x61\x6e\x63\x65\x3d\x22\x31\x30\x22\x0d\x0a\x20\x20\x20\x67\
\x75\x69\x64\x65\x74\x6f\x6c\x65\x72\x61\x6e\x63\x65\x3d\x22\x31\
\x30\x22\x0d\x0a\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\
\x70\x61\x67\x65\x6f\x70\x61\x63\x69\x74\x79\x3d\x22\x30\x22\x0d\
\x0a\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x70\x61\x67\
\x65\x73\x68\x61\x64\x6f\x77\x3d\x22\x32\x22\x0d\x0a\x20\x20\x20\
\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\
\x77\x69\x64\x74\x68\x3d\x22\x31\x39\x32\x30\x22\x0d\x0a\x20\x20\
\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\
\x2d\x68\x65\x69\x67\x68\x74\x3d\x22\x31\x30\x31\x37\x22\x0d\x0a\
\x20\x20\x20\x69\x64\x3d\x22\x6e\x61\x6d\x65\x64\x76\x69\x65\x77\
\x38\x39\x33\x22\x0d\x0a\x20\x20\x20\x73\x68\x6f\x77\x67\x72\x69\
\x64\x3d\x22\x66\x61\x6c\x73\x65\x22\x0d\x0a\x20\x20\x20\x66\x69\
\x74\x2d\x6d\x61\x72\x67\x69\x6e\x2d\x74\x6f\x70\x3d\x22\x30\x22\
\x0d\x0a\x20\x20\x20\x66\x69\x74\x2d\x6d\x61\x72\x67\x69\x6e\x2d\
\x6c\x65\x66\x74\x3d\x22\x30\x22\x0d\x0a\x20\x20\x20\x66\x69\x74\
\x2d\x6d\x61\x72\x67\x69\x6e\x2d\x72\x69\x67\x68\x74\x3d\x22\x30\
\x22\x0d\x0a\x20\x20\x20\x66\x69\x74\x2d\x6d\x61\x72\x67\x69\x6e\
\x2d\x62\x6f\x74\x74\x6f\x6d\x3d\x22\x30\x22\x0d\x0a\x20\x20\x20\
\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x7a\x6f\x6f\x6d\x3d\x22\x30\
\x2e\x38\x35\x38\x36\x32\x39\x36\x36\x22\x0d\x0a\x20\x20\x20\x69\
\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\x78\x3d\x22\x33\x34\x35\x2e\
\x32\x39\x31\x34\x32\x22\x0d\x0a\x20\x20\x20\x69\x6e\x6b\x73\x63\
\x61\x70\x65\x3a\x63\x79\x3d\x22\x33\x32\x2e\x37\x33\x31\x32\x35\
\x38\x22\x0d\x0a\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\
\x77\x69\x6e\x64\x6f\x77\x2d\x78\x3d\x22\x2d\x38\x22\x0d\x0a\x20\
\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\
\x77\x2d\x79\x3d\x22\x2d\x38\x22\x0d\x0a\x20\x20\x20\x69\x6e\x6b\
\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x6d\x61\x78\
\x69\x6d\x69\x7a\x65\x64\x3d\x22\x31\x22\x0d\x0a\x20\x20\x20\x69\
\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\x75\x72\x72\x65\x6e\x74\x2d\
\x6c\x61\x79\x65\x72\x3d\x22\x43\x61\x70\x61\x5f\x31\x22\x20\x2f\
\x3e\x0d\x0a\x3c\x67\x0d\x0a\x20\x20\x20\x69\x64\x3d\x22\x67\x38\
\x36\x30\x22\x0d\x0a\x20\x20\x20\x74\x72\x61\x6e\x73\x66\x6f\x72\
\x6d\x3d\x22\x6d\x61\x74\x72\x69\x78\x28\x30\x2e\x37\x31\x37\x30\
\x38\x36\x38\x33\x2c\x30\x2c\x30\x2c\x30\x2e\x37\x31\x37\x30\x38\
\x36\x38\x33\x2c\x31\x32\x38\x2c\x31\x32\x38\x29\x22\x3e\x0d\x0a\
\x09\x3c\x67\x0d\x0a\x20\x20\x20\x69\x64\x3d\x22\x63\x6c\x6f\x73\
\x65\x22\x3e\x0d\x0a\x09\x09\x3c\x70\x6f\x6c\x79\x67\x6f\x6e\x0d\
\x0a\x20\x20\x20\x70\x6f\x69\x6e\x74\x73\x3d\x22\x33\x35\x37\x2c\
\x33\x32\x31\x2e\x33\x20\x32\x31\x34\x2e\x32\x2c\x31\x37\x38\x2e\
\x35\x20\x33\x35\x37\x2c\x33\x35\x2e\x37\x20\x33\x32\x31\x2e\x33\
\x2c\x30\x20\x31\x37\x38\x2e\x35\x2c\x31\x34\x32\x2e\x38\x20\x33\
\x35\x2e\x37\x2c\x30\x20\x30\x2c\x33\x35\x2e\x37\x20\x31\x34\x32\
\x2e\x38\x2c\x31\x37\x38\x2e\x35\x20\x30\x2c\x33\x32\x31\x2e\x33\
\x20\x33\x35\x2e\x37\x2c\x33\x35\x37\x20\x31\x37\x38\x2e\x35\x2c\
\x32\x31\x34\x2e\x32\x20\x33\x32\x31\x2e\x33\x2c\x33\x35\x37\x20\
\x22\x0d\x0a\x20\x20\x20\x69\x64\x3d\x22\x70\x6f\x6c\x79\x67\x6f\
\x6e\x38\x35\x37\x22\x20\x2f\x3e\x0d\x0a\x09\x3c\x2f\x67\x3e\x0d\
\x0a\x3c\x2f\x67\x3e\x0d\x0a\x3c\x67\x0d\x0a\x20\x20\x20\x69\x64\
\x3d\x22\x67\x38\x36\x32\x22\x0d\x0a\x20\x20\x20\x74\x72\x61\x6e\
\x73\x66\x6f\x72\x6d\x3d\x22\x74\x72\x61\x6e\x73\x6c\x61\x74\x65\
\x28\x30\x2c\x31\x35\x35\x29\x22\x3e\x0d\x0a\x3c\x2f\x67\x3e\x0d\
\x0a\x3c\x67\x0d\x0a\x20\x20\x20\x69\x64\x3d\x22\x67\x38\x36\x34\
\x22\x0d\x0a\x20\x20\x20\x74\x72\x61\x6e\x73\x66\x6f\x72\x6d\x3d\
\x22\x74\x72\x61\x6e\x73\x6c\x61\x74\x65\x28\x30\x2c\x31\x35\x35\
\x29\x22\x3e\x0d\x0a\x3c\x2f\x67\x3e\x0d\x0a\x3c\x67\x0d\x0a\x20\
\x20\x20\x69\x64\x3d\x22\x67\x38\x36\x36\x22\x0d\x0a\x20\x20\x20\
\x74\x72\x61\x6e\x73\x66\x6f\x72\x6d\x3d\x22\x74\x72\x61\x6e\x73\
\x6c\x61\x74\x65\x28\x30\x2c\x31\x35\x35\x29\x22\x3e\x0d\x0a\x3c\
\x2f\x67\x3e\x0d\x0a\x3c\x67\x0d\x0a\x20\x20\x20\x69\x64\x3d\x22\
\x67\x38\x36\x38\x22\x0d\x0a\x20\x20\x20\x74\x72\x61\x6e\x73\x66\
\x6f\x72\x6d\x3d\x22\x74\x72\x61\x6e\x73\x6c\x61\x74\x65\x28\x30\
\x2c\x31\x35\x35\x29\x22\x3e\x0d\x0a\x3c\x2f\x67\x3e\x0d\x0a\x3c\
\x67\x0d\x0a\x20\x20\x20\x69\x64\x3d\x22\x67\x38\x37\x30\x22\x0d\
\x0a\x20\x20\x20\x74\x72\x61\x6e\x73\x66\x6f\x72\x6d\x3d\x22\x74\
\x72\x61\x6e\x73\x6c\x61\x74\x65\x28\x30\x2c\x31\x35\x35\x29\x22\
\x3e\x0d\x0a\x3c\x2f\x67\x3e\x0d\x0a\x3c\x67\x0d\x0a\x20\x20\x20\
\x69\x64\x3d\x22\x67\x38\x37\x32\x22\x0d\x0a\x20\x20\x20\x74\x72\
\x61\x6e\x73\x66\x6f\x72\x6d\x3d\x22\x74\x72\x61\x6e\x73\x6c\x61\
\x74\x65\x28\x30\x2c\x31\x35\x35\x29\x22\x3e\x0d\x0a\x3c\x2f\x67\
\x3e\x0d\x0a\x3c\x67\x0d\x0a\x20\x20\x20\x69\x64\x3d\x22\x67\x38\
\x37\x34\x22\x0d\x0a\x20\x20\x20\x74\x72\x61\x6e\x73\x66\x6f\x72\
\x6d\x3d\x22\x74\x72\x61\x6e\x73\x6c\x61\x74\x65\x28\x30\x2c\x31\
\x35\x35\x29\x22\x3e\x0d\x0a\x3c\x2f\x67\x3e\x0d\x0a\x3c\x67\x0d\
\x0a\x20\x20\x20\x69\x64\x3d\x22\x67\x38\x37\x36\x22\x0d\x0a\x20\
\x20\x20\x74\x72\x61\x6e\x73\x66\x6f\x72\x6d\x3d\x22\x74\x72\x61\
\x6e\x73\x6c\x61\x74\x65\x28\x30\x2c\x31\x35\x35\x29\x22\x3e\x0d\
\x0a\x3c\x2f\x67\x3e\x0d\x0a\x3c\x67\x0d\x0a\x20\x20\x20\x69\x64\
\x3d\x22\x67\x38\x37\x38\x22\x0d\x0a\x20\x20\x20\x74\x72\x61\x6e\
\x73\x66\x6f\x72\x6d\x3d\x22\x74\x72\x61\x6e\x73\x6c\x61\x74\x65\
\x28\x30\x2c\x31\x35\x35\x29\x22\x3e\x0d\x0a\x3c\x2f\x67\x3e\x0d\
\x0a\x3c\x67\x0d\x0a\x20\x20\x20\x69\x64\x3d\x22\x67\x38\x38\x30\
\x22\x0d\x0a\x20\x20\x20\x74\x72\x61\x6e\x73\x66\x6f\x72\x6d\x3d\
\x22\x74\x72\x61\x6e\x73\x6c\x61\x74\x65\x28\x30\x2c\x31\x35\x35\
\x29\x22\x3e\x0d\x0a\x3c\x2f\x67\x3e\x0d\x0a\x3c\x67\x0d\x0a\x20\
\x20\x20\x69\x64\x3d\x22\x67\x38\x38\x32\x22\x0d\x0a\x20\x20\x20\
\x74\x72\x61\x6e\x73\x66\x6f\x72\x6d\x3d\x22\x74\x72\x61\x6e\x73\
\x6c\x61\x74\x65\x28\x30\x2c\x31\x35\x35\x29\x22\x3e\x0d\x0a\x3c\
\x2f\x67\x3e\x0d\x0a\x3c\x67\x0d\x0a\x20\x20\x20\x69\x64\x3d\x22\
\x67\x38\x38\x34\x22\x0d\x0a\x20\x20\x20\x74\x72\x61\x6e\x73\x66\
\x6f\x72\x6d\x3d\x22\x74\x72\x61\x6e\x73\x6c\x61\x74\x65\x28\x30\
\x2c\x31\x35\x35\x29\x22\x3e\x0d\x0a\x3c\x2f\x67\x3e\x0d\x0a\x3c\
\x67\x0d\x0a\x20\x20\x20\x69\x64\x3d\x22\x67\x38\x38\x36\x22\x0d\
\x0a\x20\x20\x20\x74\x72\x61\x6e\x73\x66\x6f\x72\x6d\x3d\x22\x74\
\x72\x61\x6e\x73\x6c\x61\x74\x65\x28\x30\x2c\x31\x35\x35\x29\x22\
\x3e\x0d\x0a\x3c\x2f\x67\x3e\x0d\x0a\x3c\x67\x0d\x0a\x20\x20\x20\
\x69\x64\x3d\x22\x67\x38\x38\x38\x22\x0d\x0a\x20\x20\x20\x74\x72\
\x61\x6e\x73\x66\x6f\x72\x6d\x3d\x22\x74\x72\x61\x6e\x73\x6c\x61\
\x74\x65\x28\x30\x2c\x31\x35\x35\x29\x22\x3e\x0d\x0a\x3c\x2f\x67\
\x3e\x0d\x0a\x3c\x67\x0d\x0a\x20\x20\x20\x69\x64\x3d\x22\x67\x38\
\x39\x30\x22\x0d\x0a\x20\x20\x20\x74\x72\x61\x6e\x73\x66\x6f\x72\
\x6d\x3d\x22\x74\x72\x61\x6e\x73\x6c\x61\x74\x65\x28\x30\x2c\x31\
\x35\x35\x29\x22\x3e\x0d\x0a\x3c\x2f\x67\x3e\x0d\x0a\x3c\x2f\x73\
\x76\x67\x3e\
\x00\x00\x0b\xf7\
\x3c\
\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\
\x30\x22\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x22\x55\x54\x46\
\x2d\x38\x22\x20\x73\x74\x61\x6e\x64\x61\x6c\x6f\x6e\x65\x3d\x22\
\x6e\x6f\x22\x3f\x3e\x0d\x0a\x3c\x21\x2d\x2d\x20\x47\x65\x6e\x65\
\x72\x61\x74\x6f\x72\x3a\x20\x41\x64\x6f\x62\x65\x20\x49\x6c\x6c\
\x75\x73\x74\x72\x61\x74\x6f\x72\x20\x31\x36\x2e\x30\x2e\x30\x2c\
\x20\x53\x56\x47\x20\x45\x78\x70\x6f\x72\x74\x20\x50\x6c\x75\x67\
\x2d\x49\x6e\x20\x2e\x20\x53\x56\x47\x20\x56\x65\x72\x73\x69\x6f\
\x6e\x3a\x20\x36\x2e\x30\x30\x20\x42\x75\x69\x6c\x64\x20\x30\x29\
\x20\x20\x2d\x2d\x3e\x0d\x0a\x0d\x0a\x3c\x73\x76\x67\x0d\x0a\x20\
\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x64\x63\x3d\x22\x68\x74\x74\x70\
\x3a\x2f\x2f\x70\x75\x72\x6c\x2e\x6f\x72\x67\x2f\x64\x63\x2f\x65\
\x6c\x65\x6d\x65\x6e\x74\x73\x2f\x31\x2e\x31\x2f\x22\x0d\x0a\x20\
\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x63\x63\x3d\x22\x68\x74\x74\x70\
\x3a\x2f\x2f\x63\x72\x65\x61\x74\x69\x76\x65\x63\x6f\x6d\x6d\x6f\
\x6e\x73\x2e\x6f\x72\x67\x2f\x6e\x73\x23\x22\x0d\x0a\x20\x20\x20\
\x78\x6d\x6c\x6e\x73\x3a\x72\x64\x66\x3d\x22\x68\x74\x74\x70\x3a\
\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x31\x39\x39\
\x39\x2f\x30\x32\x2f\x32\x32\x2d\x72\x64\x66\x2d\x73\x79\x6e\x74\
\x61\x78\x2d\x6e\x73\x23\x22\x0d\x0a\x20\x20\x20\x78\x6d\x6c\x6e\
\x73\x3a\x73\x76\x67\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\
\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\
\x67\x22\x0d\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3d\x22\x68\x74\
\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\
\x32\x30\x30\x30\x2f\x73\x76\x67\x22\x0d\x0a\x20\x20\x20\x78\x6d\
\x6c\x6e\x73\x3a\x73\x6f\x64\x69\x70\x6f\x64\x69\x3d\x22\x68\x74\
\x74\x70\x3a\x2f\x2f\x73\x6f\x64\x69\x70\x6f\x64\x69\x2e\x73\x6f\
\x75\x72\x63\x65\x66\x6f\x72\x67\x65\x2e\x6e\x65\x74\x2f\x44\x54\
\x44\x2f\x73\x6f\x64\x69\x70\x6f\x64\x69\x2d\x30\x2e\x64\x74\x64\
\x22\x0d\x0a\x20\x20\x20\x78\x6d\x6c\x6e\x73\x3a\x69\x6e\x6b\x73\
\x63\x61\x70\x65\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\
\x2e\x69\x6e\x6b\x73\x63\x61\x70\x65\x2e\x6f\x72\x67\x2f\x6e\x61\
\x6d\x65\x73\x70\x61\x63\x65\x73\x2f\x69\x6e\x6b\x73\x63\x61\x70\
\x65\x22\x0d\x0a\x20\x20\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\
\x31\x2e\x31\x22\x0d\x0a\x20\x20\x20\x69\x64\x3d\x22\x43\x61\x70\
\x61\x5f\x31\x22\x0d\x0a\x20\x20\x20\x78\x3d\x22\x30\x70\x78\x22\
\x0d\x0a\x20\x20\x20\x79\x3d\x22\x30\x70\x78\x22\x0d\x0a\x20\x20\
\x20\x77\x69\x64\x74\x68\x3d\x22\x35\x31\x32\x22\x0d\x0a\x20\x20\
\x20\x68\x65\x69\x67\x68\x74\x3d\x22\x35\x31\x32\x22\x0d\x0a\x20\
\x20\x20\x76\x69\x65\x77\x42\x6f\x78\x3d\x22\x30\x20\x30\x20\x35\
\x31\x32\x20\x35\x31\x32\x22\x0d\x0a\x20\x20\x20\x78\x6d\x6c\x3a\
\x73\x70\x61\x63\x65\x3d\x22\x70\x72\x65\x73\x65\x72\x76\x65\x22\
\x0d\x0a\x20\x20\x20\x73\x6f\x64\x69\x70\x6f\x64\x69\x3a\x64\x6f\
\x63\x6e\x61\x6d\x65\x3d\x22\x63\x6c\x6f\x73\x65\x2d\x62\x75\x74\
\x74\x6f\x6e\x2d\x64\x69\x73\x61\x62\x6c\x65\x64\x2e\x73\x76\x67\
\x22\x0d\x0a\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x76\
\x65\x72\x73\x69\x6f\x6e\x3d\x22\x30\x2e\x39\x32\x2e\x33\x20\x28\
\x32\x34\x30\x35\x35\x34\x36\x2c\x20\x32\x30\x31\x38\x2d\x30\x33\
\x2d\x31\x31\x29\x22\x3e\x3c\x6d\x65\x74\x61\x64\x61\x74\x61\x0d\
\x0a\x20\x20\x20\x69\x64\x3d\x22\x6d\x65\x74\x61\x64\x61\x74\x61\
\x38\x39\x37\x22\x3e\x3c\x72\x64\x66\x3a\x52\x44\x46\x3e\x3c\x63\
\x63\x3a\x57\x6f\x72\x6b\x0d\x0a\x20\x20\x20\x20\x20\x20\x20\x72\
\x64\x66\x3a\x61\x62\x6f\x75\x74\x3d\x22\x22\x3e\x3c\x64\x63\x3a\
\x66\x6f\x72\x6d\x61\x74\x3e\x69\x6d\x61\x67\x65\x2f\x73\x76\x67\
\x2b\x78\x6d\x6c\x3c\x2f\x64\x63\x3a\x66\x6f\x72\x6d\x61\x74\x3e\
\x3c\x64\x63\x3a\x74\x79\x70\x65\x0d\x0a\x20\x20\x20\x20\x20\x20\
\x20\x20\x20\x72\x64\x66\x3a\x72\x65\x73\x6f\x75\x72\x63\x65\x3d\
\x22\x68\x74\x74\x70\x3a\x2f\x2f\x70\x75\x72\x6c\x2e\x6f\x72\x67\
\x2f\x64\x63\x2f\x64\x63\x6d\x69\x74\x79\x70\x65\x2f\x53\x74\x69\
\x6c\x6c\x49\x6d\x61\x67\x65\x22\x20\x2f\x3e\x3c\x64\x63\x3a\x74\
\x69\x74\x6c\x65\x3e\x3c\x2f\x64\x63\x3a\x74\x69\x74\x6c\x65\x3e\
\x3c\x2f\x63\x63\x3a\x57\x6f\x72\x6b\x3e\x3c\x2f\x72\x64\x66\x3a\
\x52\x44\x46\x3e\x3c\x2f\x6d\x65\x74\x61\x64\x61\x74\x61\x3e\x3c\
\x64\x65\x66\x73\x0d\x0a\x20\x20\x20\x69\x64\x3d\x22\x64\x65\x66\
\x73\x38\x39\x35\x22\x20\x2f\x3e\x3c\x73\x6f\x64\x69\x70\x6f\x64\
\x69\x3a\x6e\x61\x6d\x65\x64\x76\x69\x65\x77\x0d\x0a\x20\x20\x20\
\x70\x61\x67\x65\x63\x6f\x6c\x6f\x72\x3d\x22\x23\x66\x66\x66\x66\
\x66\x66\x22\x0d\x0a\x20\x20\x20\x62\x6f\x72\x64\x65\x72\x63\x6f\
\x6c\x6f\x72\x3d\x22\x23\x36\x36\x36\x36\x36\x36\x22\x0d\x0a\x20\
\x20\x20\x62\x6f\x72\x64\x65\x72\x6f\x70\x61\x63\x69\x74\x79\x3d\
\x22\x31\x22\x0d\x0a\x20\x20\x20\x6f\x62\x6a\x65\x63\x74\x74\x6f\
\x6c\x65\x72\x61\x6e\x63\x65\x3d\x22\x31\x30\x22\x0d\x0a\x20\x20\
\x20\x67\x72\x69\x64\x74\x6f\x6c\x65\x72\x61\x6e\x63\x65\x3d\x22\
\x31\x30\x22\x0d\x0a\x20\x20\x20\x67\x75\x69\x64\x65\x74\x6f\x6c\
\x65\x72\x61\x6e\x63\x65\x3d\x22\x31\x30\x22\x0d\x0a\x20\x20\x20\
\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x70\x61\x67\x65\x6f\x70\x61\
\x63\x69\x74\x79\x3d\x22\x30\x22\x0d\x0a\x20\x20\x20\x69\x6e\x6b\
\x73\x63\x61\x70\x65\x3a\x70\x61\x67\x65\x73\x68\x61\x64\x6f\x77\
\x3d\x22\x32\x22\x0d\x0a\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\
\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x77\x69\x64\x74\x68\x3d\x22\
\x31\x39\x32\x30\x22\x0d\x0a\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\
\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x68\x65\x69\x67\x68\x74\
\x3d\x22\x31\x30\x31\x37\x22\x0d\x0a\x20\x20\x20\x69\x64\x3d\x22\
\x6e\x61\x6d\x65\x64\x76\x69\x65\x77\x38\x39\x33\x22\x0d\x0a\x20\
\x20\x20\x73\x68\x6f\x77\x67\x72\x69\x64\x3d\x22\x66\x61\x6c\x73\
\x65\x22\x0d\x0a\x20\x20\x20\x66\x69\x74\x2d\x6d\x61\x72\x67\x69\
\x6e\x2d\x74\x6f\x70\x3d\x22\x30\x22\x0d\x0a\x20\x20\x20\x66\x69\
\x74\x2d\x6d\x61\x72\x67\x69\x6e\x2d\x6c\x65\x66\x74\x3d\x22\x30\
\x22\x0d\x0a\x20\x20\x20\x66\x69\x74\x2d\x6d\x61\x72\x67\x69\x6e\
\x2d\x72\x69\x67\x68\x74\x3d\x22\x30\x22\x0d\x0a\x20\x20\x20\x66\
\x69\x74\x2d\x6d\x61\x72\x67\x69\x6e\x2d\x62\x6f\x74\x74\x6f\x6d\
\x3d\x22\x30\x22\x0d\x0a\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\
\x65\x3a\x7a\x6f\x6f\x6d\x3d\x22\x30\x2e\x38\x35\x38\x36\x32\x39\
\x36\x36\x22\x0d\x0a\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\
\x3a\x63\x78\x3d\x22\x33\x34\x35\x2e\x32\x39\x31\x34\x32\x22\x0d\
\x0a\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x63\x79\x3d\
\x22\x33\x32\x2e\x37\x33\x31\x32\x35\x38\x22\x0d\x0a\x20\x20\x20\
\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\
\x78\x3d\x22\x2d\x38\x22\x0d\x0a\x20\x20\x20\x69\x6e\x6b\x73\x63\
\x61\x70\x65\x3a\x77\x69\x6e\x64\x6f\x77\x2d\x79\x3d\x22\x2d\x38\
\x22\x0d\x0a\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\x3a\x77\
\x69\x6e\x64\x6f\x77\x2d\x6d\x61\x78\x69\x6d\x69\x7a\x65\x64\x3d\
\x22\x31\x22\x0d\x0a\x20\x20\x20\x69\x6e\x6b\x73\x63\x61\x70\x65\
\x3a\x63\x75\x72\x72\x65\x6e\x74\x2d\x6c\x61\x79\x65\x72\x3d\x22\
\x43\x61\x70\x61\x5f\x31\x22\x20\x2f\x3e\x0d\x0a\x3c\x67\x0d\x0a\
\x20\x20\x20\x69\x64\x3d\x22\x67\x38\x36\x30\x22\x0d\x0a\x20\x20\
\x20\x74\x72\x61\x6e\x73\x66\x6f\x72\x6d\x3d\x22\x6d\x61\x74\x72\
\x69\x78\x28\x30\x2e\x37\x31\x37\x30\x38\x36\x38\x33\x2c\x30\x2c\
\x30\x2c\x30\x2e\x37\x31\x37\x30\x38\x36\x38\x33\x2c\x31\x32\x38\
\x2c\x31\x32\x38\x29\x22\x0d\x0a\x20\x20\x20\x73\x74\x79\x6c\x65\
\x3d\x22\x73\x74\x72\x6f\x6b\x65\x3a\x6e\x6f\x6e\x65\x3b\x73\x74\
\x72\x6f\x6b\x65\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x31\x3b\x66\
\x69\x6c\x6c\x3a\x23\x30\x30\x30\x30\x30\x30\x3b\x66\x69\x6c\x6c\
\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x30\x2e\x35\x30\x31\x39\x36\
\x30\x38\x31\x22\x3e\x0d\x0a\x09\x3c\x67\x0d\x0a\x20\x20\x20\x69\
\x64\x3d\x22\x63\x6c\x6f\x73\x65\x22\x0d\x0a\x20\x20\x20\x73\x74\
\x79\x6c\x65\x3d\x22\x73\x74\x72\x6f\x6b\x65\x3a\x6e\x6f\x6e\x65\
\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\
\x31\x3b\x66\x69\x6c\x6c\x3a\x23\x30\x30\x30\x30\x30\x30\x3b\x66\
\x69\x6c\x6c\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x30\x2e\x35\x30\
\x31\x39\x36\x30\x38\x31\x22\x3e\x0d\x0a\x09\x09\x3c\x70\x6f\x6c\
\x79\x67\x6f\x6e\x0d\x0a\x20\x20\x20\x70\x6f\x69\x6e\x74\x73\x3d\
\x22\x33\x35\x37\x2c\x33\x32\x31\x2e\x33\x20\x32\x31\x34\x2e\x32\
\x2c\x31\x37\x38\x2e\x35\x20\x33\x35\x37\x2c\x33\x35\x2e\x37\x20\
\x33\x32\x31\x2e\x33\x2c\x30\x20\x31\x37\x38\x2e\x35\x2c\x31\x34\
\x32\x2e\x38\x20\x33\x35\x2e\x37\x2c\x30\x20\x30\x2c\x33\x35\x2e\
\x37\x20\x31\x34\x32\x2e\x38\x2c\x31\x37\x38\x2e\x35\x20\x30\x2c\
\x33\x32\x31\x2e\x33\x20\x33\x35\x2e\x37\x2c\x33\x35\x37\x20\x31\
\x37\x38\x2e\x35\x2c\x32\x31\x34\x2e\x32\x20\x33\x32\x31\x2e\x33\
\x2c\x33\x35\x37\x20\x22\x0d\x0a\x20\x20\x20\x69\x64\x3d\x22\x70\
\x6f\x6c\x79\x67\x6f\x6e\x38\x35\x37\x22\x0d\x0a\x20\x20\x20\x73\
\x74\x79\x6c\x65\x3d\x22\x73\x74\x72\x6f\x6b\x65\x3a\x6e\x6f\x6e\
\x65\x3b\x73\x74\x72\x6f\x6b\x65\x2d\x6f\x70\x61\x63\x69\x74\x79\
\x3a\x31\x3b\x66\x69\x6c\x6c\x3a\x23\x30\x30\x30\x30\x30\x30\x3b\
\x66\x69\x6c\x6c\x2d\x6f\x70\x61\x63\x69\x74\x79\x3a\x30\x2e\x35\
\x30\x31\x39\x36\x30\x38\x31\x22\x20\x2f\x3e\x0d\x0a\x09\x3c\x2f\
\x67\x3e\x0d\x0a\x3c\x2f\x67\x3e\x0d\x0a\x3c\x67\x0d\x0a\x20\x20\
\x20\x69\x64\x3d\x22\x67\x38\x36\x32\x22\x0d\x0a\x20\x20\x20\x74\
\x72\x61\x6e\x73\x66\x6f\x72\x6d\x3d\x22\x74\x72\x61\x6e\x73\x6c\
\x61\x74\x65\x28\x30\x2c\x31\x35\x35\x29\x22\x3e\x0d\x0a\x3c\x2f\
\x67\x3e\x0d\x0a\x3c\x67\x0d\x0a\x20\x20\x20\x69\x64\x3d\x22\x67\
\x38\x36\x34\x22\x0d\x0a\x20\x20\x20\x74\x72\x61\x6e\x73\x66\x6f\
\x72\x6d\x3d\x22\x74\x72\x61\x6e\x73\x6c\x61\x74\x65\x28\x30\x2c\
\x31\x35\x35\x29\x22\x3e\x0d\x0a\x3c\x2f\x67\x3e\x0d\x0a\x3c\x67\
\x0d\x0a\x20\x20\x20\x69\x64\x3d\x22\x67\x38\x36\x36\x22\x0d\x0a\
\x20\x20\x20\x74\x72\x61\x6e\x73\x66\x6f\x72\x6d\x3d\x22\x74\x72\
\x61\x6e\x73\x6c\x61\x74\x65\x28\x30\x2c\x31\x35\x35\x29\x22\x3e\
\x0d\x0a\x3c\x2f\x67\x3e\x0d\x0a\x3c\x67\x0d\x0a\x20\x20\x20\x69\
\x64\x3d\x22\x67\x38\x36\x38\x22\x0d\x0a\x20\x20\x20\x74\x72\x61\
\x6e\x73\x66\x6f\x72\x6d\x3d\x22\x74\x72\x61\x6e\x73\x6c\x61\x74\
\x65\x28\x30\x2c\x31\x35\x35\x29\x22\x3e\x0d\x0a\x3c\x2f\x67\x3e\
\x0d\x0a\x3c\x67\x0d\x0a\x20\x20\x20\x69\x64\x3d\x22\x67\x38\x37\
\x30\x22\x0d\x0a\x20\x20\x20\x74\x72\x61\x6e\x73\x66\x6f\x72\x6d\
\x3d\x22\x74\x72\x61\x6e\x73\x6c\x61\x74\x65\x28\x30\x2c\x31\x35\
\x35\x29\x22\x3e\x0d\x0a\x3c\x2f\x67\x3e\x0d\x0a\x3c\x67\x0d\x0a\
\x20\x20\x20\x69\x64\x3d\x22\x67\x38\x37\x32\x22\x0d\x0a\x20\x20\
\x20\x74\x72\x61\x6e\x73\x66\x6f\x72\x6d\x3d\x22\x74\x72\x61\x6e\
\x73\x6c\x61\x74\x65\x28\x30\x2c\x31\x35\x35\x29\x22\x3e\x0d\x0a\
\x3c\x2f\x67\x3e\x0d\x0a\x3c\x67\x0d\x0a\x20\x20\x20\x69\x64\x3d\
\x22\x67\x38\x37\x34\x22\x0d\x0a\x20\x20\x20\x74\x72\x61\x6e\x73\
\x66\x6f\x72\x6d\x3d\x22\x74\x72\x61\x6e\x73\x6c\x61\x74\x65\x28\
\x30\x2c\x31\x35\x35\x29\x22\x3e\x0d\x0a\x3c\x2f\x67\x3e\x0d\x0a\
\x3c\x67\x0d\x0a\x20\x20\x20\x69\x64\x3d\x22\x67\x38\x37\x36\x22\
\x0d\x0a\x20\x20\x20\x74\x72\x61\x6e\x73\x66\x6f\x72\x6d\x3d\x22\
\x74\x72\x61\x6e\x73\x6c\x61\x74\x65\x28\x30\x2c\x31\x35\x35\x29\
\x22\x3e\x0d\x0a\x3c\x2f\x67\x3e\x0d\x0a\x3c\x67\x0d\x0a\x20\x20\
\x20\x69\x64\x3d\x22\x67\x38\x37\x38\x22\x0d\x0a\x20\x20\x20\x74\
\x72\x61\x6e\x73\x66\x6f\x72\x6d\x3d\x22\x74\x72\x61\x6e\x73\x6c\
\x61\x74\x65\x28\x30\x2c\x31\x35\x35\x29\x22\x3e\x0d\x0a\x3c\x2f\
\x67\x3e\x0d\x0a\x3c\x67\x0d\x0a\x20\x20\x20\x69\x64\x3d\x22\x67\
\x38\x38\x30\x22\x0d\x0a\x20\x20\x20\x74\x72\x61\x6e\x73\x66\x6f\
\x72\x6d\x3d\x22\x74\x72\x61\x6e\x73\x6c\x61\x74\x65\x28\x30\x2c\
\x31\x35\x35\x29\x22\x3e\x0d\x0a\x3c\x2f\x67\x3e\x0d\x0a\x3c\x67\
\x0d\x0a\x20\x20\x20\x69\x64\x3d\x22\x67\x38\x38\x32\x22\x0d\x0a\
\x20\x20\x20\x74\x72\x61\x6e\x73\x66\x6f\x72\x6d\x3d\x22\x74\x72\
\x61\x6e\x73\x6c\x61\x74\x65\x28\x30\x2c\x31\x35\x35\x29\x22\x3e\
\x0d\x0a\x3c\x2f\x67\x3e\x0d\x0a\x3c\x67\x0d\x0a\x20\x20\x20\x69\
\x64\x3d\x22\x67\x38\x38\x34\x22\x0d\x0a\x20\x20\x20\x74\x72\x61\
\x6e\x73\x66\x6f\x72\x6d\x3d\x22\x74\x72\x61\x6e\x73\x6c\x61\x74\
\x65\x28\x30\x2c\x31\x35\x35\x29\x22\x3e\x0d\x0a\x3c\x2f\x67\x3e\
\x0d\x0a\x3c\x67\x0d\x0a\x20\x20\x20\x69\x64\x3d\x22\x67\x38\x38\
\x36\x22\x0d\x0a\x20\x20\x20\x74\x72\x61\x6e\x73\x66\x6f\x72\x6d\
\x3d\x22\x74\x72\x61\x6e\x73\x6c\x61\x74\x65\x28\x30\x2c\x31\x35\
\x35\x29\x22\x3e\x0d\x0a\x3c\x2f\x67\x3e\x0d\x0a\x3c\x67\x0d\x0a\
\x20\x20\x20\x69\x64\x3d\x22\x67\x38\x38\x38\x22\x0d\x0a\x20\x20\
\x20\x74\x72\x61\x6e\x73\x66\x6f\x72\x6d\x3d\x22\x74\x72\x61\x6e\
\x73\x6c\x61\x74\x65\x28\x30\x2c\x31\x35\x35\x29\x22\x3e\x0d\x0a\
\x3c\x2f\x67\x3e\x0d\x0a\x3c\x67\x0d\x0a\x20\x20\x20\x69\x64\x3d\
\x22\x67\x38\x39\x30\x22\x0d\x0a\x20\x20\x20\x74\x72\x61\x6e\x73\
\x66\x6f\x72\x6d\x3d\x22\x74\x72\x61\x6e\x73\x6c\x61\x74\x65\x28\
\x30\x2c\x31\x35\x35\x29\x22\x3e\x0d\x0a\x3c\x2f\x67\x3e\x0d\x0a\
\x3c\x2f\x73\x76\x67\x3e\
\x00\x00\x06\x61\
\x0d\
\x0a\x2f\x2a\x0d\x0a\x20\x2a\x20\x44\x65\x66\x61\x75\x6c\x74\x20\
\x73\x74\x79\x6c\x65\x20\x73\x68\x65\x65\x74\x20\x6f\x6e\x20\x57\
\x69\x6e\x64\x6f\x77\x73\x20\x50\x6c\x61\x74\x66\x6f\x72\x6d\x73\
\x0d\x0a\x20\x2a\x20\x4e\x6f\x74\x65\x3a\x20\x41\x6c\x77\x61\x79\
\x73\x20\x75\x73\x65\x20\x43\x53\x53\x2d\x63\x6c\x61\x73\x73\x65\
\x73\x20\x77\x69\x74\x68\x20\x61\x6e\x64\x20\x77\x69\x74\x68\x6f\
\x75\x74\x20\x22\x61\x64\x73\x2d\x2d\x22\x20\x6e\x61\x6d\x65\x73\
\x70\x61\x63\x65\x20\x74\x6f\x20\x73\x75\x70\x70\x6f\x72\x74\x20\
\x51\x74\x34\x20\x26\x20\x51\x74\x35\x0d\x0a\x20\x2a\x2f\x0d\x0a\
\x0d\x0a\x61\x64\x73\x2d\x2d\x43\x44\x6f\x63\x6b\x43\x6f\x6e\x74\
\x61\x69\x6e\x65\x72\x57\x69\x64\x67\x65\x74\x0d\x0a\x7b\x0d\x0a\
\x20\x20\x20\x20\x62\x61\x63\x6b\x67\x72\x6f\x75\x6e\x64\x3a\x20\
\x70\x61\x6c\x65\x74\x74\x65\x28\x64\x61\x72\x6b\x29\x3b\x0d\x0a\
\x7d\x0d\x0a\x0d\x0a\x61\x64\x73\x2d\x2d\x43\x44\x6f\x63\x6b\x43\
\x6f\x6e\x74\x61\x69\x6e\x65\x72\x57\x69\x64\x67\x65\x74\x20\x51\
\x53\x70\x6c\x69\x74\x74\x65\x72\x3a\x3a\x68\x61\x6e\x64\x6c\x65\
\x0d\x0a\x7b\x0d\x0a\x20\x20\x20\x20\x62\x61\x63\x6b\x67\x72\x6f\
\x75\x6e\x64\x3a\x20\x70\x61\x6c\x65\x74\x74\x65\x28\x64\x61\x72\
\x6b\x29\x3b\x0d\x0a\x7d\x0d\x0a\x0d\x0a\x61\x64\x73\x2d\x2d\x43\
\x44\x6f\x63\x6b\x41\x72\x65\x61\x57\x69\x64\x67\x65\x74\x0d\x0a\
\x7b\x0d\x0a\x20\x20\x20\x20\x62\x61\x63\x6b\x67\x72\x6f\x75\x6e\
\x64\x3a\x20\x70\x61\x6c\x65\x74\x74\x65\x28\x77\x69\x6e\x64\x6f\
\x77\x29\x3b\x0d\x0a\x20\x20\x20\x20\x62\x6f\x72\x64\x65\x72\x3a\
\x20\x31\x70\x78\x20\x73\x6f\x6c\x69\x64\x20\x77\x68\x69\x74\x65\
\x3b\x0d\x0a\x7d\x0d\x0a\x0d\x0a\x61\x64\x73\x2d\x2d\x43\x44\x6f\
\x63\x6b\x41\x72\x65\x61\x57\x69\x64\x67\x65\x74\x20\x23\x74\x61\
\x62\x73\x4d\x65\x6e\x75\x42\x75\x74\x74\x6f\x6e\x3a\x3a\x6d\x65\
\x6e\x75\x2d\x69\x6e\x64\x69\x63\x61\x74\x6f\x72\x0d\x0a\x7b\x0d\
\x0a\x20\x20\x20\x20\x69\x6d\x61\x67\x65\x3a\x20\x6e\x6f\x6e\x65\
\x3b\x0d\x0a\x7d\x0d\x0a\x0d\x0a\x0d\x0a\x61\x64\x73\x2d\x2d\x43\
\x44\x6f\x63\x6b\x57\x69\x64\x67\x65\x74\x54\x61\x62\x0d\x0a\x7b\
\x0d\x0a\x20\x20\x20\x20\x62\x61\x63\x6b\x67\x72\x6f\x75\x6e\x64\
\x3a\x20\x70\x61\x6c\x65\x74\x74\x65\x28\x77\x69\x6e\x64\x6f\x77\
\x29\x3b\x0d\x0a\x20\x20\x20\x20\x62\x6f\x72\x64\x65\x72\x2d\x63\
\x6f\x6c\x6f\x72\x3a\x20\x70\x61\x6c\x65\x74\x74\x65\x28\x6c\x69\
\x67\x68\x74\x29\x3b\x0d\x0a\x20\x20\x20\x20\x62\x6f\x72\x64\x65\
\x72\x2d\x73\x74\x79\x6c\x65\x3a\x20\x73\x6f\x6c\x69\x64\x3b\x0d\
\x0a\x20\x20\x20\x20\x62\x6f\x72\x64\x65\x72\x2d\x77\x69\x64\x74\
\x68\x3a\x20\x30\x20\x31\x70\x78\x20\x30\x20\x30\x3b\x0d\x0a\x20\
\x20\x20\x20\x70\x61\x64\x64\x69\x6e\x67\x3a\x20\x30\x20\x30\x70\
\x78\x3b\x0d\x0a\x7d\x0d\x0a\x0d\x0a\x61\x64\x73\x2d\x2d\x43\x44\
\x6f\x63\x6b\x57\x69\x64\x67\x65\x74\x54\x61\x62\x5b\x61\x63\x74\
\x69\x76\x65\x54\x61\x62\x3d\x22\x74\x72\x75\x65\x22\x5d\x0d\x0a\
\x7b\x0d\x0a\x20\x20\x20\x20\x62\x61\x63\x6b\x67\x72\x6f\x75\x6e\
\x64\x3a\x20\x71\x6c\x69\x6e\x65\x61\x72\x67\x72\x61\x64\x69\x65\
\x6e\x74\x28\x73\x70\x72\x65\x61\x64\x3a\x70\x61\x64\x2c\x20\x78\
\x31\x3a\x30\x2c\x20\x79\x31\x3a\x30\x2c\x20\x78\x32\x3a\x30\x2c\
\x20\x79\x32\x3a\x30\x2e\x35\x2c\x20\x73\x74\x6f\x70\x3a\x30\x20\
\x70\x61\x6c\x65\x74\x74\x65\x28\x77\x69\x6e\x64\x6f\x77\x29\x2c\
\x20\x73\x74\x6f\x70\x3a\x31\x20\x70\x61\x6c\x65\x74\x74\x65\x28\
\x6c\x69\x67\x68\x74\x29\x29\x3b\x0d\x0a\x20\x20\x20\x20\x2f\x2a\
\x62\x61\x63\x6b\x67\x72\x6f\x75\x6e\x64\x3a\x20\x70\x61\x6c\x65\
\x74\x74\x65\x28\x68\x69\x67\x68\x6c\x69\x67\x68\x74\x29\x3b\x2a\
\x2f\x0d\x0a\x7d\x0d\x0a\x0d\x0a\x61\x64\x73\x2d\x2d\x43\x44\x6f\
\x63\x6b\x57\x69\x64\x67\x65\x74\x54\x61\x62\x20\x51\x4c\x61\x62\
\x65\x6c\x0d\x0a\x7b\x0d\x0a\x20\x20\x20\x20\x63\x6f\x6c\x6f\x72\
\x3a\x20\x70\x61\x6c\x65\x74\x74\x65\x28\x64\x61\x72\x6b\x29\x3b\
\x0d\x0a\x7d\x0d\x0a\x0d\x0a\x61\x64\x73\x2d\x2d\x43\x44\x6f\x63\
\x6b\x57\x69\x64\x67\x65\x74\x54\x61\x62\x5b\x61\x63\x74\x69\x76\
\x65\x54\x61\x62\x3d\x22\x74\x72\x75\x65\x22\x5d\x20\x51\x4c\x61\
\x62\x65\x6c\x0d\x0a\x7b\x0d\x0a\x20\x20\x20\x20\x63\x6f\x6c\x6f\
\x72\x3a\x20\x70\x61\x6c\x65\x74\x74\x65\x28\x66\x6f\x72\x65\x67\
\x72\x6f\x75\x6e\x64\x29\x3b\x0d\x0a\x7d\x0d\x0a\x0d\x0a\x61\x64\
\x73\x2d\x2d\x43\x44\x6f\x63\x6b\x57\x69\x64\x67\x65\x74\x0d\x0a\
\x7b\x0d\x0a\x20\x20\x20\x20\x62\x61\x63\x6b\x67\x72\x6f\x75\x6e\
\x64\x3a\x20\x70\x61\x6c\x65\x74\x74\x65\x28\x6c\x69\x67\x68\x74\
\x29\x3b\x0d\x0a\x20\x20\x20\x20\x62\x6f\x72\x64\x65\x72\x2d\x63\
\x6f\x6c\x6f\x72\x3a\x20\x70\x61\x6c\x65\x74\x74\x65\x28\x6c\x69\
\x67\x68\x74\x29\x3b\x0d\x0a\x20\x20\x20\x20\x62\x6f\x72\x64\x65\
\x72\x2d\x73\x74\x79\x6c\x65\x3a\x20\x73\x6f\x6c\x69\x64\x3b\x0d\
\x0a\x20\x20\x20\x20\x62\x6f\x72\x64\x65\x72\x2d\x77\x69\x64\x74\
\x68\x3a\x20\x31\x70\x78\x20\x30\x20\x30\x20\x30\x3b\x0d\x0a\x7d\
\x0d\x0a\x0d\x0a\x23\x74\x61\x62\x73\x4d\x65\x6e\x75\x42\x75\x74\
\x74\x6f\x6e\x2c\x0d\x0a\x23\x63\x6c\x6f\x73\x65\x42\x75\x74\x74\
\x6f\x6e\x2c\x0d\x0a\x23\x75\x6e\x64\x6f\x63\x6b\x42\x75\x74\x74\
\x6f\x6e\x0d\x0a\x7b\x0d\x0a\x09\x70\x61\x64\x64\x69\x6e\x67\x3a\
\x20\x30\x70\x78\x20\x2d\x32\x70\x78\x3b\x0d\x0a\x7d\x0d\x0a\x0d\
\x0a\x0d\x0a\x51\x53\x63\x72\x6f\x6c\x6c\x41\x72\x65\x61\x23\x64\
\x6f\x63\x6b\x57\x69\x64\x67\x65\x74\x53\x63\x72\x6f\x6c\x6c\x41\
\x72\x65\x61\x0d\x0a\x7b\x0d\x0a\x09\x70\x61\x64\x64\x69\x6e\x67\
\x3a\x20\x30\x70\x78\x3b\x0d\x0a\x09\x62\x6f\x72\x64\x65\x72\x3a\
\x20\x6e\x6f\x6e\x65\x3b\x0d\x0a\x7d\x0d\x0a\x0d\x0a\x0d\x0a\x23\
\x74\x61\x62\x43\x6c\x6f\x73\x65\x42\x75\x74\x74\x6f\x6e\x0d\x0a\
\x7b\x0d\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x6d\x61\x72\x67\x69\
\x6e\x2d\x74\x6f\x70\x3a\x20\x32\x70\x78\x3b\x0d\x0a\x20\x20\x20\
\x20\x20\x20\x20\x20\x62\x61\x63\x6b\x67\x72\x6f\x75\x6e\x64\x3a\
\x20\x6e\x6f\x6e\x65\x3b\x0d\x0a\x20\x20\x20\x20\x20\x20\x20\x20\
\x62\x6f\x72\x64\x65\x72\x3a\x20\x6e\x6f\x6e\x65\x3b\x0d\x0a\x20\
\x20\x20\x20\x20\x20\x20\x20\x70\x61\x64\x64\x69\x6e\x67\x3a\x20\
\x30\x70\x78\x20\x2d\x32\x70\x78\x3b\x0d\x0a\x7d\x0d\x0a\x0d\x0a\
\x23\x74\x61\x62\x43\x6c\x6f\x73\x65\x42\x75\x74\x74\x6f\x6e\x3a\
\x68\x6f\x76\x65\x72\x0d\x0a\x7b\x0d\x0a\x20\x20\x20\x20\x20\x20\
\x20\x20\x62\x6f\x72\x64\x65\x72\x3a\x20\x31\x70\x78\x20\x73\x6f\
\x6c\x69\x64\x20\x72\x67\x62\x61\x28\x30\x2c\x20\x30\x2c\x20\x30\
\x2c\x20\x33\x32\x29\x3b\x0d\x0a\x20\x20\x20\x20\x20\x20\x20\x20\
\x62\x61\x63\x6b\x67\x72\x6f\x75\x6e\x64\x3a\x20\x72\x67\x62\x61\
\x28\x30\x2c\x20\x30\x2c\x20\x30\x2c\x20\x31\x36\x29\x3b\x0d\x0a\
\x7d\x0d\x0a\x0d\x0a\x23\x74\x61\x62\x43\x6c\x6f\x73\x65\x42\x75\
\x74\x74\x6f\x6e\x3a\x70\x72\x65\x73\x73\x65\x64\x0d\x0a\x7b\x0d\
\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x62\x61\x63\x6b\x67\x72\x6f\
\x75\x6e\x64\x3a\x20\x72\x67\x62\x61\x28\x30\x2c\x20\x30\x2c\x20\
\x30\x2c\x20\x33\x32\x29\x3b\x0d\x0a\x7d\x0d\x0a\x0d\x0a\x0d\x0a\
\
\x00\x00\x06\x30\
\x0d\
\x0a\x2f\x2a\x0d\x0a\x20\x2a\x20\x44\x65\x66\x61\x75\x6c\x74\x20\
\x73\x74\x79\x6c\x65\x20\x73\x68\x65\x65\x74\x20\x6f\x6e\x20\x57\
\x69\x6e\x64\x6f\x77\x73\x20\x50\x6c\x61\x74\x66\x6f\x72\x6d\x73\
\x0d\x0a\x20\x2a\x20\x4e\x6f\x74\x65\x3a\x20\x41\x6c\x77\x61\x79\
\x73\x20\x75\x73\x65\x20\x43\x53\x53\x2d\x63\x6c\x61\x73\x73\x65\
\x73\x20\x77\x69\x74\x68\x20\x61\x6e\x64\x20\x77\x69\x74\x68\x6f\
\x75\x74\x20\x22\x61\x64\x73\x2d\x2d\x22\x20\x6e\x61\x6d\x65\x73\
\x70\x61\x63\x65\x20\x74\x6f\x20\x73\x75\x70\x70\x6f\x72\x74\x20\
\x51\x74\x34\x20\x26\x20\x51\x74\x35\x0d\x0a\x20\x2a\x2f\x0d\x0a\
\x0d\x0a\x61\x64\x73\x2d\x2d\x43\x44\x6f\x63\x6b\x43\x6f\x6e\x74\
\x61\x69\x6e\x65\x72\x57\x69\x64\x67\x65\x74\x0d\x0a\x7b\x0d\x0a\
\x20\x20\x20\x20\x62\x61\x63\x6b\x67\x72\x6f\x75\x6e\x64\x3a\x20\
\x70\x61\x6c\x65\x74\x74\x65\x28\x64\x61\x72\x6b\x29\x3b\x0d\x0a\
\x7d\x0d\x0a\x0d\x0a\x61\x64\x73\x2d\x2d\x43\x44\x6f\x63\x6b\x43\
\x6f\x6e\x74\x61\x69\x6e\x65\x72\x57\x69\x64\x67\x65\x74\x20\x51\
\x53\x70\x6c\x69\x74\x74\x65\x72\x3a\x3a\x68\x61\x6e\x64\x6c\x65\
\x0d\x0a\x7b\x0d\x0a\x20\x20\x20\x20\x62\x61\x63\x6b\x67\x72\x6f\
\x75\x6e\x64\x3a\x20\x70\x61\x6c\x65\x74\x74\x65\x28\x64\x61\x72\
\x6b\x29\x3b\x0d\x0a\x7d\x0d\x0a\x0d\x0a\x61\x64\x73\x2d\x2d\x43\
\x44\x6f\x63\x6b\x41\x72\x65\x61\x57\x69\x64\x67\x65\x74\x0d\x0a\
\x7b\x0d\x0a\x20\x20\x20\x20\x62\x61\x63\x6b\x67\x72\x6f\x75\x6e\
\x64\x3a\x20\x70\x61\x6c\x65\x74\x74\x65\x28\x77\x69\x6e\x64\x6f\
\x77\x29\x3b\x0d\x0a\x20\x20\x20\x20\x62\x6f\x72\x64\x65\x72\x3a\
\x20\x31\x70\x78\x20\x73\x6f\x6c\x69\x64\x20\x77\x68\x69\x74\x65\
\x3b\x0d\x0a\x7d\x0d\x0a\x0d\x0a\x61\x64\x73\x2d\x2d\x43\x44\x6f\
\x63\x6b\x41\x72\x65\x61\x57\x69\x64\x67\x65\x74\x20\x23\x74\x61\
\x62\x73\x4d\x65\x6e\x75\x42\x75\x74\x74\x6f\x6e\x3a\x3a\x6d\x65\
\x6e\x75\x2d\x69\x6e\x64\x69\x63\x61\x74\x6f\x72\x0d\x0a\x7b\x0d\
\x0a\x20\x20\x20\x20\x69\x6d\x61\x67\x65\x3a\x20\x6e\x6f\x6e\x65\
\x3b\x0d\x0a\x7d\x0d\x0a\x0d\x0a\x0d\x0a\x61\x64\x73\x2d\x2d\x43\
\x44\x6f\x63\x6b\x57\x69\x64\x67\x65\x74\x54\x61\x62\x0d\x0a\x7b\
\x0d\x0a\x20\x20\x20\x20\x62\x61\x63\x6b\x67\x72\x6f\x75\x6e\x64\
\x3a\x20\x70\x61\x6c\x65\x74\x74\x65\x28\x77\x69\x6e\x64\x6f\x77\
\x29\x3b\x0d\x0a\x20\x20\x20\x20\x62\x6f\x72\x64\x65\x72\x2d\x63\
\x6f\x6c\x6f\x72\x3a\x20\x70\x61\x6c\x65\x74\x74\x65\x28\x6c\x69\
\x67\x68\x74\x29\x3b\x0d\x0a\x20\x20\x20\x20\x62\x6f\x72\x64\x65\
\x72\x2d\x73\x74\x79\x6c\x65\x3a\x20\x73\x6f\x6c\x69\x64\x3b\x0d\
\x0a\x20\x20\x20\x20\x62\x6f\x72\x64\x65\x72\x2d\x77\x69\x64\x74\
\x68\x3a\x20\x30\x20\x31\x70\x78\x20\x30\x20\x30\x3b\x0d\x0a\x20\
\x20\x20\x20\x70\x61\x64\x64\x69\x6e\x67\x3a\x20\x30\x20\x30\x70\
\x78\x3b\x0d\x0a\x7d\x0d\x0a\x0d\x0a\x61\x64\x73\x2d\x2d\x43\x44\
\x6f\x63\x6b\x57\x69\x64\x67\x65\x74\x54\x61\x62\x5b\x61\x63\x74\
\x69\x76\x65\x54\x61\x62\x3d\x22\x74\x72\x75\x65\x22\x5d\x0d\x0a\
\x7b\x0d\x0a\x20\x20\x20\x20\x62\x61\x63\x6b\x67\x72\x6f\x75\x6e\
\x64\x3a\x20\x71\x6c\x69\x6e\x65\x61\x72\x67\x72\x61\x64\x69\x65\
\x6e\x74\x28\x73\x70\x72\x65\x61\x64\x3a\x70\x61\x64\x2c\x20\x78\
\x31\x3a\x30\x2c\x20\x79\x31\x3a\x30\x2c\x20\x78\x32\x3a\x30\x2c\
\x20\x79\x32\x3a\x30\x2e\x35\x2c\x20\x73\x74\x6f\x70\x3a\x30\x20\
\x70\x61\x6c\x65\x74\x74\x65\x28\x77\x69\x6e\x64\x6f\x77\x29\x2c\
\x20\x73\x74\x6f\x70\x3a\x31\x20\x70\x61\x6c\x65\x74\x74\x65\x28\
\x6c\x69\x67\x68\x74\x29\x29\x3b\x0d\x0a\x20\x20\x20\x20\x2f\x2a\
\x62\x61\x63\x6b\x67\x72\x6f\x75\x6e\x64\x3a\x20\x70\x61\x6c\x65\
\x74\x74\x65\x28\x68\x69\x67\x68\x6c\x69\x67\x68\x74\x29\x3b\x2a\
\x2f\x0d\x0a\x7d\x0d\x0a\x0d\x0a\x61\x64\x73\x2d\x2d\x43\x44\x6f\
\x63\x6b\x57\x69\x64\x67\x65\x74\x54\x61\x62\x20\x51\x4c\x61\x62\
\x65\x6c\x0d\x0a\x7b\x0d\x0a\x20\x20\x20\x20\x63\x6f\x6c\x6f\x72\
\x3a\x20\x70\x61\x6c\x65\x74\x74\x65\x28\x64\x61\x72\x6b\x29\x3b\
\x0d\x0a\x7d\x0d\x0a\x0d\x0a\x61\x64\x73\x2d\x2d\x43\x44\x6f\x63\
\x6b\x57\x69\x64\x67\x65\x74\x54\x61\x62\x5b\x61\x63\x74\x69\x76\
\x65\x54\x61\x62\x3d\x22\x74\x72\x75\x65\x22\x5d\x20\x51\x4c\x61\
\x62\x65\x6c\x0d\x0a\x7b\x0d\x0a\x20\x20\x20\x20\x63\x6f\x6c\x6f\
\x72\x3a\x20\x70\x61\x6c\x65\x74\x74\x65\x28\x66\x6f\x72\x65\x67\
\x72\x6f\x75\x6e\x64\x29\x3b\x0d\x0a\x7d\x0d\x0a\x0d\x0a\x61\x64\
\x73\x2d\x2d\x43\x44\x6f\x63\x6b\x57\x69\x64\x67\x65\x74\x0d\x0a\
\x7b\x0d\x0a\x20\x20\x20\x20\x62\x61\x63\x6b\x67\x72\x6f\x75\x6e\
\x64\x3a\x20\x70\x61\x6c\x65\x74\x74\x65\x28\x6c\x69\x67\x68\x74\
\x29\x3b\x0d\x0a\x20\x20\x20\x20\x62\x6f\x72\x64\x65\x72\x2d\x63\
\x6f\x6c\x6f\x72\x3a\x20\x70\x61\x6c\x65\x74\x74\x65\x28\x6c\x69\
\x67\x68\x74\x29\x3b\x0d\x0a\x20\x20\x20\x20\x62\x6f\x72\x64\x65\
\x72\x2d\x73\x74\x79\x6c\x65\x3a\x20\x73\x6f\x6c\x69\x64\x3b\x0d\
\x0a\x20\x20\x20\x20\x62\x6f\x72\x64\x65\x72\x2d\x77\x69\x64\x74\
\x68\x3a\x20\x31\x70\x78\x20\x30\x20\x30\x20\x30\x3b\x0d\x0a\x7d\
\x0d\x0a\x0d\x0a\x23\x74\x61\x62\x73\x4d\x65\x6e\x75\x42\x75\x74\
\x74\x6f\x6e\x2c\x0d\x0a\x23\x63\x6c\x6f\x73\x65\x42\x75\x74\x74\
\x6f\x6e\x2c\x0d\x0a\x23\x75\x6e\x64\x6f\x63\x6b\x42\x75\x74\x74\
\x6f\x6e\x0d\x0a\x7b\x0d\x0a\x09\x70\x61\x64\x64\x69\x6e\x67\x3a\
\x20\x30\x70\x78\x20\x2d\x32\x70\x78\x3b\x0d\x0a\x7d\x0d\x0a\x0d\
\x0a\x0d\x0a\x51\x53\x63\x72\x6f\x6c\x6c\x41\x72\x65\x61\x23\x64\
\x6f\x63\x6b\x57\x69\x64\x67\x65\x74\x53\x63\x72\x6f\x6c\x6c\x41\
\x72\x65\x61\x0d\x0a\x7b\x0d\x0a\x09\x70\x61\x64\x64\x69\x6e\x67\
\x3a\x20\x30\x70\x78\x3b\x0d\x0a\x09\x62\x6f\x72\x64\x65\x72\x3a\
\x20\x6e\x6f\x6e\x65\x3b\x0d\x0a\x7d\x0d\x0a\x0d\x0a\x0d\x0a\x23\
\x74\x61\x62\x43\x6c\x6f\x73\x65\x42\x75\x74\x74\x6f\x6e\x0d\x0a\
\x7b\x0d\x0a\x09\x6d\x61\x72\x67\x69\x6e\x2d\x74\x6f\x70\x3a\x20\
\x32\x70\x78\x3b\x0d\x0a\x09\x62\x61\x63\x6b\x67\x72\x6f\x75\x6e\
\x64\x3a\x20\x6e\x6f\x6e\x65\x3b\x0d\x0a\x09\x62\x6f\x72\x64\x65\
\x72\x3a\x20\x6e\x6f\x6e\x65\x3b\x0d\x0a\x09\x70\x61\x64\x64\x69\
\x6e\x67\x3a\x20\x30\x70\x78\x20\x2d\x32\x70\x78\x3b\x0d\x0a\x7d\
\x0d\x0a\x0d\x0a\x23\x74\x61\x62\x43\x6c\x6f\x73\x65\x42\x75\x74\
\x74\x6f\x6e\x3a\x68\x6f\x76\x65\x72\x0d\x0a\x7b\x0d\x0a\x09\x62\
\x6f\x72\x64\x65\x72\x3a\x20\x31\x70\x78\x20\x73\x6f\x6c\x69\x64\
\x20\x72\x67\x62\x61\x28\x30\x2c\x20\x30\x2c\x20\x30\x2c\x20\x33\
\x32\x29\x3b\x0d\x0a\x09\x62\x61\x63\x6b\x67\x72\x6f\x75\x6e\x64\
\x3a\x20\x72\x67\x62\x61\x28\x30\x2c\x20\x30\x2c\x20\x30\x2c\x20\
\x31\x36\x29\x3b\x0d\x0a\x7d\x0d\x0a\x0d\x0a\x23\x74\x61\x62\x43\
\x6c\x6f\x73\x65\x42\x75\x74\x74\x6f\x6e\x3a\x70\x72\x65\x73\x73\
\x65\x64\x0d\x0a\x7b\x0d\x0a\x09\x62\x61\x63\x6b\x67\x72\x6f\x75\
\x6e\x64\x3a\x20\x72\x67\x62\x61\x28\x30\x2c\x20\x30\x2c\x20\x30\
\x2c\x20\x33\x32\x29\x3b\x0d\x0a\x7d\x0d\x0a\x0d\x0a\x0d\x0a\
"
qt_resource_name = b"\
\x00\x03\
\x00\x00\x67\xb3\
\x00\x61\
\x00\x64\x00\x73\
\x00\x0b\
\x0c\x6b\x3c\xf3\
\x00\x73\
\x00\x74\x00\x79\x00\x6c\x00\x65\x00\x73\x00\x68\x00\x65\x00\x65\x00\x74\x00\x73\
\x00\x06\
\x07\x03\x7d\xc3\
\x00\x69\
\x00\x6d\x00\x61\x00\x67\x00\x65\x00\x73\
\x00\x10\
\x08\x7c\xee\x07\
\x00\x63\
\x00\x6c\x00\x6f\x00\x73\x00\x65\x00\x2d\x00\x62\x00\x75\x00\x74\x00\x74\x00\x6f\x00\x6e\x00\x2e\x00\x73\x00\x76\x00\x67\
\x00\x19\
\x03\x4c\x6a\xc7\
\x00\x63\
\x00\x6c\x00\x6f\x00\x73\x00\x65\x00\x2d\x00\x62\x00\x75\x00\x74\x00\x74\x00\x6f\x00\x6e\x00\x2d\x00\x64\x00\x69\x00\x73\x00\x61\
\x00\x62\x00\x6c\x00\x65\x00\x64\x00\x2e\x00\x73\x00\x76\x00\x67\
\x00\x11\
\x0c\x15\xf2\x83\
\x00\x64\
\x00\x65\x00\x66\x00\x61\x00\x75\x00\x6c\x00\x74\x00\x5f\x00\x6c\x00\x69\x00\x6e\x00\x75\x00\x78\x00\x2e\x00\x63\x00\x73\x00\x73\
\
\x00\x0b\
\x0c\xe2\x33\xa3\
\x00\x64\
\x00\x65\x00\x66\x00\x61\x00\x75\x00\x6c\x00\x74\x00\x2e\x00\x63\x00\x73\x00\x73\
"
qt_resource_struct_v1 = b"\
\x00\x00\x00\x00\x00\x02\x00\x00\x00\x01\x00\x00\x00\x01\
\x00\x00\x00\x00\x00\x02\x00\x00\x00\x02\x00\x00\x00\x02\
\x00\x00\x00\x28\x00\x02\x00\x00\x00\x02\x00\x00\x00\x06\
\x00\x00\x00\x0c\x00\x02\x00\x00\x00\x02\x00\x00\x00\x04\
\x00\x00\x00\x98\x00\x00\x00\x00\x00\x01\x00\x00\x17\x03\
\x00\x00\x00\xc0\x00\x00\x00\x00\x00\x01\x00\x00\x1d\x68\
\x00\x00\x00\x60\x00\x00\x00\x00\x00\x01\x00\x00\x0b\x08\
\x00\x00\x00\x3a\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\
"
qt_resource_struct_v2 = b"\
\x00\x00\x00\x00\x00\x02\x00\x00\x00\x01\x00\x00\x00\x01\
\x00\x00\x00\x00\x00\x00\x00\x00\
\x00\x00\x00\x00\x00\x02\x00\x00\x00\x02\x00\x00\x00\x02\
\x00\x00\x00\x00\x00\x00\x00\x00\
\x00\x00\x00\x28\x00\x02\x00\x00\x00\x02\x00\x00\x00\x06\
\x00\x00\x00\x00\x00\x00\x00\x00\
\x00\x00\x00\x0c\x00\x02\x00\x00\x00\x02\x00\x00\x00\x04\
\x00\x00\x00\x00\x00\x00\x00\x00\
\x00\x00\x00\x98\x00\x00\x00\x00\x00\x01\x00\x00\x17\x03\
\x00\x00\x01\x6d\xaf\xb0\x91\x61\
\x00\x00\x00\xc0\x00\x00\x00\x00\x00\x01\x00\x00\x1d\x68\
\x00\x00\x01\x6d\xaf\xb0\x91\x60\
\x00\x00\x00\x60\x00\x00\x00\x00\x00\x01\x00\x00\x0b\x08\
\x00\x00\x01\x6d\xaf\xb0\x91\x5e\
\x00\x00\x00\x3a\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\
\x00\x00\x01\x6d\xaf\xb0\x91\x5e\
"
qt_version = QtCore.qVersion().split('.')
if qt_version < ['5', '8', '0']:
rcc_version = 1
qt_resource_struct = qt_resource_struct_v1
else:
rcc_version = 2
qt_resource_struct = qt_resource_struct_v2
def qInitResources():
QtCore.qRegisterResourceData(rcc_version, qt_resource_struct, qt_resource_name, qt_resource_data)
def qCleanupResources():
QtCore.qUnregisterResourceData(rcc_version, qt_resource_struct, qt_resource_name, qt_resource_data)
qInitResources()

316
demo.py Normal file
View File

@ -0,0 +1,316 @@
import datetime
import logging
from PyQt5.QtCore import (QCoreApplication, QDir, Qt, QSettings, QSignalBlocker,
QRect)
from PyQt5.QtGui import QGuiApplication
from PyQt5.QtWidgets import (QCalendarWidget, QFileSystemModel, QFrame, QLabel,
QMenu, QTreeView, QAction, QWidgetAction,
QComboBox, QStyle, QSizePolicy, QInputDialog)
from PyQt5 import QtWidgets
from PyQtAds import QtAds
class _State:
label_count = 0
calendar_count = 0
file_system_count = 0
def create_long_text_label_dock_widget(view_menu: QMenu) -> QtAds.CDockWidget:
'''
Create long text label dock widget
Parameters
----------
view_menu : QMenu
Returns
-------
value : QtAds.CDockWidget
'''
label = QLabel()
label.setWordWrap(True)
label.setAlignment(Qt.AlignTop | Qt.AlignLeft)
label.setText('''\
Label {} {} - Lorem ipsum dolor sit amet, consectetuer
adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa. Cum
sociis natoque penatibus et magnis dis parturient montes, nascetur
ridiculus mus. Donec quam felis, ultricies nec, pellentesque eu, pretium
quis, sem. Nulla consequat massa quis enim. Donec pede justo, fringilla
vel, aliquet nec, vulputate eget, arcu. In enim justo, rhoncus ut,
imperdiet a, venenatis vitae, justo. Nullam dictum felis eu pede mollis
pretium. Integer tincidunt. Cras dapibus. Vivamus elementum semper nisi.
Aenean vulputate eleifend tellus. Aenean leo ligula, porttitor eu,
consequat vitae, eleifend ac, enim. Aliquam lorem ante, dapibus in, viverra
quis, feugiat a, tellus. Phasellus viverra nulla ut metus varius laoreet.
'''.format(_State.label_count, str(datetime.datetime.now())))
_State.label_count += 1
dock_widget = QtAds.CDockWidget("Label {}".format(_State.label_count))
dock_widget.setWidget(label)
view_menu.addAction(dock_widget.toggleViewAction())
return dock_widget
def create_calendar_dock_widget(view_menu: QMenu) -> QtAds.CDockWidget:
'''
Create calendar dock widget
Parameters
----------
view_menu : QMenu
Returns
-------
value : QtAds.CDockWidget
'''
widget = QCalendarWidget()
dock_widget = QtAds.CDockWidget("Calendar {}".format(_State.calendar_count))
_State.calendar_count += 1
dock_widget.setWidget(widget)
dock_widget.setToggleViewActionMode(QtAds.CDockWidget.ActionModeShow)
view_menu.addAction(dock_widget.toggleViewAction())
return dock_widget
def create_file_system_tree_dock_widget(view_menu: QMenu) -> QtAds.CDockWidget:
'''
Create file system tree dock widget
Parameters
----------
view_menu : QMenu
Returns
-------
value : QtAds.CDockWidget
'''
widget = QTreeView()
widget.setFrameShape(QFrame.NoFrame)
m = QFileSystemModel(widget)
m.setRootPath(QDir.currentPath())
widget.setModel(m)
dock_widget = QtAds.CDockWidget("Filesystem {}".format(_State.file_system_count))
_State.file_system_count += 1
dock_widget.setWidget(widget)
view_menu.addAction(dock_widget.toggleViewAction())
return dock_widget
class MainWindow(QtWidgets.QMainWindow):
save_perspective_action: QAction
perspective_list_action: QWidgetAction
perspective_combo_box: QComboBox
dock_manager: QtAds.CDockManager
def __init__(self, parent=None):
super().__init__(parent)
self.save_perspective_action = None
self.perspective_list_action = None
self.perspective_combo_box = None
self.dock_manager = None
self.setup_ui()
self.dock_manager = QtAds.CDockManager(self)
self.perspective_combo_box.activated[str].connect(self.dock_manager.openPerspective)
self.create_content()
self.resize(800, 600)
self.restore_state()
self.restore_perspectives()
def setup_ui(self):
self.setObjectName("MainWindow")
self.resize(400, 300)
self.setDockOptions(QtWidgets.QMainWindow.AllowTabbedDocks)
self.centralWidget = QtWidgets.QWidget(self)
self.centralWidget.setObjectName("centralWidget")
self.setCentralWidget(self.centralWidget)
self.status_bar = QtWidgets.QStatusBar(self)
self.status_bar.setObjectName("statusBar")
self.setStatusBar(self.status_bar)
self.menu_bar = QtWidgets.QMenuBar(self)
self.menu_bar.setGeometry(QRect(0, 0, 400, 21))
self.menu_bar.setObjectName("menuBar")
self.menu_file = QtWidgets.QMenu(self.menu_bar)
self.menu_file.setObjectName("menuFile")
self.menu_view = QtWidgets.QMenu(self.menu_bar)
self.menu_view.setObjectName("menuView")
self.menu_about = QtWidgets.QMenu(self.menu_bar)
self.menu_about.setObjectName("menuAbout")
self.setMenuBar(self.menu_bar)
self.tool_bar = QtWidgets.QToolBar(self)
self.tool_bar.setObjectName("toolBar")
self.addToolBar(Qt.TopToolBarArea, self.tool_bar)
self.action_exit = QtWidgets.QAction(self)
self.action_exit.setObjectName("actionExit")
self.action_save_state = QtWidgets.QAction(self)
self.action_save_state.setObjectName("actionSaveState")
self.action_save_state.triggered.connect(self.saveState)
self.action_restore_state = QtWidgets.QAction(self)
self.action_restore_state.setObjectName("actionRestoreState")
self.action_restore_state.triggered.connect(self.restore_state)
self.menu_file.addAction(self.action_exit)
self.menu_file.addAction(self.action_save_state)
self.menu_file.addAction(self.action_restore_state)
self.menu_bar.addAction(self.menu_file.menuAction())
self.menu_bar.addAction(self.menu_view.menuAction())
self.menu_bar.addAction(self.menu_about.menuAction())
self.setWindowTitle("MainWindow")
self.menu_file.setTitle("File")
self.menu_view.setTitle("View")
self.menu_about.setTitle("About")
self.tool_bar.setWindowTitle("toolBar")
self.action_exit.setText("Exit")
self.action_save_state.setText("Save State")
self.action_restore_state.setText("Restore State")
self.create_actions()
def create_actions(self):
'''
Creates the toolbar actions
'''
self.tool_bar.addAction(self.action_save_state)
self.action_save_state.setIcon(self.style().standardIcon(QStyle.SP_DialogSaveButton))
self.tool_bar.addAction(self.action_restore_state)
self.action_restore_state.setIcon(self.style().standardIcon(QStyle.SP_DialogOpenButton))
self.save_perspective_action = QAction("Save Perspective", self)
self.save_perspective_action.triggered.connect(self.save_perspective)
self.perspective_list_action = QWidgetAction(self)
self.perspective_combo_box = QComboBox(self)
self.perspective_combo_box.setSizeAdjustPolicy(QComboBox.AdjustToContents)
self.perspective_combo_box.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Preferred)
self.perspective_list_action.setDefaultWidget(self.perspective_combo_box)
self.tool_bar.addSeparator()
self.tool_bar.addAction(self.perspective_list_action)
self.tool_bar.addAction(self.save_perspective_action)
def create_content(self):
'''
Fill the dock manager with dock widgets
'''
# Test container docking
view_menu = self.menu_view
dock_widget = create_calendar_dock_widget(view_menu)
dock_widget.setIcon(self.style().standardIcon(QStyle.SP_DialogOpenButton))
dock_widget.setFeature(QtAds.CDockWidget.DockWidgetClosable, False)
self.dock_manager.addDockWidget(QtAds.LeftDockWidgetArea, dock_widget)
self.dock_manager.addDockWidget(QtAds.LeftDockWidgetArea, create_long_text_label_dock_widget(view_menu))
file_system_widget = create_file_system_tree_dock_widget(view_menu)
tool_bar = file_system_widget.createDefaultToolBar()
tool_bar.addAction(self.action_save_state)
tool_bar.addAction(self.action_restore_state)
self.dock_manager.addDockWidget(QtAds.BottomDockWidgetArea, file_system_widget)
file_system_widget = create_file_system_tree_dock_widget(view_menu)
tool_bar = file_system_widget.createDefaultToolBar()
tool_bar.addAction(self.action_save_state)
tool_bar.addAction(self.action_restore_state)
file_system_widget.setFeature(QtAds.CDockWidget.DockWidgetMovable, False)
top_dock_area = self.dock_manager.addDockWidget(QtAds.TopDockWidgetArea, file_system_widget)
dock_widget = create_calendar_dock_widget(view_menu)
dock_widget.setFeature(QtAds.CDockWidget.DockWidgetClosable, False)
dock_widget.setTabToolTip("Tab ToolTip\nHodie est dies magna")
self.dock_manager.addDockWidget(QtAds.CenterDockWidgetArea, dock_widget, top_dock_area)
# Test dock area docking
right_dock_area = self.dock_manager.addDockWidget(
QtAds.RightDockWidgetArea,
create_long_text_label_dock_widget(view_menu), top_dock_area)
self.dock_manager.addDockWidget(
QtAds.TopDockWidgetArea,
create_long_text_label_dock_widget(view_menu), right_dock_area)
bottom_dock_area = self.dock_manager.addDockWidget(
QtAds.BottomDockWidgetArea,
create_long_text_label_dock_widget(view_menu), right_dock_area)
self.dock_manager.addDockWidget(
QtAds.RightDockWidgetArea,
create_long_text_label_dock_widget(view_menu), right_dock_area)
self.dock_manager.addDockWidget(
QtAds.CenterDockWidgetArea,
create_long_text_label_dock_widget(view_menu), bottom_dock_area)
def save_state(self):
'''
Saves the dock manager state and the main window geometry
'''
settings = QSettings("Settings.ini", QSettings.IniFormat)
settings.setValue("mainWindow/Geometry", self.saveGeometry())
settings.setValue("mainWindow/State", self.saveState())
settings.setValue("mainWindow/DockingState", self.dock_manager.saveState())
def save_perspectives(self):
'''
Save the list of perspectives
'''
settings = QSettings("Settings.ini", QSettings.IniFormat)
self.dock_manager.savePerspectives(settings)
def restore_state(self):
'''
Restores the dock manager state
'''
settings = QSettings("Settings.ini", QSettings.IniFormat)
geom = settings.value("mainWindow/Geometry")
if geom is not None:
self.restoreGeometry(geom)
state = settings.value("mainWindow/State")
if state is not None:
self.restoreState(state)
state = settings.value("mainWindow/DockingState")
if state is not None:
self.dock_manager.restore_state(state)
def restore_perspectives(self):
'''
Restore the perspective listo of the dock manager
'''
settings = QSettings("Settings.ini", QSettings.IniFormat)
self.dock_manager.loadPerspectives(settings)
self.perspective_combo_box.clear()
self.perspective_combo_box.addItems(self.dock_manager.perspectiveNames())
def save_perspective(self):
perspective_name, ok = QInputDialog.getText(self, 'Save perspective', 'Enter unique name:')
if ok and perspective_name:
self.dock_manager.addPerspective(perspective_name)
_ = QSignalBlocker(self.perspective_combo_box)
self.perspective_combo_box.clear()
self.perspective_combo_box.addItems(self.dock_manager.perspectiveNames())
self.perspective_combo_box.setCurrentText(perspective_name)
self.save_perspectives()
def main(app_):
main_window = MainWindow()
main_window.show()
state = main_window.dock_manager.saveState()
# print('This is what the saved state looks like in XML:')
# print(str(state, 'utf-8'))
# print()
# main_window.dock_manager.restore_state(state)
return main_window
if __name__ == '__main__':
# logging.basicConfig(level='DEBUG')
QCoreApplication.setAttribute(Qt.AA_UseHighDpiPixmaps)
QGuiApplication.setAttribute(Qt.AA_EnableHighDpiScaling)
app = QtWidgets.QApplication([])
window = main(app)
window.show()
app.exec_()

41
recipes/meta.yaml Normal file
View File

@ -0,0 +1,41 @@
{% set data = load_setup_py_data() %}
package:
name: pyqtads
version: {{ data.get('version') }}
source:
path: ../
build:
number: 0
script: python setup.py install --single-version-externally-managed --record=record.txt --conda-recipe
requirements:
build:
- python
- setuptools
- pyqt>=5.9
- sip>=4.19
run:
- python
- pyqt>=5.9
- sip>=4.19
- pywin32 [win]
test:
imports:
- PyQtAds
about:
home: {{ data.get('url') }}
license: {{ data.get('license') }}
license_family: LGPL
license_file: 'LICENSE.md'
summary: {{ data.get('description') }}
description: {{ data.get('description') }}
doc_url: ''
dev_url: {{ data.get('url') }}
extra:
recipe-maintainers: 'nicolas.elie@cnrs.fr'

342
setup.py Normal file
View File

@ -0,0 +1,342 @@
import os
import sys
import shlex
import subprocess
import glob
from setuptools import setup, find_packages
from setuptools.extension import Extension
from distutils import sysconfig, dir_util, spawn, log
from distutils.dep_util import newer
import sipdistutils
import sipconfig
from PyQt5.QtCore import PYQT_CONFIGURATION
from PyQt5.pyrcc_main import processResourceFile
MAJOR = 2
MINOR = 5
MICRO = 1
ISRELEASED = True
VERSION = '%d.%d.%d' % (MAJOR, MINOR, MICRO)
MODULE_NAME = "ads"
SRC_PATH = "PyQtAds"
REQUIRE_PYQT = True
if "--conda-recipe" in sys.argv:
REQUIRE_PYQT = False
sys.argv.remove("--conda-recipe")
class HostPythonConfiguration(object):
def __init__(self):
self.platform = sys.platform
self.version = sys.hexversion>>8
self.inc_dir = sysconfig.get_python_inc()
self.venv_inc_dir = sysconfig.get_python_inc(prefix=sys.prefix)
self.module_dir = sysconfig.get_python_lib(plat_specific=1)
if sys.platform == 'win32':
self.data_dir = sys.prefix
self.lib_dir = sys.prefix +'\\libs'
else:
self.data_dir = sys.prefix + '/share'
self.lib_dir = sys.prefix + '/lib'
class TargetQtConfiguration(object):
def __init__(self, qmake):
pipe = os.popen(' '.join([qmake, '-query']))
for l in pipe:
l = l.strip()
tokens = l.split(':', 1)
if isinstance(tokens, list):
if len(tokens) != 2:
error("Unexpected output from qmake: '%s'\n" % l)
name, value = tokens
else:
name = tokens
value = None
name = name.replace('/', '_')
setattr(self, name, value)
pipe.close()
class build_ext(sipdistutils.build_ext):
description = "Builds the " + MODULE_NAME + " module."
user_options = sipdistutils.build_ext.user_options + [
('qmake-bin=', None, "Path to qmake binary"),
('sip-bin=', None, "Path to sip binary"),
('qt-include-dir=', None, "Path to Qt headers"),
('pyqt-sip-dir=', None, "Path to PyQt's SIP files"),
('pyqt-sip-flags=', None, "SIP flags used to generate PyQt bindings"),
('sip-dir=', None, "Path to module's SIP files"),
('inc-dir=', None, "Path to module's include files")
]
def initialize_options (self):
super().initialize_options()
self.qmake_bin = 'qmake'
self.sip_bin = None
self.qt_include_dir = None
self.qt_libinfix = ''
self.pyqt_sip_dir = None
self.pyqt_sip_flags = None
self.sip_files_dir = None
self.sip_inc_dir = None
self.inc_dir = None
self.pyconfig = HostPythonConfiguration()
self.qtconfig = TargetQtConfiguration(self.qmake_bin)
self.config = sipconfig.Configuration()
self.config.default_mod_dir = ("/usr/local/lib/python%i.%i/dist-packages" %
(sys.version_info.major, sys.version_info.minor))
def finalize_options (self):
super().finalize_options()
if not self.qt_include_dir:
self.qt_include_dir = self.qtconfig.QT_INSTALL_HEADERS
if not self.qt_libinfix:
try:
with open(os.path.join(self.qtconfig.QT_INSTALL_PREFIX, 'mkspecs', 'qconfig.pri'), 'r') as f:
for line in f.readlines():
if line.startswith('QT_LIBINFIX'):
self.qt_libinfix = line.split('=')[1].strip('\n').strip()
except (FileNotFoundError, IndexError):
pass
if not self.pyqt_sip_dir:
self.pyqt_sip_dir = os.path.join(self.pyconfig.data_dir, 'sip', 'PyQt5')
if not self.pyqt_sip_flags:
self.pyqt_sip_flags = PYQT_CONFIGURATION.get('sip_flags', '')
if not self.sip_files_dir:
self.sip_files_dir = os.path.abspath(os.path.join(".", "sip"))
if not self.sip_inc_dir:
self.sip_inc_dir = self.pyconfig.venv_inc_dir
if not self.inc_dir:
self.inc_dir = os.path.abspath(os.path.join(".", "src"))
if not self.qt_include_dir:
raise SystemExit('Could not find Qt5 headers. '
'Please specify via --qt-include-dir=')
if not self.pyqt_sip_dir:
raise SystemExit('Could not find PyQt SIP files. '
'Please specify containing directory via '
'--pyqt-sip-dir=')
if not self.pyqt_sip_flags:
raise SystemExit('Could not find PyQt SIP flags. '
'Please specify via --pyqt-sip-flags=')
def _find_sip(self):
"""override _find_sip to allow for manually speficied sip path."""
return self.sip_bin or super()._find_sip()
def _sip_compile(self, sip_bin, source, sbf):
cmd = [sip_bin]
if hasattr(self, 'sip_opts'):
cmd += self.sip_opts
if hasattr(self, '_sip_sipfiles_dir'):
cmd += ['-I', self._sip_sipfiles_dir()]
cmd += [
"-I", self.sip_files_dir,
"-I", self.pyqt_sip_dir,
"-I", self.sip_inc_dir,
"-I", self.inc_dir,
"-c", self._sip_output_dir(),
"-b", sbf,
"-w", "-o"]
cmd += shlex.split(self.pyqt_sip_flags) # use same SIP flags as for PyQt5
cmd.append(source)
self.spawn(cmd)
def swig_sources (self, sources, extension=None):
if not self.extensions:
return
# Add the local include directory to the include path
if extension is not None:
extension.extra_compile_args += ['-D', 'QT_CORE_LIB',
'-D', 'QT_GUI_LIB',
'-D', 'QT_WIDGETS_LIB',
'-D', 'ADS_SHARED_EXPORT']
extension.include_dirs += [self.qt_include_dir, self.inc_dir,
os.path.join(self.qt_include_dir, 'QtCore'),
os.path.join(self.qt_include_dir, 'QtGui'),
os.path.join(self.qt_include_dir, 'QtWidgets')]
extension.libraries += ['Qt5Core' + self.qt_libinfix,
'Qt5Gui' + self.qt_libinfix,
'Qt5Widgets' + self.qt_libinfix]
if sys.platform == 'win32':
extension.library_dirs += [self.qtconfig.QT_INSTALL_LIBS,
self.inc_dir, self._sip_output_dir()]
elif sys.platform == 'darwin':
extension.extra_compile_args += ['-F' + self.qtconfig.QT_INSTALL_LIBS,
'-std=c++11', '-stdlib=libc++', '-mmacosx-version-min=10.9']
extension.extra_link_args += ['-F' + self.qtconfig.QT_INSTALL_LIBS,
'-mmacosx-version-min=10.9']
elif sys.platform == 'linux':
extension.extra_compile_args += ['-std=c++11']
return super().swig_sources(sources, extension)
def build_extension(self, ext):
cppsources = [source for source in ext.sources if source.endswith(".cpp")]
dir_util.mkpath(self.build_temp, dry_run=self.dry_run)
# Run moc on all header files.
for source in cppsources:
header = source.replace(".cpp", ".h")
if os.path.exists(header):
moc_file = "moc_" + os.path.basename(header).replace(".h", ".cpp")
out_file = os.path.join(self.build_temp, moc_file)
if newer(header, out_file) or self.force:
call_arg = ["moc", "-o", out_file, header]
spawn.spawn(call_arg, dry_run=self.dry_run)
if os.path.getsize(out_file) > 0:
ext.sources.append(out_file)
# Add the temp build directory to include path, for compiler to find
# the created .moc files
ext.include_dirs += [self._sip_output_dir()]
sipdistutils.build_ext.build_extension(self, ext)
def git_version():
'''Return the git revision as a string'''
def _minimal_ext_cmd(cmd):
# construct minimal environment
env = {}
for k in ['SYSTEMROOT', 'PATH', 'HOME']:
v = os.environ.get(k)
if v is not None:
env[k] = v
# LANGUAGE is used on win32
env['LANGUAGE'] = 'C'
env['LANG'] = 'C'
env['LC_ALL'] = 'C'
out = subprocess.Popen(cmd, stdout=subprocess.PIPE, env=env).communicate()[0]
return out
try:
out = _minimal_ext_cmd(['git', 'rev-parse', 'HEAD'])
GIT_REVISION = out.strip().decode('ascii')
except OSError:
GIT_REVISION = "Unknown"
return GIT_REVISION
def get_version_info():
# Adding the git rev number needs to be done inside write_version_py(),
# otherwise the import of numpy.version messes up the build under Python 3.
FULLVERSION = VERSION
if os.path.exists('.git'):
GIT_REVISION = git_version()
elif os.path.exists(os.path.join(SRC_PATH, 'version.py')):
# must be a source distribution, use existing version file
try:
from PyQtAds.version import git_revision as GIT_REVISION
except ImportError:
raise ImportError("Unable to import git_revision. Try removing " \
"%(module)/version.py and the build directory " \
"before building." % {'module': SRC_PATH})
else:
GIT_REVISION = "Unknown"
if not ISRELEASED:
FULLVERSION += '.dev0+' + GIT_REVISION[:7]
return FULLVERSION, GIT_REVISION
def write_version_py(filename=os.path.join(SRC_PATH, '_version.py')):
cnt = ("# THIS FILE IS GENERATED FROM %(module)s SETUP.PY\n\n"
"short_version = '%(version)s'\n"
"version = '%(version)s'\n"
"full_version = '%(full_version)s'\n"
"git_revision = '%(git_revision)s'\n"
"release = %(isrelease)s\n"
"if not release:\n"
" version = full_version\n")
FULLVERSION, GIT_REVISION = get_version_info()
with open(filename, 'w') as f:
f.write(cnt % {'module': SRC_PATH,
'version': VERSION,
'full_version': FULLVERSION,
'git_revision': GIT_REVISION,
'isrelease': str(ISRELEASED)})
setup_requires = ["PyQt5"] if REQUIRE_PYQT else []
cpp_sources = glob.glob(os.path.join('src', '*.cpp'))
sip_sources = [os.path.join('sip', MODULE_NAME + '.sip')]
if sys.platform == 'linux':
cpp_sources += glob.glob(os.path.join('src', 'linux', '*.cpp'))
ext_modules = [Extension('PyQtAds.QtAds.ads', cpp_sources + sip_sources)]
install_requires = ["PyQt5"]
if sys.platform == 'win32':
install_requires.append("pywin32")
write_version_py(os.path.join(SRC_PATH, '_version.py'))
processResourceFile([os.path.join('src', 'ads.qrc')],
os.path.join(SRC_PATH, 'rc.py'), False)
with open('README.md', 'r') as f:
LONG_DESCRIPTION = f.read()
setup(
name = SRC_PATH,
author = "Nicolas Elie",
author_email = "nicolas.elie@cnrs.fr",
url = "https://github.com/githubuser0xFFFF/Qt-Advanced-Docking-System",
version = get_version_info()[0],
description = "Advanced Docking System for Qt",
long_description = LONG_DESCRIPTION,
keywords = ["qt"],
license = "LGPLv2+",
classifiers = ["Development Status :: 4 - Beta",
"Intended Audience :: Developers",
"License :: OSI Approved :: GNU Lesser General Public License v2 or later (LGPLv2+)",
"Operating System :: OS Independent",
"Topic :: Software Development :: Libraries :: Python Modules",
"Environment :: Win32 (MS Windows)",
"Environment :: MacOS X",
"Environment :: X11 Applications :: Qt",
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3.2",
"Programming Language :: Python :: 3.3",
"Programming Language :: Python :: 3.4",
"Programming Language :: Python :: 3.5",
"Programming Language :: Python :: 3.6",
"Programming Language :: Python :: 3.7"],
ext_modules = ext_modules,
cmdclass = {
'build_ext': build_ext,
},
packages = find_packages(),
setup_requires = setup_requires,
install_requires = install_requires,
zip_safe=False
)

82
simple.py Normal file
View File

@ -0,0 +1,82 @@
import logging
from PyQt5 import QtWidgets, QtCore
from PyQt5.QtCore import Qt
from PyQtAds import QtAds
class MainWindow(QtWidgets.QMainWindow):
def __init__(self, parent=None):
super().__init__(parent)
self.setup_ui()
self.dock_manager = QtAds.CDockManager(self)
self.dock_widgets = []
for label_text, area in (
('1 Top', QtAds.TopDockWidgetArea),
('2 Bottom', QtAds.BottomDockWidgetArea),
('3 Left', QtAds.LeftDockWidgetArea),
('4 Right', QtAds.RightDockWidgetArea),
):
# Create example content label - this can be any application specific
# widget
label = QtWidgets.QLabel()
label.setWordWrap(True)
label.setAlignment(Qt.AlignTop | Qt.AlignLeft)
label.setText(f"{label_text}: Lorem ipsum dolor sit amet, consectetuer adipiscing elit. ")
# Create a dock widget with the title Label 1 and set the created label
# as the dock widget content
dock_widget = QtAds.CDockWidget(label_text)
dock_widget.setWidget(label)
self.dock_widgets.append(dock_widget)
# Add the toggleViewAction of the dock widget to the menu to give
# the user the possibility to show the dock widget if it has been closed
self.menu_view.addAction(dock_widget.toggleViewAction())
# Add the dock widget to the top dock widget area
self.dock_manager.addDockWidget(area, dock_widget)
def setup_ui(self):
self.setWindowTitle("MainWindow")
self.setObjectName("MainWindow")
self.resize(400, 300)
self.central_widget = QtWidgets.QWidget(self)
self.central_widget.setObjectName("central_widget")
self.setCentralWidget(self.central_widget)
self.menu_bar = QtWidgets.QMenuBar(self)
self.menu_bar.setGeometry(QtCore.QRect(0, 0, 400, 21))
self.menu_bar.setObjectName("menuBar")
self.menu_view = QtWidgets.QMenu(self.menu_bar)
self.menu_view.setObjectName("menu_view")
self.menu_view.setTitle("View")
self.setMenuBar(self.menu_bar)
self.status_bar = QtWidgets.QStatusBar(self)
self.status_bar.setObjectName("statusBar")
self.setStatusBar(self.status_bar)
self.menu_bar.addAction(self.menu_view.menuAction())
def main(app):
main = MainWindow()
main.show()
state = main.dock_manager.saveState()
print('This is what the saved state looks like in XML:')
print(state)
print()
main.dock_manager.restoreState(state)
return main
if __name__ == '__main__':
logging.basicConfig(level='DEBUG')
app = QtWidgets.QApplication([])
window = main(app)
window.show()
print('shown')
app.exec_()

56
sip/DockAreaTabBar.sip Normal file
View File

@ -0,0 +1,56 @@
%Import QtWidgets/QtWidgetsmod.sip
%If (Qt_5_0_0 -)
namespace ads
{
class CDockAreaTabBar : QScrollArea
{
%TypeHeaderCode
#include <DockAreaTabBar.h>
%End
protected:
virtual void wheelEvent(QWheelEvent* Event);
virtual void mousePressEvent(QMouseEvent* ev);
virtual void mouseReleaseEvent(QMouseEvent* ev);
virtual void mouseMoveEvent(QMouseEvent* ev);
virtual void mouseDoubleClickEvent(QMouseEvent *event);
void startFloating(const QPoint& Offset);
ads::CFloatingDockContainer* makeAreaFloating(const QPoint& Offset,
ads::eDragState DragState);
public:
CDockAreaTabBar(ads::CDockAreaWidget* parent /TransferThis/);
virtual ~CDockAreaTabBar();
void insertTab(int Index, ads::CDockWidgetTab* Tab /Transfer/);
void removeTab(ads::CDockWidgetTab* Tab) /TransferBack/;
int count() const;
int currentIndex() const;
ads::CDockWidgetTab* currentTab() const;
ads::CDockWidgetTab* tab(int Index) const;
virtual bool eventFilter(QObject *watched, QEvent *event);
bool isTabOpen(int Index) const;
virtual QSize minimumSizeHint() const;
virtual QSize sizeHint() const;
public slots:
void setCurrentIndex(int Index);
void closeTab(int Index);
signals:
void currentChanging(int Index);
void currentChanged(int Index);
void tabBarClicked(int index);
void tabCloseRequested(int index);
void tabClosed(int index);
void tabOpened(int index);
void tabMoved(int from, int to);
void removingTab(int index);
void tabInserted(int index);
};
};
%End

32
sip/DockAreaTitleBar.sip Normal file
View File

@ -0,0 +1,32 @@
%Import QtWidgets/QtWidgetsmod.sip
%If (Qt_5_0_0 -)
namespace ads
{
class CDockAreaTitleBar : QFrame
{
%TypeHeaderCode
#include <DockAreaTitleBar.h>
%End
public slots:
void markTabsMenuOutdated();
public:
CDockAreaTitleBar(ads::CDockAreaWidget* parent /TransferThis/);
virtual ~CDockAreaTitleBar();
ads::CDockAreaTabBar* tabBar() const;
QAbstractButton* button(ads::TitleBarButton which) const;
virtual void setVisible(bool Visible);
signals:
void tabBarClicked(int index);
};
};
%End

65
sip/DockAreaWidget.sip Normal file
View File

@ -0,0 +1,65 @@
%Import QtWidgets/QtWidgetsmod.sip
%If (Qt_5_0_0 -)
namespace ads
{
class CDockAreaWidget : QFrame
{
%TypeHeaderCode
#include <DockAreaWidget.h>
%End
protected:
void insertDockWidget(int index, ads::CDockWidget* DockWidget /Transfer/, bool Activate = true);
void addDockWidget(ads::CDockWidget* DockWidget /Transfer/);
void removeDockWidget(ads::CDockWidget* DockWidget) /TransferBack/;
void toggleDockWidgetView(ads::CDockWidget* DockWidget, bool Open);
CDockWidget* nextOpenDockWidget(ads::CDockWidget* DockWidget) const;
int index(ads::CDockWidget* DockWidget);
void hideAreaWithNoVisibleContent();
void updateTitleBarVisibility();
void internalSetCurrentDockWidget(ads::CDockWidget* DockWidget /Transfer/);
void markTitleBarMenuOutdated();
protected slots:
void toggleView(bool Open);
public:
CDockAreaWidget(ads::CDockManager* DockManager /TransferThis/, ads::CDockContainerWidget* parent /TransferThis/);
virtual ~CDockAreaWidget();
ads::CDockManager* dockManager() const;
ads::CDockContainerWidget* dockContainer() const;
QRect titleBarGeometry() const;
QRect contentAreaGeometry() const;
int dockWidgetsCount() const;
QList<ads::CDockWidget*> dockWidgets() const;
int openDockWidgetsCount() const;
QList<ads::CDockWidget*> openedDockWidgets() const;
ads::CDockWidget* dockWidget(int Index) const;
int currentIndex() const;
int indexOfFirstOpenDockWidget() const;
ads::CDockWidget* currentDockWidget() const;
void setCurrentDockWidget(ads::CDockWidget* DockWidget /Transfer/);
void saveState(QXmlStreamWriter& Stream) const;
ads::CDockWidget::DockWidgetFeatures features() const;
QAbstractButton* titleBarButton(ads::TitleBarButton which) const;
virtual void setVisible(bool Visible);
public slots:
void setCurrentIndex(int index);
void closeArea();
void closeOtherAreas();
signals:
void tabBarClicked(int index);
void currentChanging(int index);
void currentChanged(int index);
void viewToggled(bool Open);
};
};
%End

154
sip/DockContainerWidget.sip Normal file
View File

@ -0,0 +1,154 @@
%Import QtWidgets/QtWidgetsmod.sip
%If (Qt_5_0_0 -)
namespace ads
{
/**
* Container that manages a number of dock areas with single dock widgets
* or tabyfied dock widgets in each area.
* Each window that support docking has a DockContainerWidget. That means
* the main application window and all floating windows are ore contain
* an DockContainerWidget.
*/
class CDockContainerWidget : QFrame
{
%TypeHeaderCode
#include <DockContainerWidget.h>
%End
protected:
virtual bool event(QEvent *e);
QSplitter* rootSplitter() const;
void createRootSplitter();
void dropFloatingWidget(ads::CFloatingDockContainer* FloatingWidget, const QPoint& TargetPos);
void addDockArea(ads::CDockAreaWidget* DockAreaWidget /Transfer/, ads::DockWidgetArea area = ads::CenterDockWidgetArea);
void removeDockArea(ads::CDockAreaWidget* area /Transfer/);
void saveState(QXmlStreamWriter& Stream) const;
bool restoreState(QXmlStreamReader& Stream, bool Testing);
ads::CDockAreaWidget* lastAddedDockAreaWidget(ads::DockWidgetArea area) const;
bool hasTopLevelDockWidget() const;
ads::CDockWidget* topLevelDockWidget() const;
ads::CDockAreaWidget* topLevelDockArea() const;
QList<ads::CDockWidget*> dockWidgets() const;
public:
/**
* Default Constructor
*/
CDockContainerWidget(ads::CDockManager* DockManager /TransferThis/, QWidget* parent /TransferThis/ = 0);
/**
* Virtual Destructor
*/
virtual ~CDockContainerWidget();
/**
* Adds dockwidget into the given area.
* If DockAreaWidget is not null, then the area parameter indicates the area
* into the DockAreaWidget. If DockAreaWidget is null, the Dockwidget will
* be dropped into the container.
* \return Returns the dock area widget that contains the new DockWidget
*/
ads::CDockAreaWidget* addDockWidget(ads::DockWidgetArea area, ads::CDockWidget* Dockwidget /Transfer/,
ads::CDockAreaWidget* DockAreaWidget /Transfer/ = 0);
/**
* Removes dockwidget
*/
void removeDockWidget(ads::CDockWidget* Dockwidget) /TransferBack/;
/**
* Returns the current zOrderIndex
*/
virtual unsigned int zOrderIndex() const;
/**
* This function returns true if this container widgets z order index is
* higher than the index of the container widget given in Other parameter
*/
bool isInFrontOf(ads::CDockContainerWidget* Other) const;
/**
* Returns the dock area at teh given global position or 0 if there is no
* dock area at this position
*/
ads::CDockAreaWidget* dockAreaAt(const QPoint& GlobalPos) const;
/**
* Returns the dock area at the given Index or 0 if the index is out of
* range
*/
ads::CDockAreaWidget* dockArea(int Index) const;
/**
* Returns the list of dock areas that are not closed
* If all dock widgets in a dock area are closed, the dock area will be closed
*/
QList<ads::CDockAreaWidget*> openedDockAreas() const;
/**
* Returns the number of dock areas in this container
*/
int dockAreaCount() const;
/**
* Returns the number of visible dock areas
*/
int visibleDockAreaCount() const;
/**
* This function returns true, if this container is in a floating widget
*/
bool isFloating() const;
/**
* Dumps the layout for debugging purposes
*/
void dumpLayout();
/**
* This functions returns the dock widget features of all dock widget in
* this container.
* A bitwise and is used to combine the flags of all dock widgets. That
* means, if only dock widget does not support a certain flag, the whole
* dock are does not support the flag.
*/
ads::CDockWidget::DockWidgetFeatures features() const;
/**
* If this dock container is in a floating widget, this function returns
* the floating widget.
* Else, it returns a nullptr.
*/
ads::CFloatingDockContainer* floatingWidget() const;
/**
* Call this function to close all dock areas except the KeepOpenArea
*/
void closeOtherAreas(ads::CDockAreaWidget* KeepOpenArea);
signals:
/**
* This signal is emitted if one or multiple dock areas has been added to
* the internal list of dock areas.
* If multiple dock areas are inserted, this signal is emitted only once
*/
void dockAreasAdded();
/**
* This signal is emitted if one or multiple dock areas has been removed
*/
void dockAreasRemoved();
/**
* This signal is emitted if a dock area is opened or closed via
* toggleView() function
*/
void dockAreaViewToggled(ads::CDockAreaWidget* DockArea, bool Open);
}; // class DockContainerWidget
};
// namespace ads
%End

205
sip/DockManager.sip Normal file
View File

@ -0,0 +1,205 @@
%Import QtWidgets/QtWidgetsmod.sip
%If (Qt_5_0_0 -)
%MappedType QMap<QString, ads::CDockWidget*>
/TypeHint="Dict[QString, CDockWidget*]", TypeHintValue="{}"/
{
%TypeHeaderCode
#include <qmap.h>
%End
%ConvertFromTypeCode
PyObject *d = PyDict_New();
if (!d)
return 0;
QMap<QString, ads::CDockWidget*>::const_iterator it = sipCpp->constBegin();
QMap<QString, ads::CDockWidget*>::const_iterator end = sipCpp->constEnd();
while (it != end)
{
QString *k = new QString(it.key());
PyObject *kobj = sipConvertFromType(k, sipType_QString,
sipTransferObj);
if (!kobj)
{
delete k;
Py_DECREF(d);
return 0;
}
PyObject *vobj = sipConvertFromType(it.value(), sipType_ads_CDockWidget,
sipTransferObj);
if (!vobj)
{
Py_DECREF(kobj);
Py_DECREF(d);
return 0;
}
int rc = PyDict_SetItem(d, kobj, vobj);
Py_DECREF(vobj);
Py_DECREF(kobj);
if (rc < 0)
{
Py_DECREF(d);
return 0;
}
++it;
}
return d;
%End
%ConvertToTypeCode
if (!sipIsErr)
return PyDict_Check(sipPy);
QMap<QString, ads::CDockWidget*> *qm = new QMap<QString, ads::CDockWidget*>;
Py_ssize_t pos = 0;
PyObject *kobj, *vobj;
while (PyDict_Next(sipPy, &pos, &kobj, &vobj))
{
int kstate;
QString *k = reinterpret_cast<QString *>(
sipForceConvertToType(kobj, sipType_QString, sipTransferObj,
SIP_NOT_NONE, &kstate, sipIsErr));
if (*sipIsErr)
{
PyErr_Format(PyExc_TypeError,
"a dict key has type '%s' but '_TYPE1_' is expected",
sipPyTypeName(Py_TYPE(kobj)));
delete qm;
return 0;
}
int vstate;
ads::CDockWidget *v = reinterpret_cast<ads::CDockWidget *>(
sipForceConvertToType(vobj, sipType_ads_CDockWidget, sipTransferObj,
SIP_NOT_NONE, &vstate, sipIsErr));
if (*sipIsErr)
{
PyErr_Format(PyExc_TypeError,
"a dict value has type '%s' but '_TYPE2_' is expected",
sipPyTypeName(Py_TYPE(vobj)));
sipReleaseType(k, sipType_QString, kstate);
delete qm;
return 0;
}
qm->insert(*k, v);
sipReleaseType(v, sipType_ads_CDockWidget, vstate);
sipReleaseType(k, sipType_QString, kstate);
}
*sipCppPtr = qm;
return sipGetState(sipTransferObj);
%End
};
namespace ads
{
class CDockManager : ads::CDockContainerWidget
{
%TypeHeaderCode
#include <DockManager.h>
%End
protected:
void registerFloatingWidget(ads::CFloatingDockContainer* FloatingWidget /Transfer/);
void removeFloatingWidget(ads::CFloatingDockContainer* FloatingWidget) /TransferBack/;
void registerDockContainer(ads::CDockContainerWidget* DockContainer /Transfer/);
void removeDockContainer(ads::CDockContainerWidget* DockContainer /TransferBack/);
ads::CDockOverlay* containerOverlay() const;
ads::CDockOverlay* dockAreaOverlay() const;
public:
enum eViewMenuInsertionOrder
{
MenuSortedByInsertion,
MenuAlphabeticallySorted
};
enum eConfigFlag
{
ActiveTabHasCloseButton,
DockAreaHasCloseButton,
DockAreaCloseButtonClosesTab,
OpaqueSplitterResize,
XmlAutoFormattingEnabled,
XmlCompressionEnabled,
TabCloseButtonIsToolButton,
AllTabsHaveCloseButton,
RetainTabSizeWhenCloseButtonHidden,
DefaultConfig,
};
typedef QFlags<ads::CDockManager::eConfigFlag> ConfigFlags;
CDockManager(QWidget* parent /TransferThis/ = 0);
virtual ~CDockManager();
static ads::CDockManager::ConfigFlags configFlags();
static void setConfigFlags(const ads::CDockManager::ConfigFlags Flags);
static void setConfigFlag(ads::CDockManager::eConfigFlag Flag, bool On = true);
ads::CDockAreaWidget* addDockWidget(ads::DockWidgetArea area, ads::CDockWidget* Dockwidget /Transfer/,
ads::CDockAreaWidget* DockAreaWidget /Transfer/ = 0);
ads::CDockAreaWidget* addDockWidgetTab(ads::DockWidgetArea area,
ads::CDockWidget* Dockwidget /Transfer/);
ads::CDockAreaWidget* addDockWidgetTabToArea(ads::CDockWidget* Dockwidget /Transfer/,
ads::CDockAreaWidget* DockAreaWidget /Transfer/);
ads::CDockWidget* findDockWidget(const QString& ObjectName) const;
void removeDockWidget(ads::CDockWidget* Dockwidget) /TransferBack/;
QMap<QString, ads::CDockWidget*> dockWidgetsMap() const;
const QList<ads::CDockContainerWidget*> dockContainers() const;
const QList<ads::CFloatingDockContainer*> floatingWidgets() const;
virtual unsigned int zOrderIndex() const;
QByteArray saveState(int version = 0) const;
bool restoreState(const QByteArray &state, int version = 0);
void addPerspective(const QString& UniquePrespectiveName);
void removePerspective(const QString& Name);
void removePerspectives(const QStringList& Names);
QStringList perspectiveNames() const;
void savePerspectives(QSettings& Settings) const;
void loadPerspectives(QSettings& Settings);
QAction* addToggleViewActionToMenu(QAction* ToggleViewAction /Transfer/,
const QString& Group = QString(), const QIcon& GroupIcon = QIcon());
QMenu* viewMenu() const;
void setViewMenuInsertionOrder(ads::CDockManager::eViewMenuInsertionOrder Order);
bool isRestoringState() const;
static int startDragDistance();
public slots:
void openPerspective(const QString& PerspectiveName);
signals:
void perspectiveListChanged();
void perspectivesRemoved();
void restoringState();
void stateRestored();
void openingPerspective(const QString& PerspectiveName);
void perspectiveOpened(const QString& PerspectiveName);
};
};
%End

77
sip/DockOverlay.sip Normal file
View File

@ -0,0 +1,77 @@
%Import QtWidgets/QtWidgetsmod.sip
%If (Qt_5_0_0 -)
namespace ads
{
class CDockOverlay : public QFrame
{
%TypeHeaderCode
#include <DockOverlay.h>
%End
public:
enum eMode
{
ModeDockAreaOverlay,
ModeContainerOverlay
};
CDockOverlay(QWidget* parent /TransferThis/, eMode Mode = ads::CDockOverlay::ModeDockAreaOverlay);
virtual ~CDockOverlay();
void setAllowedAreas(ads::DockWidgetAreas areas);
ads::DockWidgetAreas allowedAreas() const;
ads::DockWidgetArea dropAreaUnderCursor() const;
ads::DockWidgetArea showOverlay(QWidget* target);
void hideOverlay();
void enableDropPreview(bool Enable);
QRect dropOverlayRect() const;
virtual bool event(QEvent *e);
protected:
virtual void paintEvent(QPaintEvent *e);
virtual void showEvent(QShowEvent* e);
virtual void hideEvent(QHideEvent* e);
};
class CDockOverlayCross : public QWidget
{
public:
enum eIconColor
{
FrameColor,
WindowBackgroundColor,
OverlayColor,
ArrowColor,
ShadowColor
};
protected:
QString iconColors() const;
QColor iconColor() const;
void setIconFrameColor(const QColor& Color);
void setIconBackgroundColor(const QColor& Color);
void setIconOverlayColor(const QColor& Color);
void setIconArrowColor(const QColor& Color);
void setIconShadowColor(const QColor& Color);
public:
CDockOverlayCross(ads::CDockOverlay* overlay /TransferThis/);
virtual ~CDockOverlayCross();
void setIconColor(ads::CDockOverlayCross::eIconColor ColorIndex, const QColor& Color);
QColor iconColor(ads::CDockOverlayCross::eIconColor ColorIndex) const;
ads::DockWidgetArea cursorLocation() const;
void setupOverlayCross(ads::CDockOverlay::eMode Mode);
void updateOverlayIcons();
void reset();
void updatePosition();
void setIconColors(const QString& Colors);
};
};
%End

23
sip/DockSplitter.sip Normal file
View File

@ -0,0 +1,23 @@
%Import QtWidgets/QtWidgetsmod.sip
%If (Qt_5_0_0 -)
namespace ads
{
class CDockSplitter : QSplitter
{
%TypeHeaderCode
#include <DockSplitter.h>
%End
public:
CDockSplitter(QWidget *parent /TransferThis/ = 0);
CDockSplitter(Qt::Orientation orientation, QWidget *parent /TransferThis/ = 0);
virtual ~CDockSplitter();
bool hasVisibleContent() const;
};
};
%End

101
sip/DockWidget.sip Normal file
View File

@ -0,0 +1,101 @@
%Import QtWidgets/QtWidgetsmod.sip
%If (Qt_5_0_0 -)
namespace ads
{
class CDockWidget : QFrame
{
%TypeHeaderCode
#include <DockWidget.h>
%End
protected:
void setDockManager(ads::CDockManager* DockManager /Transfer/);
void setDockArea(ads::CDockAreaWidget* DockArea /Transfer/);
void setToggleViewActionChecked(bool Checked);
void saveState(QXmlStreamWriter& Stream) const;
void flagAsUnassigned();
static void emitTopLevelEventForWidget(ads::CDockWidget* TopLevelDockWidget, bool Floating);
void emitTopLevelChanged(bool Floating);
void setClosedState(bool Closed);
void toggleViewInternal(bool Open);
public:
enum DockWidgetFeature
{
DockWidgetClosable,
DockWidgetMovable,
DockWidgetFloatable,
AllDockWidgetFeatures,
NoDockWidgetFeatures
};
typedef QFlags<ads::CDockWidget::DockWidgetFeature> DockWidgetFeatures;
enum eState
{
StateHidden,
StateDocked,
StateFloating
};
enum eInsertMode
{
AutoScrollArea,
ForceScrollArea,
ForceNoScrollArea
};
enum eToggleViewActionMode
{
ActionModeToggle,
ActionModeShow
};
CDockWidget(const QString &title, QWidget* parent /TransferThis/ = 0);
virtual ~CDockWidget();
virtual QSize minimumSizeHint() const;
void setWidget(QWidget* widget /Transfer/, ads::CDockWidget::eInsertMode InsertMode = AutoScrollArea);
QWidget* takeWidget() /TransferBack/;
QWidget* widget() const;
ads::CDockWidgetTab* tabWidget() const;
void setFeatures(ads::CDockWidget::DockWidgetFeatures features);
void setFeature(ads::CDockWidget::DockWidgetFeature flag, bool on);
ads::CDockWidget::DockWidgetFeatures features() const;
ads::CDockManager* dockManager() const;
ads::CDockContainerWidget* dockContainer() const;
ads::CDockAreaWidget* dockAreaWidget() const;
bool isFloating() const;
bool isInFloatingContainer() const;
bool isClosed() const;
QAction* toggleViewAction() const;
void setToggleViewActionMode(ads::CDockWidget::eToggleViewActionMode Mode);
void setIcon(const QIcon& Icon);
QIcon icon() const;
QToolBar* toolBar() const;
QToolBar* createDefaultToolBar();
void setToolBar(QToolBar* ToolBar);
void setToolBarStyle(Qt::ToolButtonStyle Style, ads::CDockWidget::eState State);
Qt::ToolButtonStyle toolBarStyle(ads::CDockWidget::eState State) const;
void setToolBarIconSize(const QSize& IconSize, ads::CDockWidget::eState State);
QSize toolBarIconSize(eState State) const;
void setTabToolTip(const QString &text);
public:
virtual bool event(QEvent *e);
public slots:
void toggleView(bool Open = true);
signals:
void viewToggled(bool Open);
void closed();
void titleChanged(const QString& Title);
void topLevelChanged(bool topLevel);
};
};
%End

50
sip/DockWidgetTab.sip Normal file
View File

@ -0,0 +1,50 @@
%Import QtWidgets/QtWidgetsmod.sip
%If (Qt_5_0_0 -)
namespace ads
{
class CDockWidgetTab : QFrame
{
%TypeHeaderCode
#include <DockWidgetTab.h>
%End
protected:
virtual void mousePressEvent(QMouseEvent* ev);
virtual void mouseReleaseEvent(QMouseEvent* ev);
virtual void mouseMoveEvent(QMouseEvent* ev);
virtual void contextMenuEvent(QContextMenuEvent* ev);
virtual void mouseDoubleClickEvent(QMouseEvent *event);
public:
CDockWidgetTab(ads::CDockWidget* DockWidget /TransferThis/, QWidget* parent /TransferThis/ = 0);
virtual ~CDockWidgetTab();
bool isActiveTab() const;
void setActiveTab(bool active);
ads::CDockWidget* dockWidget() const;
void setDockAreaWidget(ads::CDockAreaWidget* DockArea /Transfer/);
ads::CDockAreaWidget* dockAreaWidget() const;
void setIcon(const QIcon& Icon);
const QIcon& icon() const;
QString text() const;
void setText(const QString& title);
bool isClosable() const;
virtual bool event(QEvent *e);
public slots:
virtual void setVisible(bool visible);
signals:
void activeTabChanged();
void clicked();
void closeRequested();
void closeOtherTabsRequested();
void moved(const QPoint& GlobalPos);
}; // class DockWidgetTab
};
// namespace ads
%End

40
sip/ElidingLabel.sip Normal file
View File

@ -0,0 +1,40 @@
%Import QtWidgets/QtWidgetsmod.sip
%If (Qt_5_0_0 -)
namespace ads
{
class CElidingLabel : QLabel
{
%TypeHeaderCode
#include <ElidingLabel.h>
%End
protected:
virtual void mouseReleaseEvent(QMouseEvent* event);
virtual void resizeEvent( QResizeEvent *event );
virtual void mouseDoubleClickEvent( QMouseEvent *ev );
public:
CElidingLabel(QWidget* parent /TransferThis/ = 0, Qt::WindowFlags f = 0);
CElidingLabel(const QString& text, QWidget* parent /TransferThis/ = 0, Qt::WindowFlags f = 0);
virtual ~CElidingLabel();
Qt::TextElideMode elideMode() const;
void setElideMode(Qt::TextElideMode mode);
public:
virtual QSize minimumSizeHint() const;
virtual QSize sizeHint() const;
void setText(const QString &text);
QString text() const;
signals:
void clicked();
void doubleClicked();
};
};
%End

View File

@ -0,0 +1,50 @@
%Import QtWidgets/QtWidgetsmod.sip
%If (Qt_5_0_0 -)
namespace ads
{
class CFloatingDockContainer : QWidget
{
%TypeHeaderCode
#include <FloatingDockContainer.h>
%End
protected:
void startFloating(const QPoint& DragStartMousePos, const QSize& Size,
ads::eDragState DragState, QWidget* MouseEventHandler);
void startDragging(const QPoint& DragStartMousePos, const QSize& Size,
QWidget* MouseEventHandler);
void finishDragging();
void initFloatingGeometry(const QPoint& DragStartMousePos, const QSize& Size);
void moveFloating();
bool restoreState(QXmlStreamReader& Stream, bool Testing);
void updateWindowTitle();
protected:
virtual void changeEvent(QEvent *event);
virtual void moveEvent(QMoveEvent *event);
virtual bool event(QEvent *e);
virtual void closeEvent(QCloseEvent *event);
virtual void hideEvent(QHideEvent *event);
virtual void showEvent(QShowEvent *event);
virtual bool eventFilter(QObject *watched, QEvent *event);
public:
CFloatingDockContainer(ads::CDockManager* DockManager /TransferThis/);
CFloatingDockContainer(ads::CDockAreaWidget* DockArea /TransferThis/);
CFloatingDockContainer(ads::CDockWidget* DockWidget /TransferThis/);
virtual ~CFloatingDockContainer();
ads::CDockContainerWidget* dockContainer() const;
bool isClosable() const;
bool hasTopLevelDockWidget() const;
ads::CDockWidget* topLevelDockWidget() const;
QList<ads::CDockWidget*> dockWidgets() const;
};
};
%End

20
sip/ads.sip Normal file
View File

@ -0,0 +1,20 @@
%Module(name=PyQtAds.QtAds.ads, call_super_init=True, keyword_arguments="Optional", use_limited_api=True)
%Import QtCore/QtCoremod.sip
%DefaultSupertype sip.simplewrapper
%Platforms {Linux macOS Windows}
%Include ads_globals.sip
%Include DockWidget.sip
%Include DockAreaTabBar.sip
%Include DockAreaTitleBar.sip
%Include DockAreaWidget.sip
%Include DockContainerWidget.sip
%Include DockManager.sip
%Include DockOverlay.sip
%Include DockSplitter.sip
%Include DockWidgetTab.sip
%Include ElidingLabel.sip
%Include FloatingDockContainer.sip
%If (Linux)
%Include linux/FloatingWidgetTitleBar.sip
%End

44
sip/ads_globals.sip Normal file
View File

@ -0,0 +1,44 @@
%Import QtWidgets/QtWidgetsmod.sip
%If (Qt_5_0_0 -)
namespace ads
{
%TypeHeaderCode
#include <ads_globals.h>
%End
enum DockWidgetArea
{
NoDockWidgetArea,
LeftDockWidgetArea,
RightDockWidgetArea,
TopDockWidgetArea,
BottomDockWidgetArea,
CenterDockWidgetArea,
InvalidDockWidgetArea,
OuterDockAreas,
AllDockAreas
};
typedef QFlags<ads::DockWidgetArea> DockWidgetAreas;
enum TitleBarButton
{
TitleBarButtonTabsMenu,
TitleBarButtonUndock,
TitleBarButtonClose
};
enum eDragState
{
DraggingInactive,
DraggingMousePressed,
DraggingTab,
DraggingFloatingWidget
};
};
%End

View File

@ -0,0 +1,31 @@
%Import QtWidgets/QtWidgetsmod.sip
%If (Qt_5_0_0 -)
namespace ads
{
%TypeHeaderCode
#include <FloatingWidgetTitleBar.h>
%End
class CFloatingWidgetTitleBar : QWidget
{
protected:
virtual void mousePressEvent(QMouseEvent *ev);
virtual void mouseReleaseEvent(QMouseEvent *ev);
virtual void mouseMoveEvent(QMouseEvent *ev);
public:
explicit CFloatingWidgetTitleBar(CFloatingDockContainer *parent /TransferThis/ = 0);
virtual ~CFloatingWidgetTitleBar();
void enableCloseButton(bool Enable);
void setTitle(const QString &Text);
signals:
void closeRequested();
};
};
%End