diff --git a/Sankore 3.1.iss b/Sankore 3.1.iss
index 158894c7..1e968088 100644
--- a/Sankore 3.1.iss
+++ b/Sankore 3.1.iss
@@ -1,89 +1,88 @@
-; Script generated by the Inno Setup Script Wizard.
-; SEE THE DOCUMENTATION FOR DETAILS ON CREATING INNO SETUP SCRIPT FILES!
-
-[Setup]
-; NOTE: The value of AppId uniquely identifies this application.
-; Do not use the same AppId value in installers for other applications.
-; (To generate a new GUID, click Tools | Generate GUID inside the IDE.)
-AppId={{E63D17F8-D9DA-479D-B9B5-0D101A03703B}
-AppName=Sankore 3.1
-AppVerName=Sankore 3.1
-AppPublisher=Mnemis
-
-AppPublisherURL=http://www.getuniboard.com
-AppSupportURL=http://support.getuniboard.com
-AppUpdatesURL=http://www.getuniboard.com
-
-DefaultDirName={pf}\Sankore 3.1
-DefaultGroupName=Sankore 3.1
-
-OutputDir=.\install\win32\
-OutputBaseFilename=Sankore 3.1 setup
-SetupIconFile=.\resources\win\uniboard.ico
-Compression=lzma
-SolidCompression=yes
-
-[Languages]
-Name: "english"; MessagesFile: "compiler:Default.isl"
-
-[Tasks]
-Name: "desktopicon"; Description: "{cm:CreateDesktopIcon}"; GroupDescription: "{cm:AdditionalIcons}"; Flags: unchecked
-Name: "quicklaunchicon"; Description: "{cm:CreateQuickLaunchIcon}"; GroupDescription: "{cm:AdditionalIcons}"; Flags: unchecked
-
-[InstallDelete]
-
-Type: files ; Name: "{app}\Sankore 3.1.pdb"
-Type: filesandordirs ; Name: "{app}\library"
-Type: filesandordirs ; Name: "{app}\Microsoft.VC90.CRT"
-Type: filesandordirs ; Name: "{app}\plugins"
-Type: filesandordirs ; Name: "{app}\i18n"
-Type: files ; Name: "{app}\*.dll"
-
-[Files]
-Source: ".\build\win32\release\product\*"; DestDir: "{app}"; Flags: ignoreversion recursesubdirs createallsubdirs
-Source: ".\runtime\windows\*"; DestDir: "{app}"; Flags: ignoreversion recursesubdirs createallsubdirs;
-Source: ".\resources\win\plugins\*"; DestDir: "{app}"; Flags: recursesubdirs createallsubdirs
-; NOTE: Don't use "Flags: ignoreversion" on any shared system files
-
-[Icons]
-Name: "{group}\Sankore 3.1"; Filename: "{app}\Sankore 3.1.exe"
-;Name: "{group}\{cm:ProgramOnTheWeb,Sankore 3.1}"; Filename: "http://www.getuniboard.com/"
-Name: "{group}\{cm:UninstallProgram,Sankore 3.1}"; Filename: "{uninstallexe}"
-Name: "{commondesktop}\Sankore 3.1"; Filename: "{app}\Sankore 3.1.exe"; Tasks: desktopicon
-Name: "{userappdata}\Microsoft\Internet Explorer\Quick Launch\Sankore 3.1"; Filename: "{app}\Sankore 3.1.exe"; Tasks: quicklaunchicon
-Name: "{group}\Printing Preferences"; Filename: "{app}\properties.exe"; WorkingDir: {app}
-
-[Registry]
-Root: HKCR; Subkey: ".ubz"; ValueType: string; ValueName: ""; ValueData: "SankoreFile"; Flags: uninsdeletevalue
-Root: HKCR; Subkey: "SankoreFile"; ValueType: string; ValueName: ""; ValueData: "Sankore 3.1 document"; Flags: uninsdeletekey
-Root: HKCR; Subkey: "SankoreFile\DefaultIcon"; ValueType: string; ValueName: ""; ValueData: "{app}\Sankore 3.1.exe,1"
-Root: HKCR; Subkey: "SankoreFile\shell\open\command"; ValueType: string; ValueName: ""; ValueData: """{app}\Sankore 3.1.exe"" ""%1"""
-
-Root: HKLM; Subkey: "SOFTWARE\Sankore 3.1"; ValueType: string; ValueName: "Client application"; ValueData: "{app}\Sankore 3.1.exe"; Flags: uninsdeletevalue; Check: isProcessorNotX64
-Root: HKLM; Subkey: "SOFTWARE\Sankore 3.1"; ValueType: dword; ValueName: "Transfer mode"; ValueData: "0"; Flags: uninsdeletevalue; Check: isProcessorNotX64
-Root: HKLM; Subkey: "SOFTWARE\Sankore 3.1"; ValueType: dword; ValueName: "EMF: Hide page"; ValueData: "1"; Flags: uninsdeletevalue; Check: isProcessorNotX64
-Root: HKLM; Subkey: "SOFTWARE\Sankore 3.1\Defaults"; ValueType: dword; ValueName: "PDF: Enabled"; ValueData: "1"; Flags: uninsdeletevalue; Check: isProcessorNotX64
-
-Root: HKLM64; Subkey: "SOFTWARE\Sankore 3.1"; ValueType: string; ValueName: "Client application"; ValueData: "{app}\Sankore 3.1.exe"; Flags: uninsdeletevalue; Check: isProcessorX64
-Root: HKLM64; Subkey: "SOFTWARE\Sankore 3.1"; ValueType: dword; ValueName: "Transfer mode"; ValueData: "0"; Flags: uninsdeletevalue; Check: isProcessorX64
-Root: HKLM64; Subkey: "SOFTWARE\Sankore 3.1"; ValueType: dword; ValueName: "EMF: Hide page"; ValueData: "1"; Flags: uninsdeletevalue; Check: isProcessorX64
-Root: HKLM64; Subkey: "SOFTWARE\Sankore 3.1\Defaults"; ValueType: dword; ValueName: "PDF: Enabled"; ValueData: "1"; Flags: uninsdeletevalue; Check: isProcessorX64
-
-[Run]
-Filename: "{app}\Sankore 3.1.exe"; Description: "{cm:LaunchProgram,Sankore 3.1}"; Flags: nowait postinstall
-
-[UninstallDelete]
-; cleanup and delete whole installation directory
-Name: {app}; Type: filesandordirs
-
-[Code]
-function isProcessorX64: Boolean;
-begin
- Result := (ProcessorArchitecture = paX64);
-end;
-
-function isProcessorNotX64: Boolean;
-begin
- Result := not isProcessorX64;
-end;
-
+; Script generated by the Inno Setup Script Wizard.
+; SEE THE DOCUMENTATION FOR DETAILS ON CREATING INNO SETUP SCRIPT FILES!
+
+[Setup]
+; NOTE: The value of AppId uniquely identifies this application.
+; Do not use the same AppId value in installers for other applications.
+; (To generate a new GUID, click Tools | Generate GUID inside the IDE.)
+AppId={{E63D17F8-D9DA-479D-B9B5-0D101A03703B}
+AppName=Sankore 3.1
+AppVerName=Sankore 3.1
+AppPublisher=Mnemis
+
+AppPublisherURL=http://www.getuniboard.com
+AppSupportURL=http://support.getuniboard.com
+AppUpdatesURL=http://www.getuniboard.com
+
+DefaultDirName={pf}\Sankore 3.1
+DefaultGroupName=Sankore 3.1
+
+OutputDir=.\install\win32\
+OutputBaseFilename=Sankore 3.1 setup
+SetupIconFile=.\resources\win\uniboard.ico
+Compression=lzma
+SolidCompression=yes
+
+[Languages]
+Name: "english"; MessagesFile: "compiler:Default.isl"
+
+[Tasks]
+Name: "desktopicon"; Description: "{cm:CreateDesktopIcon}"; GroupDescription: "{cm:AdditionalIcons}"; Flags: unchecked
+Name: "quicklaunchicon"; Description: "{cm:CreateQuickLaunchIcon}"; GroupDescription: "{cm:AdditionalIcons}"; Flags: unchecked
+
+[InstallDelete]
+
+Type: files ; Name: "{app}\Sankore 3.1.pdb"
+Type: filesandordirs ; Name: "{app}\library"
+Type: filesandordirs ; Name: "{app}\Microsoft.VC90.CRT"
+Type: filesandordirs ; Name: "{app}\plugins"
+Type: filesandordirs ; Name: "{app}\i18n"
+Type: files ; Name: "{app}\*.dll"
+
+[Files]
+Source: ".\build\win32\release\product\*"; DestDir: "{app}"; Flags: ignoreversion recursesubdirs createallsubdirs
+Source: ".\runtime\windows\*"; DestDir: "{app}"; Flags: ignoreversion recursesubdirs createallsubdirs;
+Source: ".\resources\win\plugins\*"; DestDir: "{app}"; Flags: recursesubdirs createallsubdirs
+; NOTE: Don't use "Flags: ignoreversion" on any shared system files
+
+[Icons]
+Name: "{group}\Sankore 3.1"; Filename: "{app}\Sankore 3.1.exe"
+;Name: "{group}\{cm:ProgramOnTheWeb,Sankore 3.1}"; Filename: "http://www.getuniboard.com/"
+Name: "{group}\{cm:UninstallProgram,Sankore 3.1}"; Filename: "{uninstallexe}"
+Name: "{commondesktop}\Sankore 3.1"; Filename: "{app}\Sankore 3.1.exe"; Tasks: desktopicon
+Name: "{userappdata}\Microsoft\Internet Explorer\Quick Launch\Sankore 3.1"; Filename: "{app}\Sankore 3.1.exe"; Tasks: quicklaunchicon
+Name: "{group}\Printing Preferences"; Filename: "{app}\properties.exe"; WorkingDir: {app}
+
+[Registry]
+Root: HKCR; Subkey: ".ubz"; ValueType: string; ValueName: ""; ValueData: "SankoreFile"; Flags: uninsdeletevalue
+Root: HKCR; Subkey: "SankoreFile"; ValueType: string; ValueName: ""; ValueData: "Sankore 3.1 document"; Flags: uninsdeletekey
+Root: HKCR; Subkey: "SankoreFile\DefaultIcon"; ValueType: string; ValueName: ""; ValueData: "{app}\Sankore 3.1.exe,1"
+Root: HKCR; Subkey: "SankoreFile\shell\open\command"; ValueType: string; ValueName: ""; ValueData: """{app}\Sankore 3.1.exe"" ""%1"""
+
+Root: HKLM; Subkey: "SOFTWARE\Sankore 3.1"; ValueType: string; ValueName: "Client application"; ValueData: "{app}\Sankore 3.1.exe"; Flags: uninsdeletevalue; Check: isProcessorNotX64
+Root: HKLM; Subkey: "SOFTWARE\Sankore 3.1"; ValueType: dword; ValueName: "Transfer mode"; ValueData: "0"; Flags: uninsdeletevalue; Check: isProcessorNotX64
+Root: HKLM; Subkey: "SOFTWARE\Sankore 3.1"; ValueType: dword; ValueName: "EMF: Hide page"; ValueData: "1"; Flags: uninsdeletevalue; Check: isProcessorNotX64
+Root: HKLM; Subkey: "SOFTWARE\Sankore 3.1\Defaults"; ValueType: dword; ValueName: "PDF: Enabled"; ValueData: "1"; Flags: uninsdeletevalue; Check: isProcessorNotX64
+
+Root: HKLM64; Subkey: "SOFTWARE\Sankore 3.1"; ValueType: string; ValueName: "Client application"; ValueData: "{app}\Sankore 3.1.exe"; Flags: uninsdeletevalue; Check: isProcessorX64
+Root: HKLM64; Subkey: "SOFTWARE\Sankore 3.1"; ValueType: dword; ValueName: "Transfer mode"; ValueData: "0"; Flags: uninsdeletevalue; Check: isProcessorX64
+Root: HKLM64; Subkey: "SOFTWARE\Sankore 3.1"; ValueType: dword; ValueName: "EMF: Hide page"; ValueData: "1"; Flags: uninsdeletevalue; Check: isProcessorX64
+Root: HKLM64; Subkey: "SOFTWARE\Sankore 3.1\Defaults"; ValueType: dword; ValueName: "PDF: Enabled"; ValueData: "1"; Flags: uninsdeletevalue; Check: isProcessorX64
+
+[Run]
+Filename: "{app}\Sankore 3.1.exe"; Description: "{cm:LaunchProgram,Sankore 3.1}"; Flags: nowait postinstall
+
+[UninstallDelete]
+; cleanup and delete whole installation directory
+Name: {app}; Type: filesandordirs
+
+[Code]
+function isProcessorX64: Boolean;
+begin
+ Result := (ProcessorArchitecture = paX64);
+end;
+
+function isProcessorNotX64: Boolean;
+begin
+ Result := not isProcessorX64;
+end;
\ No newline at end of file
diff --git a/Sankore_3.1.pro b/Sankore_3.1.pro
index ef05e726..c6cb40b8 100644
--- a/Sankore_3.1.pro
+++ b/Sankore_3.1.pro
@@ -7,9 +7,9 @@ CONFIG += debug_and_release \
no_include_pwd
VERSION_MAJ = 1
-VERSION_MIN = 00
-VERSION_TYPE = r # a = alpha, b = beta, r = release, other => error
-VERSION_PATCH = 00
+VERSION_MIN = 10
+VERSION_TYPE = b # a = alpha, b = beta, r = release, other => error
+VERSION_PATCH = 01
VERSION = "$${VERSION_MAJ}.$${VERSION_MIN}.$${VERSION_TYPE}.$${VERSION_PATCH}"
VERSION = $$replace(VERSION, "\\.r", "")
@@ -269,6 +269,12 @@ macx {
TRANSLATION_ro.path = "$$RESOURCES_DIR/ro.lproj"
QMAKE_BUNDLE_DATA += TRANSLATION_ro
}
+ exists(resources/i18n/sankore_ar.qm) {
+ TRANSLATION_ar.files = resources/i18n/sankore_ar.qm \
+ resources/i18n/Localizable.strings
+ TRANSLATION_ar.path = "$$RESOURCES_DIR/ar.lproj"
+ QMAKE_BUNDLE_DATA += TRANSLATION_ar
+ }
QMAKE_BUNDLE_DATA += UB_ETC \
UB_LIBRARY \
@@ -338,7 +344,8 @@ TRANSLATIONS = resources/i18n/sankore_en.ts \
resources/i18n/sankore_ja.ts \
resources/i18n/sankore_ko.ts \
resources/i18n/sankore_zh.ts \
- resources/i18n/sankore_ro.ts
+ resources/i18n/sankore_ro.ts \
+ resources/i18n/sankore_ar.ts
INSTALLS = UB_ETC \
UB_I18N \
diff --git a/resources/forms/preferences.ui b/resources/forms/preferences.ui
index d55a6287..2d694d52 100644
--- a/resources/forms/preferences.ui
+++ b/resources/forms/preferences.ui
@@ -21,10 +21,59 @@
+ -
+
+
+ QFrame::NoFrame
+
+
+ QFrame::Raised
+
+
+
+ 0
+
+
-
+
+
+ Default Settings
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+ -
+
+
-
+
+
+ Close
+
+
+ true
+
+
+
+
+
+
+
+
-
- 4
+ 0
@@ -564,7 +613,7 @@
-
- 4
+ 3
@@ -577,7 +626,7 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
<html><head><meta name="qrichtext" content="1" /><style type="text/css">
p, li { white-space: pre-wrap; }
-</style></head><body style=" font-family:'Ubuntu'; font-size:10pt; font-weight:400; font-style:normal;">
+</style></head><body style=" font-family:'Ubuntu'; font-size:11pt; font-weight:400; font-style:normal;">
<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:9pt; color:#1a1a1a;">The OpenSSL toolkit stays under a dual license, i.e. both the conditions of the OpenSSL License and the original SSLeay license apply to the toolkit.</span></p>
<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:9pt; color:#1a1a1a;">See below for the actual license texts. Actually both licenses are BSD-style Open Source licenses. In case of any license issues related to OpenSSL please contact </span><a href="mailto:openssl-core@openssl.org"><span style=" font-size:9pt; text-decoration: underline; color:#0000ff;">openssl-core@openssl.org</span></a><span style=" font-size:9pt; color:#1a1a1a;">.</span><span style=" font-size:9pt;"> </span></p></body></html>
@@ -596,7 +645,7 @@ p, li { white-space: pre-wrap; }
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
<html><head><meta name="qrichtext" content="1" /><style type="text/css">
p, li { white-space: pre-wrap; }
-</style></head><body style=" font-family:'Ubuntu'; font-size:10pt; font-weight:400; font-style:normal;">
+</style></head><body style=" font-family:'Ubuntu'; font-size:11pt; font-weight:400; font-style:normal;">
<p align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:9pt; color:#1a1a1a;">Copyright (C) 1995-1998 Jean-loup Gailly and Mark Adler</span><span style=" font-size:12pt;"><br /><br /></span><span style=" font-size:9pt; color:#1a1a1a;"> This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages arising from the use of this software.</span><span style=" font-size:9pt;"><br /><br /></span><span style=" font-size:9pt; color:#1a1a1a;"> Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions:</span><span style=" font-size:9pt;"><br /><br /></span><span style=" font-size:9pt; color:#1a1a1a;"> 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.</span><span style=" font-size:9pt;"><br /></span><span style=" font-size:9pt; color:#1a1a1a;"> 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.</span><span style=" font-size:9pt;"><br /></span><span style=" font-size:9pt; color:#1a1a1a;"> 3. This notice may not be removed or altered from any source distribution.</span><span style=" font-size:9pt;"> </span></p></body></html>
@@ -614,7 +663,7 @@ p, li { white-space: pre-wrap; }
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
<html><head><meta name="qrichtext" content="1" /><style type="text/css">
p, li { white-space: pre-wrap; }
-</style></head><body style=" font-family:'Ubuntu'; font-size:10pt; font-weight:400; font-style:normal;">
+</style></head><body style=" font-family:'Ubuntu'; font-size:11pt; font-weight:400; font-style:normal;">
<p align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:9pt; color:#000000;">Xpdf is licensed under the GNU General Public License (GPL), version 2.</span></p></body></html>
@@ -632,7 +681,7 @@ p, li { white-space: pre-wrap; }
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
<html><head><meta name="qrichtext" content="1" /><style type="text/css">
p, li { white-space: pre-wrap; }
-</style></head><body style=" font-family:'Ubuntu'; font-size:10pt; font-weight:400; font-style:normal;">
+</style></head><body style=" font-family:'Ubuntu'; font-size:11pt; font-weight:400; font-style:normal;">
<p align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:9pt;">GNU Library or Lesser General Public License (LGPL), zlib/libpng License</span></p></body></html>
@@ -650,7 +699,7 @@ p, li { white-space: pre-wrap; }
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
<html><head><meta name="qrichtext" content="1" /><style type="text/css">
p, li { white-space: pre-wrap; }
-</style></head><body style=" font-family:'Ubuntu'; font-size:10pt; font-weight:400; font-style:normal;">
+</style></head><body style=" font-family:'Ubuntu'; font-size:11pt; font-weight:400; font-style:normal;">
<p align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:9pt;">SANKORE3.1 is free software: you can redistribute it and/or modify it under the terms of the Lesser GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or any later version. You can find the source code of this software at <https://adullact.net/projects/sankore/></span></p>
<p align="justify" style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:9pt;"></p>
<p align="justify" style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:9pt;"></p>
@@ -845,7 +894,7 @@ p, li { white-space: pre-wrap; }
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
<html><head><meta name="qrichtext" content="1" /><style type="text/css">
p, li { white-space: pre-wrap; }
-</style></head><body style=" font-family:'Ubuntu'; font-size:10pt; font-weight:400; font-style:normal;">
+</style></head><body style=" font-family:'Ubuntu'; font-size:11pt; font-weight:400; font-style:normal;">
<p align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:9pt; color:#1a1a1a;">Sankoré 3.1 version , Copyright (C) 2010 Sankoré 3.1 comes with ABSOLUTELY NO WARRANTY.</span><span style=" font-size:9pt;"><br /></span><span style=" font-size:9pt; color:#35382a;"> </span></p>
<p align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:9pt; color:#35382a;">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 3 of the License, or (at your option) any later version.</span></p>
<p align="justify" style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:9pt; color:#35382a;"></p>
@@ -861,8 +910,8 @@ p, li { white-space: pre-wrap; }
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
<html><head><meta name="qrichtext" content="1" /><style type="text/css">
p, li { white-space: pre-wrap; }
-</style></head><body style=" font-family:'Ubuntu'; font-size:10pt; font-weight:400; font-style:normal;">
-<p align="justify" style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"></p>
+</style></head><body style=" font-family:'Ubuntu'; font-size:11pt; font-weight:400; font-style:normal;">
+<p align="justify" style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:10pt;"></p>
<p align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:9pt; color:#3c3c3c;">GIPENA</span><span style=" font-size:9pt;"><br /></span><span style=" font-size:9pt; color:#3c3c3c;">Délégation Interministérielle à l'Education Numérique en Afrique</span><span style=" font-size:9pt;"><br /></span><span style=" font-size:9pt; color:#3c3c3c;">20 Avenue Ségur Paris 75007</span><span style=" font-size:9pt;"><br /><br /></span><span style=" font-size:9pt; color:#3c3c3c;">Téléphone : 01 43 17 68 08</span><span style=" font-size:9pt;"><br /><br /></span><span style=" font-size:9pt; color:#3c3c3c;">email: </span><a href="mailto:contact@sankore.org"><span style=" font-size:9pt; text-decoration: underline; color:#0000ff;">contact@sankore.org</span></a><span style=" font-size:9pt;"> </span></p></body></html>
@@ -907,55 +956,78 @@ p, li { white-space: pre-wrap; }
-
-
- -
-
-
- QFrame::NoFrame
-
-
- QFrame::Raised
-
-
-
- 0
-
-
-
-
-
- Default Settings
-
-
-
- -
-
-
- Qt::Horizontal
-
-
-
- 40
- 20
-
-
-
-
- -
-
-
-
-
-
- Close
-
-
- true
-
-
-
-
-
-
+
+
+ Network
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+ Community
+
+
+
-
+
+
-
+
+
+ User/Pass:
+
+
+
+ -
+
+
+
+ 5
+
+
+ 0
+
+
-
+
+
+ QLineEdit::Normal
+
+
+
+ -
+
+
+ QLineEdit::Password
+
+
+
+
+
+
+
+
+ -
+
+
+ Qt::Vertical
+
+
+
+ 20
+ 40
+
+
+
+
+
+
+
+
+
diff --git a/resources/i18n/sankore_ar.ts b/resources/i18n/sankore_ar.ts
new file mode 100644
index 00000000..e9d93b02
--- /dev/null
+++ b/resources/i18n/sankore_ar.ts
@@ -0,0 +1,2627 @@
+
+
+ BlackoutWidget
+
+
+
+
+
+
+
+
+
+
+ DownloadDialog
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ DownloadItem
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ IntranetPodcastPublishingDialog
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ MainWindow
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ PasswordDialog
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ProxyDialog
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ QObject
+
+
+ Category list label on navigation tool bar
+
+
+
+
+ Pictures category element
+
+
+
+
+ UBAbstractPublisher
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ UBAbstractWidget
+
+
+
+
+
+
+
+
+
+
+ UBApplication
+
+
+
+
+
+
+
+
+
+
+ UBApplicationController
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ UBBoardController
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ UBBoardPaletteManager
+
+
+
+
+
+
+
+
+
+
+ UBCapturePublisher
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ UBCapturePublishingDialog
+
+
+
+
+
+
+ UBDesktopPalette
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ UBDocumentController
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ UBDocumentManager
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ UBDocumentNavigator
+
+
+
+
+
+
+ UBDocumentPublisher
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ UBDocumentTreeWidget
+
+
+
+
+
+
+
+
+
+
+ UBDropMeWidget
+
+
+
+
+
+
+ UBExportDocument
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ UBExportFullPDF
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ UBExportPDF
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ UBExportWeb
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ UBGraphicsItemDelegate
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ UBGraphicsTextItem
+
+
+
+
+
+
+ UBGraphicsTextItemDelegate
+
+
+
+
+
+
+ UBGraphicsWidgetItemDelegate
+
+
+
+
+
+
+
+
+
+
+ UBImportDocument
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ UBImportImage
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ UBImportPDF
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ UBIntranetPodcastPublisher
+
+
+
+
+
+
+
+
+
+
+ UBIntranetPodcastPublishingDialog
+
+
+
+
+
+
+ UBLibActionBar
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ UBLibItemProperties
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ UBLibraryController
+
+
+
+
+
+
+ Audio category element
+
+
+
+
+ Movies category element
+
+
+
+
+ Pictures category element
+
+
+
+
+ Shapes category element
+
+
+
+
+ Applications category element
+
+
+
+
+ Favorite category element
+
+
+
+
+ Interactives category element
+
+
+
+
+
+
+
+
+
+
+
+
+ UBNetworkAccessManager
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ UBNewFolderDlg
+
+
+
+
+
+
+
+
+
+
+ UBPersistenceManager
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ UBPodcastController
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ UBPreferencesController
+
+
+
+
+
+
+
+
+
+
+ UBSettings
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ UBThumbnailAdaptor
+
+
+
+
+
+
+
+
+
+
+ UBToolsManager
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ UBTrapFlashController
+
+
+
+
+
+
+
+
+
+
+ UBUpdateDlg
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ UBW3CWidget
+
+
+
+
+
+
+ UBWebPluginWidget
+
+
+
+
+
+
+ UBWebPublisher
+
+
+
+
+
+
+ UBWidgetUniboardAPI
+
+
+
+
+
+
+ UBYouTubePublisher
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ UBYouTubePublishingDialog
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ UBZoomPalette
+
+
+
+
+
+
+ WBClearButton
+
+
+
+
+
+
+ WBDownloadItem
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ unknown file size
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ WBDownloadManager
+
+
+
+
+
+
+ always >= 2
+
+
+
+
+ WBHistoryModel
+
+
+
+
+
+
+
+
+
+
+ WBHistoryTreeModel
+
+
+
+
+
+
+
+
+
+
+ WBSearchLineEdit
+
+
+
+
+
+
+ WBTabBar
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ WBTabWidget
+
+
+
+
+
+
+
+
+
+
+ WBToolbarSearch
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ WBWebPage
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ WBWebView
+
+
+
+
+
+
+ YouTubePublishingDialog
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ brushProperties
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ capturePublishingDialog
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ documentPublishingDialog
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ documents
+
+
+
+
+
+
+
+
+
+
+ preferencesDialog
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ trapFlashDialog
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/resources/images/toolPalette/triangleTool.png b/resources/images/toolPalette/triangleTool.png
index 0421bcea..a9c876cd 100644
Binary files a/resources/images/toolPalette/triangleTool.png and b/resources/images/toolPalette/triangleTool.png differ
diff --git a/src/adaptors/publishing/UBDocumentPublisher.cpp b/src/adaptors/publishing/UBDocumentPublisher.cpp
index e2201f05..b9d191c1 100644
--- a/src/adaptors/publishing/UBDocumentPublisher.cpp
+++ b/src/adaptors/publishing/UBDocumentPublisher.cpp
@@ -1,4 +1,6 @@
- #include "UBDocumentPublisher.h"
+#include
+
+#include "UBDocumentPublisher.h"
#include "frameworks/UBPlatformUtils.h"
#include "frameworks/UBFileSystemUtils.h"
@@ -36,6 +38,7 @@ UBDocumentPublisher::UBDocumentPublisher(UBDocumentProxy* pDocument, QObject *pa
, mPublishingDocument(0)
, mUsername("")
, mPassword("")
+ , bLoginCookieSet(false)
{
mpWebView = new QWebView(0);
UBApplication::mainWindow->addSankoreWebDocumentWidget(mpWebView);
@@ -44,6 +47,7 @@ UBDocumentPublisher::UBDocumentPublisher(UBDocumentProxy* pDocument, QObject *pa
connect(mpWebView, SIGNAL(loadFinished(bool)), this, SLOT(onLoadFinished(bool)));
connect(mpWebView, SIGNAL(linkClicked(QUrl)), this, SLOT(onLinkClicked(QUrl)));
+ connect(this, SIGNAL(loginDone()), this, SLOT(onLoginDone()));
init();
@@ -52,23 +56,68 @@ UBDocumentPublisher::UBDocumentPublisher(UBDocumentProxy* pDocument, QObject *pa
UBDocumentPublisher::~UBDocumentPublisher()
{
- delete mpWebView;
- delete mPublishingDocument;
+ //delete mpWebView;
+ //delete mPublishingDocument;
}
void UBDocumentPublisher::publish()
{
//check that the username and password are stored on preferences
- mUsername = "Admin";
- mPassword = "admin";
+ UBSettings* settings = UBSettings::settings();
+
+ mUsername = settings->communityUsername();
+ mPassword = settings->communityPassword();
buildUbwFile();
UBApplication::showMessage(tr("Uploading Sankore File on Web."));
+
+ login(mUsername, mPassword);
+ //sendUbw();
+
+}
+
+void UBDocumentPublisher::onLoginDone()
+{
sendUbw();
+}
+void UBDocumentPublisher::login(QString username, QString password)
+{
+ QString data,crlf;
+ QByteArray datatoSend;
+
+ // Create the request body
+ data="srid=&j_username=" +username +"&j_password=" +password +crlf+crlf;
+ datatoSend=data.toAscii(); // convert data string to byte array for request
+
+ // Create the request header
+ QString qsLoginURL = QString("http://sankore.devxwiki.com/xwiki/bin/loginsubmit/XWiki/XWikiLogin?xredirect=%0").arg(DOCPUBLICATION_URL);
+ QNetworkRequest request(QUrl(qsLoginURL.toAscii().constData()));
+ request.setRawHeader("Origin", "http://sankore.devxwiki.com");
+ request.setHeader(QNetworkRequest::ContentTypeHeader, "application/x-www-form-urlencoded");
+ request.setRawHeader("Accept", "application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5");
+ request.setRawHeader("Referer", DOCPUBLICATION_URL);
+ request.setHeader(QNetworkRequest::ContentLengthHeader,datatoSend.size());
+ request.setRawHeader("Accept-Language", "en-US,*");
+
+ // Generate a session id
+ //mSessionID = getSessionID();
+
+ // Create the cookie
+ //QList cookiesList;
+ //QString qsCookieValue;
+ //qsCookieValue = mSessionID;
+ //qsCookieValue += "; language=en";
+ //QNetworkCookie cookie("JSESSIONID", qsCookieValue.toAscii().constData());
+ //cookiesList << cookie;
+ //request.setHeader(QNetworkRequest::CookieHeader, QVariant::fromValue(cookiesList));
+
+ // Send the request
+ mpNetworkMgr->post(request,datatoSend);
}
+
void UBDocumentPublisher::buildUbwFile()
{
QDir d;
@@ -526,6 +575,9 @@ void UBDocumentPublisher::init()
mCrlf+=0x0a;
mpNetworkMgr = new QNetworkAccessManager(this);
+ //mpCache = new QNetworkDiskCache(this);
+ //mpCache->setCacheDirectory("cache");
+ //mpNetworkMgr->setCache(mpCache);
mpCookieJar = new QNetworkCookieJar();
connect(mpNetworkMgr, SIGNAL(finished(QNetworkReply*)), this, SLOT(onFinished(QNetworkReply*)));
@@ -533,20 +585,19 @@ void UBDocumentPublisher::init()
void UBDocumentPublisher::onFinished(QNetworkReply *reply)
{
+ qDebug() << "[-[ Request finished! ]-]";
QByteArray response = reply->readAll();
- if (!bCookieSet)
+ if (!bLoginCookieSet)
{
- QList cookiesList;
QVariant cookieHeader = reply->rawHeader("Set-Cookie");
- qDebug() << cookieHeader.toString();
// First we concatenate all the Set-Cookie values (the packet can contains many of them)
QStringList qslCookie = cookieHeader.toString().split("\n");
QString qsCookieValue = qslCookie.at(0);
for (int i = 1; i < qslCookie.size(); i++) {
qsCookieValue += "; " +qslCookie.at(i);
}
- qDebug() << "qsCookieValue " << qsCookieValue;
+
// Now we isolate every cookie value
QStringList qslCookieVals = qsCookieValue.split("; ");
@@ -554,32 +605,62 @@ void UBDocumentPublisher::onFinished(QNetworkReply *reply)
for (int i = 0; i < qslCookieVals.size(); i++)
{
QString cookieString = qslCookieVals.at(i);
- qDebug() << "qslCookieVals.at(i): " << cookieString.replace("\"", "");
+ //qDebug() << "qslCookieVals.at(i): " << cookieString.replace("\"", "");
QStringList qslCrntCookie = cookieString.split("=");
QNetworkCookie crntCookie;
if (qslCrntCookie.length() == 2)
- crntCookie = QNetworkCookie(qslCrntCookie.at(0).toAscii().constData(), qslCrntCookie.at(1).toAscii().constData());
+ {
+ QString qsValue = qslCrntCookie.at(1);
+ qsValue.remove("\"");
+ crntCookie = QNetworkCookie(qslCrntCookie.at(0).toAscii().constData(), qsValue.toAscii().constData());
+ }
else
+ {
crntCookie = QNetworkCookie(qslCrntCookie.at(0).toAscii().constData());
- cookiesList << crntCookie;
+ }
+ // HACK : keep only the same cookies as the XWiki website does.
+ if(crntCookie.name() == "JSESSIONID" ||
+ crntCookie.name() == "username" ||
+ crntCookie.name() == "password" ||
+ crntCookie.name() == "rememberme" ||
+ crntCookie.name() == "validation")
+ {
+ mCookies << crntCookie;
+ }
+ }
+ QNetworkCookie langCookie("language", "en");
+ mCookies << langCookie;
+ // DEBUG : Verify
+ for(int i = 0; i < mCookies.size(); i++)
+ {
+ qDebug() << mCookies.at(i).name() << "=" << mCookies.at(i).value();
}
// Set the cookiejar : it set the cookies that will be sent with every packet.
- qDebug() << reply->url().toString();
- mpCookieJar->setCookiesFromUrl(cookiesList, reply->url());
- mpNetworkMgr->setCookieJar(mpCookieJar);
- bCookieSet = true;
- }
+ mpCookieJar->setCookiesFromUrl(mCookies, QUrl(DOCPUBLICATION_URL)/*reply->url()*/);
- if (response.isEmpty()){
+ mpNetworkMgr->setCookieJar(mpCookieJar);
+ bLoginCookieSet = true;
emit loginDone();
}
- else{
- // Display the iframe
- mpWebView->setHtml(response, QUrl("http://sankore.devxwiki.com/xwiki/bin/view/Test/FileUpload"));
- UBApplication::applicationController->showSankoreWebDocument();
+ else
+ {
+ if (!response.isEmpty()){
+ // Display the iframe
+ mpWebView->setHtml(response, reply->url());
+ UBApplication::applicationController->showSankoreWebDocument();
+ }
+ else
+ {
+ // Redirect
+ QVariant locationHeader = reply->rawHeader("Location");
+ QNetworkRequest req(QUrl(locationHeader.toString()));
+ mpNetworkMgr->get(req);
+ qDebug() << mpWebView->url().toString();
+ }
}
+ reply->deleteLater();
}
void UBDocumentPublisher::sendUbw()
@@ -589,6 +670,7 @@ void UBDocumentPublisher::sendUbw()
QFile f(mTmpZipFile);
if (f.open(QIODevice::ReadOnly))
{
+ QFileInfo fi(f);
QByteArray ba = f.readAll();
QString boundary,data, multipartHeader;
QByteArray datatoSend;
@@ -597,23 +679,19 @@ void UBDocumentPublisher::sendUbw()
multipartHeader = "multipart/form-data; boundary="+boundary;
data="--"+boundary+mCrlf;
- data+="Content-Disposition: form-data; name=\"file\"; filename=\""+ f.fileName() +"\""+mCrlf;
+ data+="Content-Disposition: form-data; name=\"file\"; filename=\""+ fi.fileName() +"\""+mCrlf;
data+="Content-Type: application/octet-stream"+mCrlf+mCrlf;
datatoSend=data.toAscii(); // convert data string to byte array for request
datatoSend += ba;
- datatoSend += mCrlf.toAscii();
- datatoSend += QString("--%0--%1").arg(boundary).arg(mCrlf).toAscii();
+ datatoSend += mCrlf;
+ datatoSend += QString("--%0--%1").arg(boundary).arg(mCrlf);
- QNetworkRequest request(QUrl("http://sankore.devxwiki.com/xwiki/bin/view/Test/FileUpload"));
+ QNetworkRequest request(QUrl(DOCPUBLICATION_URL));
request.setHeader(QNetworkRequest::ContentTypeHeader, multipartHeader);
request.setHeader(QNetworkRequest::ContentLengthHeader,datatoSend.size());
request.setRawHeader("Accept", "application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5");
request.setRawHeader("Accept-Language", "en-US,*");
- request.setRawHeader("Referer", "http://sankore.devxwiki.com/xwiki/bin/view/Test/FileUpload");
- request.setRawHeader("Origin", "http://sankore.devxwiki.com");
-
- QString b64Auth = getBase64Of(QString("%0:%1").arg(mUsername).arg(mPassword));
- request.setRawHeader("Authorization", QString("Basic %0").arg(b64Auth).toAscii().constData());
+ request.setRawHeader("Referer", DOCPUBLICATION_URL);
// Send the file
mpNetworkMgr->post(request,datatoSend);
@@ -640,7 +718,8 @@ void UBDocumentPublisher::onLoadFinished(bool result)
{
Q_UNUSED(result);
// [Basic Auth] This line says: if the user click on a link, do not interpret it.
- mpWebView->page()->setLinkDelegationPolicy(QWebPage::DelegateAllLinks);
+ //mpWebView->page()->setLinkDelegationPolicy(QWebPage::DelegateAllLinks);
+ mpWebView->page()->setNetworkAccessManager(mpNetworkMgr);
}
diff --git a/src/adaptors/publishing/UBDocumentPublisher.h b/src/adaptors/publishing/UBDocumentPublisher.h
index 6c6cde80..8b4c289c 100644
--- a/src/adaptors/publishing/UBDocumentPublisher.h
+++ b/src/adaptors/publishing/UBDocumentPublisher.h
@@ -7,6 +7,9 @@
#include "ui_webPublishing.h"
#include "UBAbstractPublisher.h"
+#define DOCPUBLICATION_URL "http://sankore.devxwiki.com/xwiki/bin/view/CreateResources/UniboardUpload"
+#define XWIKI_ORIGIN_HEADER "http://sankore.devxwiki.com"
+
class UBDocumentProxy;
class UBServerXMLHttpRequest;
class UBGraphicsW3CWidgetItem;
@@ -38,6 +41,7 @@ private slots:
void onFinished(QNetworkReply* reply);
void onLinkClicked(const QUrl& url);
void onLoadFinished(bool result);
+ void onLoginDone();
private:
@@ -55,10 +59,12 @@ private:
QString mUsername;
QString mPassword;
QString mCrlf;
- bool bCookieSet;
+ bool bLoginCookieSet;
void buildUbwFile();
+ void login(QString username, QString password);
QString mTmpZipFile;
+ QList mCookies;
};
#endif // UBDOCUMENTPUBLISHER_H
diff --git a/src/api/UBWidgetUniboardAPI.cpp b/src/api/UBWidgetUniboardAPI.cpp
index 19555866..bda9d64b 100644
--- a/src/api/UBWidgetUniboardAPI.cpp
+++ b/src/api/UBWidgetUniboardAPI.cpp
@@ -375,6 +375,26 @@ QString UBWidgetUniboardAPI::lang()
return lang;
}
+void UBWidgetUniboardAPI::returnStatus(const QString& method, const QString& status)
+{
+ QString msg = QString(tr("%0 called (method=%1, status=%2)")).arg("returnStatus").arg(method).arg(status);
+ UBApplication::showMessage(msg);
+}
+
+void UBWidgetUniboardAPI::usedMethods(QStringList methods)
+{
+ // TODO: Implement this method
+ foreach(QString method, methods)
+ {
+
+ }
+}
+
+void UBWidgetUniboardAPI::response(bool correct)
+{
+ Q_UNUSED(correct);
+ // TODO: Implement this method
+}
UBDocumentDatastoreAPI::UBDocumentDatastoreAPI(UBGraphicsW3CWidgetItem *graphicsWidget)
diff --git a/src/api/UBWidgetUniboardAPI.h b/src/api/UBWidgetUniboardAPI.h
index 839b0bee..0310a84b 100644
--- a/src/api/UBWidgetUniboardAPI.h
+++ b/src/api/UBWidgetUniboardAPI.h
@@ -207,6 +207,9 @@ class UBWidgetUniboardAPI : public QObject
void addText(const QString& text, const qreal x, const qreal y, const int height = -1, const QString& font = ""
, bool bold = false, bool italic = false);
+ void returnStatus(const QString& method, const QString& status);
+ void usedMethods(QStringList methods);
+ void response(bool correct);
private:
QString uuid();
diff --git a/src/core/UBPreferencesController.cpp b/src/core/UBPreferencesController.cpp
index a8759889..2bf93f5b 100644
--- a/src/core/UBPreferencesController.cpp
+++ b/src/core/UBPreferencesController.cpp
@@ -38,6 +38,8 @@ UBPreferencesController::UBPreferencesController(QWidget *parent)
mPreferencesWindow = new QDialog(parent, Qt::Dialog);
mPreferencesUI = new Ui::preferencesDialog(); // deleted in UBPreferencesController::destructor
mPreferencesUI->setupUi(mPreferencesWindow);
+ connect(mPreferencesUI->Username_textBox, SIGNAL(editingFinished()), this, SLOT(onCommunityUsernameChanged()));
+ connect(mPreferencesUI->Password_textEdit, SIGNAL(editingFinished()), this, SLOT(onCommunityPasswordChanged()));
wire();
}
@@ -160,6 +162,9 @@ void UBPreferencesController::init()
mPreferencesUI->verticalChoice->setChecked(settings->appToolBarOrientationVertical->get().toBool());
mPreferencesUI->horizontalChoice->setChecked(!settings->appToolBarOrientationVertical->get().toBool());
+ mPreferencesUI->Username_textBox->setText(settings->communityUsername());
+ mPreferencesUI->Password_textEdit->setText(settings->communityPassword());
+
// pen tab
mPenProperties->fineSlider->setValue(settings->boardPenFineWidth->get().toDouble() * sSliderRatio);
mPenProperties->mediumSlider->setValue(settings->boardPenMediumWidth->get().toDouble() * sSliderRatio);
@@ -176,6 +181,18 @@ void UBPreferencesController::init()
}
+void UBPreferencesController::onCommunityUsernameChanged()
+{
+ UBSettings* settings = UBSettings::settings();
+ settings->setCommunityUsername(mPreferencesUI->Username_textBox->text());
+}
+
+void UBPreferencesController::onCommunityPasswordChanged()
+{
+ UBSettings* settings = UBSettings::settings();
+ settings->setCommunityPassword(mPreferencesUI->Password_textEdit->text());
+}
+
void UBPreferencesController::close()
{
//web
diff --git a/src/core/UBPreferencesController.h b/src/core/UBPreferencesController.h
index 9911539d..39c9cb51 100644
--- a/src/core/UBPreferencesController.h
+++ b/src/core/UBPreferencesController.h
@@ -55,6 +55,8 @@ class UBPreferencesController : public QObject
void toolbarPositionChanged(bool checked);
void toolbarOrientationVertical(bool checked);
void toolbarOrientationHorizontal(bool checked);
+ void onCommunityUsernameChanged();
+ void onCommunityPasswordChanged();
private:
diff --git a/src/core/UBSettings.cpp b/src/core/UBSettings.cpp
index ec8a59e9..3707e997 100644
--- a/src/core/UBSettings.cpp
+++ b/src/core/UBSettings.cpp
@@ -313,6 +313,9 @@ void UBSettings::init()
uniboardWebAuthor = new UBSetting(this, "UniboardWeb", "Author", "");
uniboardWebGoogleMapApiKey = new UBSetting(this, "UniboardWeb", "GoogleMapAPIKey", "ABQIAAAAsWU4bIbaeCLinpZ30N_erRQEk562OPinwQkG9J-ZXUNAqYhJ5RT_z2EmpfVXiUg8c41BcsD_XM6P5g");
+ communityUser = new UBSetting(this, "Community", "Username", "");
+ communityPsw = new UBSetting(this, "Community", "Password", "");
+
QStringList uris = UBToolsManager::manager()->allToolIDs();
favoritesNativeToolUris = new UBSetting(this, "App", "FavoriteToolURIs", uris);
@@ -1292,3 +1295,22 @@ void UBSettings::setProxyPassword(const QString& password)
}
+QString UBSettings::communityUsername()
+{
+ return communityUser->get().toString();
+}
+
+void UBSettings::setCommunityUsername(const QString &username)
+{
+ communityUser->set(QVariant(username));
+}
+
+QString UBSettings::communityPassword()
+{
+ return communityPsw->get().toString();
+}
+
+void UBSettings::setCommunityPassword(const QString &password)
+{
+ communityPsw->set(QVariant(password));
+}
diff --git a/src/core/UBSettings.h b/src/core/UBSettings.h
index d4720e66..08748383 100644
--- a/src/core/UBSettings.h
+++ b/src/core/UBSettings.h
@@ -89,6 +89,11 @@ class UBSettings : public QObject
QString proxyPassword();
void setProxyPassword(const QString& password);
+ QString communityUsername();
+ void setCommunityUsername(const QString& username);
+ QString communityPassword();
+ void setCommunityPassword(const QString& password);
+
void init();
static QString uniboardDataDirectory();
@@ -315,6 +320,9 @@ class UBSettings : public QObject
UBSetting* navigPaletteWidth;
UBSetting* libPaletteWidth;
+ UBSetting* communityUser;
+ UBSetting* communityPsw;
+
/*
static int navigPaletteWidth;
static int libPaletteWidth;
diff --git a/src/domain/UBGraphicsWidgetItem.cpp b/src/domain/UBGraphicsWidgetItem.cpp
index e7fbcc8e..7ec7cb98 100644
--- a/src/domain/UBGraphicsWidgetItem.cpp
+++ b/src/domain/UBGraphicsWidgetItem.cpp
@@ -36,7 +36,7 @@ void UBGraphicsWidgetItem::javaScriptWindowObjectCleared()
if(!mUniboardAPI)
mUniboardAPI = new UBWidgetUniboardAPI(scene(), this);
- mWebKitWidget->page()->mainFrame()->addToJavaScriptWindowObject("uniboard", mUniboardAPI);
+ mWebKitWidget->page()->mainFrame()->addToJavaScriptWindowObject("sankore", mUniboardAPI);
}
diff --git a/src/domain/UBW3CWidget.cpp b/src/domain/UBW3CWidget.cpp
index 4ca26cfb..81ec3201 100644
--- a/src/domain/UBW3CWidget.cpp
+++ b/src/domain/UBW3CWidget.cpp
@@ -169,7 +169,7 @@ void UBW3CWidget::javaScriptWindowObjectCleared()
{
UBWidgetUniboardAPI *uniboardAPI = new UBWidgetUniboardAPI(UBApplication::boardController->activeScene(), 0);
- page()->mainFrame()->addToJavaScriptWindowObject("uniboard", uniboardAPI);
+ page()->mainFrame()->addToJavaScriptWindowObject("sankore", uniboardAPI);
UBWidgetVotingSystemAPI *votingSystem = new UBWidgetVotingSystemAPI(this);
page()->mainFrame()->addToJavaScriptWindowObject("voting", votingSystem);
diff --git a/src/gui/UBToolWidget.cpp b/src/gui/UBToolWidget.cpp
index 539d8b66..60a15b9c 100644
--- a/src/gui/UBToolWidget.cpp
+++ b/src/gui/UBToolWidget.cpp
@@ -120,7 +120,7 @@ void UBToolWidget::javaScriptWindowObjectCleared()
{
UBWidgetUniboardAPI* uniboardAPI = new UBWidgetUniboardAPI(UBApplication::boardController->activeScene());
- mToolWidget->page()->mainFrame()->addToJavaScriptWindowObject("uniboard", uniboardAPI);
+ mToolWidget->page()->mainFrame()->addToJavaScriptWindowObject("sankore", uniboardAPI);
UBW3CWidget* w3c = dynamic_cast(mToolWidget);
if (w3c)
diff --git a/src/pdf/XPDFRenderer.cpp b/src/pdf/XPDFRenderer.cpp
index cf81d4ae..b961173f 100644
--- a/src/pdf/XPDFRenderer.cpp
+++ b/src/pdf/XPDFRenderer.cpp
@@ -183,7 +183,10 @@ void XPDFRenderer::render(QPainter *p, int pageNumber, const QRectF &bounds)
QTransform savedTransform = p->worldTransform();
p->resetTransform();
+ QTime t;
+ t.start();
p->drawImage(QPointF(savedTransform.dx() + mSliceX, savedTransform.dy() + mSliceY), pdfImage);
+ //qDebug() << "XPDFRenderer::render(...) execution time: " << t.elapsed() << "ms";
p->setWorldTransform(savedTransform);
}
}
diff --git a/src/tools/UBGraphicsTriangle.cpp b/src/tools/UBGraphicsTriangle.cpp
index f60cf9cf..7c9e4605 100644
--- a/src/tools/UBGraphicsTriangle.cpp
+++ b/src/tools/UBGraphicsTriangle.cpp
@@ -40,9 +40,35 @@ UBGraphicsTriangle::UBGraphicsTriangle()
mRotateSvgItem->setVisible(false);
mRotateSvgItem->setData(UBGraphicsItemData::ItemLayerType, QVariant(UBItemLayerType::Control));
- //updateResizeCursor();
+ updateResizeCursor();
}
+
+void UBGraphicsTriangle::updateResizeCursor()
+{
+ QPixmap pix(":/images/cursors/resize.png");
+ QTransform itemTransform = sceneTransform();
+ QRectF itemRect = boundingRect();
+
+ QPointF topLeft = itemTransform.map(itemRect.topLeft());
+ QPointF topRight = itemTransform.map(itemRect.topRight());
+ QPointF bottomLeft = itemTransform.map(itemRect.bottomLeft());
+
+ QLineF topLine(topLeft, topRight);
+ QLineF leftLine(topLeft, bottomLeft);
+
+ qreal angle = topLine.angle();
+ QTransform tr1;
+ tr1.rotate(- angle);
+ mResizeCursor1 = QCursor(pix.transformed(tr1, Qt::SmoothTransformation), pix.width() / 2, pix.height() / 2);
+
+ angle = leftLine.angle();
+ QTransform tr2;
+ tr2.rotate(- angle);
+ mResizeCursor2 = QCursor(pix.transformed(tr2, Qt::SmoothTransformation), pix.width() / 2, pix.height() / 2);
+}
+
+
UBGraphicsTriangle::~UBGraphicsTriangle()
{
}
@@ -65,7 +91,7 @@ UBItem* UBGraphicsTriangle::deepCopy(void) const
void UBGraphicsTriangle::setRect(qreal x, qreal y, qreal w, qreal h, UBGraphicsTriangleOrientation orientation)
{
QPolygonF polygon;
- polygon << QPointF(x, y) << QPoint(x, y + h) << QPoint(x+w, y + h) << QPoint(x, y);
+ polygon << QPointF(x, y) << QPoint(x, y + h) << QPoint(x+w, y + h);
setPolygon(polygon);
setOrientation(orientation);
@@ -73,26 +99,12 @@ void UBGraphicsTriangle::setRect(qreal x, qreal y, qreal w, qreal h, UBGraphicsT
void UBGraphicsTriangle::setOrientation(UBGraphicsTriangleOrientation orientation)
{
- mOrientation = orientation;
- QTransform t;
- switch(orientation)
- {
- case BottomLeft:
- t.setMatrix(1, 0, 0, 0, 1, 0, 0, 0, 1);
- break;
- case BottomRight:
- t.setMatrix(-1, 0, 0, 0, 1, 0, boundingRect().right(), 0, 1);
- break;
- case TopLeft:
- t.setMatrix(1, 0, 0, 0, -1, 0, 0, boundingRect().bottom(), 1);
- break;
- case TopRight:
- t.setMatrix(-1, 0, 0, 0, -1, 0, boundingRect().right(), boundingRect().bottom(), 1);
- break;
- }
+ mOrientation = orientation;
+ calculatePoints(boundingRect());
- rotateAroundCenter(t);
- setTransform(t);
+ QPolygonF polygon;
+ polygon << A1 << B1 << C1;
+ setPolygon(polygon);
}
UBGraphicsScene* UBGraphicsTriangle::scene() const
@@ -100,25 +112,81 @@ UBGraphicsScene* UBGraphicsTriangle::scene() const
return static_cast(QGraphicsPolygonItem::scene());
}
-void UBGraphicsTriangle::paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *)
+void UBGraphicsTriangle::calculatePoints(const QRectF& r)
{
- QPointF A1(rect().x(), rect().y());
- QPointF B1(rect().x(), rect().y() + rect().height());
- QPointF C1(rect().x() + rect().width(), rect().y() + rect().height());
+ switch(mOrientation)
+ {
+ case BottomLeft:
+ A1.setX(r.left()); A1.setY(r.top());
+ B1.setX(r.left()); B1.setY(r.bottom());
+ C1.setX(r.right()); C1.setY(r.bottom());
+ break;
+ case TopLeft:
+ A1.setX(r.left()); A1.setY(r.bottom());
+ B1.setX(r.left()); B1.setY(r.top());
+ C1.setX(r.right()); C1.setY(r.top());
+ break;
+ case TopRight:
+ A1.setX(r.right()); A1.setY(r.bottom());
+ B1.setX(r.right()); B1.setY(r.top());
+ C1.setX(r.left()); C1.setY(r.top());
+ break;
+ case BottomRight:
+ A1.setX(r.right()); A1.setY(r.top());
+ B1.setX(r.right()); B1.setY(r.bottom());
+ C1.setX(r.left()); C1.setY(r.bottom());
+ break;
+ }
- qreal C = sqrt(rect().width() * rect().width() + rect().height() * rect().height());
+ C = sqrt(rect().width() * rect().width() + rect().height() * rect().height());
qreal L = (C * d + rect().width() * d)/ rect().height();
qreal K = (C * d + rect().height() * d)/ rect().width();
- qreal W1 = rect().height() * d / C;
- qreal H1 = rect().width() * d / C;
+ switch(mOrientation)
+ {
+ case BottomLeft:
+ A2.setX(r.left() + d); A2.setY(r.top() + K);
+ B2.setX(r.left() + d); B2.setY(r.bottom() - d);
+ C2.setX(r.right() - L); C2.setY(r.bottom() - d);
+ break;
+ case TopLeft:
+ A2.setX(r.left() + d); A2.setY(r.bottom() - K);
+ B2.setX(r.left() + d); B2.setY(r.top() + d);
+ C2.setX(r.right() - L); C2.setY(r.top() + d);
+ break;
+ case TopRight:
+ A2.setX(r.right() - d); A2.setY(r.bottom() - K);
+ B2.setX(r.right() - d); B2.setY(r.top() + d);
+ C2.setX(r.left() + L); C2.setY(r.top() + d);
+ break;
+ case BottomRight:
+ A2.setX(r.right() - d); A2.setY(r.top() + K);
+ B2.setX(r.right() - d); B2.setY(r.bottom() - d);
+ C2.setX(r.left() + L); C2.setY(r.bottom() - d);
+ break;
+ }
+ W1 = rect().height() * d / C;
+ H1 = rect().width() * d / C;
- QPointF A2(rect().x() + d, rect().y() + K);
- QPointF B2(rect().x() + d, rect().y() + rect().height() - d);
- QPointF C2(rect().x() + rect().width() - L, rect().y() + rect().height() - d);
+ switch(mOrientation)
+ {
+ case BottomLeft:
+ CC.setX(r.right() - L + W1); CC.setY(r.bottom() - d - H1);
+ break;
+ case TopLeft:
+ CC.setX(r.right() - L + W1); CC.setY(r.top() + d + H1);
+ break;
+ case TopRight:
+ CC.setX(r.left() + L - W1); CC.setY(r.top() + d + H1);
+ break;
+ case BottomRight:
+ CC.setX(r.left() + L - W1); CC.setY(r.top() - d - H1);
+ break;
+ }
+}
- QPoint CC(rect().x() + rect().width() - L + W1,
- rect().y() + rect().height() - d - H1);
+void UBGraphicsTriangle::paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *)
+{
painter->setPen(Qt::NoPen);
@@ -193,41 +261,76 @@ void UBGraphicsTriangle::paintGraduations(QPainter *painter)
const int millimetersPerCentimeter = 10;
const int millimetersPerHalfCentimeter = 5;
+ qreal kx = (mOrientation == TopLeft || mOrientation == BottomLeft) ? 1 : -1;
+ qreal ky = (mOrientation == BottomLeft || mOrientation == BottomRight) ? 1 : -1;
+
painter->save();
painter->setFont(font());
QFontMetricsF fontMetrics(painter->font());
for (int millimeters = 0; millimeters < (rect().width() - sLeftEdgeMargin - sRoundingRadius) / sPixelsPerMillimeter; millimeters++)
{
- int graduationX = rotationCenter().x() + sPixelsPerMillimeter * millimeters;
+ int graduationX = rotationCenter().x() + kx * sPixelsPerMillimeter * millimeters;
int graduationHeight = (0 == millimeters % millimetersPerCentimeter) ?
centimeterGraduationHeight :
((0 == millimeters % millimetersPerHalfCentimeter) ?
halfCentimeterGraduationHeight : millimeterGraduationHeight);
// Check that grad. line inside triangle
- qreal lineY = rect().bottom() - rect().height()/rect().width()*(rect().width() - graduationX);
- if (lineY >= rotationCenter().y() - graduationHeight)
- break;
+ qreal dx = (kx > 0) ? rect().width() - graduationX : graduationX - rect().x();
+ qreal lineY = rotationCenter().y() - ky * rect().height()/rect().width() * dx;
+ if (mOrientation == BottomLeft || mOrientation == BottomRight)
+ {
+ if (lineY >= rotationCenter().y() - ky * graduationHeight)
+ break;
+ }
+ else
+ {
+ if (lineY <= rotationCenter().y() - ky * graduationHeight)
+ break;
+ }
- painter->drawLine(QLine(graduationX, rotationCenter().y(), graduationX, rotationCenter().y() - graduationHeight));
+ painter->drawLine(QLine(graduationX, rotationCenter().y(), graduationX, rotationCenter().y() - ky * graduationHeight));
if (0 == millimeters % millimetersPerCentimeter)
{
QString text = QString("%1").arg((int)(millimeters / millimetersPerCentimeter));
int textXRight = graduationX + fontMetrics.width(text) / 2;
qreal textWidth = fontMetrics.width(text);
qreal textHeight = fontMetrics.tightBoundingRect(text).height() + 5;
- int textY = rect().bottom() - 5 - centimeterGraduationHeight - textHeight;
- lineY = rect().bottom() - rect().height()/rect().width()*(rect().width() - textXRight);
+ int textY = (ky > 0) ? rotationCenter().y() - 5 - centimeterGraduationHeight - textHeight
+ : rotationCenter().y() + 5 + centimeterGraduationHeight;
- if (textXRight < rect().right()
- && lineY < textY)
+ bool bText = false;
+ switch(mOrientation)
{
+ case BottomLeft:
+ dx = rect().width() - textXRight;
+ lineY = rotationCenter().y() - rect().height()/rect().width() * dx;
+ bText = lineY <= textY;
+ break;
+ case TopLeft:
+ dx = rect().width() - textXRight;
+ lineY = rotationCenter().y() + rect().height()/rect().width() * dx;
+ bText = lineY >= textY + textHeight;
+ break;
+ case TopRight:
+ dx = textXRight - textWidth - rect().left();
+ lineY = rotationCenter().y() + rect().height()/rect().width() * dx;
+ bText = lineY >= textY + textHeight;
+ break;
+ case BottomRight:
+ dx = textXRight - textWidth - rect().left();
+ lineY = rotationCenter().y() - rect().height()/rect().width() * dx;
+ bText = lineY <= textY;
+ break;
+ }
+
+ if (bText)
painter->drawText(
QRectF(graduationX - textWidth / 2,
- textY, textWidth, textHeight),
+ textY, textWidth, textHeight),
Qt::AlignVCenter, text);
- }
+
}
}
painter->restore();
@@ -236,98 +339,210 @@ void UBGraphicsTriangle::paintGraduations(QPainter *painter)
void UBGraphicsTriangle::rotateAroundCenter(qreal angle)
{
+ qreal oldAngle = this->angle;
this->angle = angle;
QTransform transform;
- rotateAroundCenter(transform);
+ rotateAroundCenter(transform, rotationCenter());
setTransform(transform, true);
+ this->angle = oldAngle + angle; // We have to store absolute value for FLIP case
}
-void UBGraphicsTriangle::rotateAroundCenter(QTransform& transform)
+void UBGraphicsTriangle::rotateAroundCenter(QTransform& transform, QPointF center)
{
- transform.translate(rotationCenter().x(), rotationCenter().y());
+ transform.translate(center.x(), center.y());
transform.rotate(angle);
- transform.translate(- rotationCenter().x(), - rotationCenter().y());
+ transform.translate(- center.x(), - center.y());
}
QPointF UBGraphicsTriangle::rotationCenter() const
{
- return QPointF(rect().x() + sLeftEdgeMargin , rect().bottom());
+ switch(mOrientation)
+ {
+ case BottomLeft:
+ case TopLeft:
+ return B1 + QPointF(sLeftEdgeMargin, 0);
+ case TopRight:
+ case BottomRight:
+ return B1 - QPointF(sLeftEdgeMargin, 0);
+ }
+ return QPointF(0, 0);
}
QRectF UBGraphicsTriangle::closeButtonRect() const
{
- return QRectF(rect().x() + d - mCloseSvgItem->boundingRect().width() - 5,
- rect().bottom() - d - mCloseSvgItem->boundingRect().height() - 5,
- mCloseSvgItem->boundingRect().width(),
- mCloseSvgItem->boundingRect().height());
+ switch(mOrientation)
+ {
+ case BottomLeft:
+ return QRectF(B2.x() - mCloseSvgItem->boundingRect().width() - 5,
+ B2.y() - mCloseSvgItem->boundingRect().height() - 5,
+ mCloseSvgItem->boundingRect().width(),
+ mCloseSvgItem->boundingRect().height());
+ case TopLeft:
+ return QRectF(B2.x() - mCloseSvgItem->boundingRect().width() - 5,
+ B2.y() + 5,
+ mCloseSvgItem->boundingRect().width(),
+ mCloseSvgItem->boundingRect().height());
+ case TopRight:
+ return QRectF(B2.x() + 5,
+ B2.y() + 5,
+ mCloseSvgItem->boundingRect().width(),
+ mCloseSvgItem->boundingRect().height());
+ case BottomRight:
+ return QRectF(B2.x() + 5,
+ B2.y() - mCloseSvgItem->boundingRect().height() - 5,
+ mCloseSvgItem->boundingRect().width(),
+ mCloseSvgItem->boundingRect().height());
+ }
+ return QRectF(0,0,0,0);
}
QPolygonF UBGraphicsTriangle::resize1Polygon() const
{
- qreal C = sqrt(rect().width() * rect().width() + rect().height() * rect().height());
-
+ qreal x1, y1;
+ switch(mOrientation)
+ {
+ case BottomLeft:
+ x1 = -1;
+ y1 = -1;
+ break;
+ case TopLeft:
+ x1 = -1;
+ y1 = 1;
+ break;
+ case TopRight:
+ x1 = 1;
+ y1 = 1;
+ break;
+ case BottomRight:
+ x1 = 1;
+ y1 = -1;
+ break;
+ }
+ QPointF P1(C1.x() + x1 * sArrowLength, C1.y());
+ QPointF P2(C1.x() + x1 * sArrowLength * rect().width()/C, C1.y() + y1 * sArrowLength * rect().height() / C);
QPolygonF p;
-
- QPointF P1(rect().right() - sArrowLength, rect().bottom());
- QPointF P2(rect().right() - sArrowLength * rect().width() / C,
- rect().bottom() - sArrowLength * rect().height() / C );
-
- p << QPointF(rect().right(), rect().bottom()) << P1 << P2;
-
+ p << C1 << P1 << P2;
return p;
}
QPolygonF UBGraphicsTriangle::resize2Polygon() const
{
- qreal C = sqrt(rect().width() * rect().width() + rect().height() * rect().height());
-
+ qreal x1, y1;
+ switch(mOrientation)
+ {
+ case BottomLeft:
+ x1 = 1;
+ y1 = 1;
+ break;
+ case TopLeft:
+ x1 = 1;
+ y1 = -1;
+ break;
+ case TopRight:
+ x1 = -1;
+ y1 = -1;
+ break;
+ case BottomRight:
+ x1 = -1;
+ y1 = 1;
+ break;
+ }
+ QPointF P1(A1.x(), A1.y() + y1 * sArrowLength);
+ QPointF P2(A1.x() + x1 * sArrowLength * rect().width()/C,
+ A1.y() + y1 * sArrowLength * rect().height() / C);
QPolygonF p;
-
- QPointF P1(rect().left(), rect().top() + sArrowLength);
- QPointF P2(rect().left() + sArrowLength * rect().width() / C,
- rect().top() + sArrowLength * rect().height() / C );
-
- p << QPointF(rect().left(), rect().top()) << P1 << P2;
-
+ p << A1 << P1 << P2;
return p;
}
QRectF UBGraphicsTriangle::hFlipRect() const
{
- return QRectF(rect().x() + d - mHFlipSvgItem->boundingRect().width() - 5,
- rect().bottom() - d - mCloseSvgItem->boundingRect().height() - mVFlipSvgItem->boundingRect().height() -
- mVFlipSvgItem->boundingRect().height() - 15,
- mHFlipSvgItem->boundingRect().width(),
- mHFlipSvgItem->boundingRect().height());
+ qreal dy = mVFlipSvgItem->boundingRect().height() + mCloseSvgItem->boundingRect().height() + 10;
+ switch(mOrientation)
+ {
+ case BottomLeft:
+ return QRectF(B2.x() - mHFlipSvgItem->boundingRect().width() - 5,
+ B2.y() - mHFlipSvgItem->boundingRect().height() - 5 - dy,
+ mHFlipSvgItem->boundingRect().width(),
+ mHFlipSvgItem->boundingRect().height());
+ case TopLeft:
+ return QRectF(B2.x() - mHFlipSvgItem->boundingRect().width() - 5,
+ B2.y() + 5 + dy,
+ mHFlipSvgItem->boundingRect().width(),
+ mHFlipSvgItem->boundingRect().height());
+ case TopRight:
+ return QRectF(B2.x() + 5,
+ B2.y() + 5 + dy,
+ mHFlipSvgItem->boundingRect().width(),
+ mHFlipSvgItem->boundingRect().height());
+ case BottomRight:
+ return QRectF(B2.x() + 5,
+ B2.y() - mHFlipSvgItem->boundingRect().height() - 5 - dy,
+ mHFlipSvgItem->boundingRect().width(),
+ mHFlipSvgItem->boundingRect().height());
+ }
+ return QRectF(0,0,0,0);
}
QRectF UBGraphicsTriangle::vFlipRect() const
{
- return QRectF(rect().x() + d - mVFlipSvgItem->boundingRect().width() - 5,
- rect().bottom() - d - mCloseSvgItem->boundingRect().height() - mVFlipSvgItem->boundingRect().height() - 10,
- mVFlipSvgItem->boundingRect().width(),
- mVFlipSvgItem->boundingRect().height());
+ qreal dy = mCloseSvgItem->boundingRect().height() + 5;
+ switch(mOrientation)
+ {
+ case BottomLeft:
+ return QRectF(B2.x() - mVFlipSvgItem->boundingRect().width() - 5,
+ B2.y() - mVFlipSvgItem->boundingRect().height() - 5 - dy,
+ mVFlipSvgItem->boundingRect().width(),
+ mVFlipSvgItem->boundingRect().height());
+ case TopLeft:
+ return QRectF(B2.x() - mVFlipSvgItem->boundingRect().width() - 5,
+ B2.y() + 5 + dy,
+ mVFlipSvgItem->boundingRect().width(),
+ mVFlipSvgItem->boundingRect().height());
+ case TopRight:
+ return QRectF(B2.x() + 5,
+ B2.y() + 5 + dy,
+ mVFlipSvgItem->boundingRect().width(),
+ mVFlipSvgItem->boundingRect().height());
+ case BottomRight:
+ return QRectF(B2.x() + 5,
+ B2.y() - mVFlipSvgItem->boundingRect().height() - 5 - dy,
+ mVFlipSvgItem->boundingRect().width(),
+ mVFlipSvgItem->boundingRect().height());
+ }
+ return QRectF(0,0,0,0);
}
QRectF UBGraphicsTriangle::rotateRect() const
{
- QPointF A1(rect().x(), rect().y());
- QPointF B1(rect().x(), rect().y() + rect().height());
- QPointF C1(rect().x() + rect().width(), rect().y() + rect().height());
-
- qreal C = sqrt(rect().width() * rect().width() + rect().height() * rect().height());
- qreal L = (C * d + rect().width() * d)/ rect().height();
-
- QPointF C2(rect().x() + rect().width() - L, rect().y() + rect().height() - d);
-
- return QRectF(C2 + QPointF(20, 5), QSizeF(mRotateSvgItem->boundingRect().size()));
+ QPointF p(C2);
+ switch(mOrientation)
+ {
+ case BottomLeft:
+ p += QPointF(20, 5);
+ break;
+ case TopLeft:
+ p += QPointF(20, -5 - mRotateSvgItem->boundingRect().height());
+ break;
+ case TopRight:
+ p += QPointF(-20 - mRotateSvgItem->boundingRect().width(), -5 - mRotateSvgItem->boundingRect().height());
+ break;
+ case BottomRight:
+ p += QPointF(-20 - mRotateSvgItem->boundingRect().width(), 5);
+ break;
+ }
+ return QRectF(p, QSizeF(mRotateSvgItem->boundingRect().size()));
+}
+QCursor UBGraphicsTriangle::resizeCursor1() const
+{
+ return mResizeCursor1;
}
-QCursor UBGraphicsTriangle::moveResizeCursor() const
+QCursor UBGraphicsTriangle::resizeCursor2() const
{
- return Qt::OpenHandCursor;
+ return mResizeCursor2;
}
QCursor UBGraphicsTriangle::flipCursor() const
@@ -376,8 +591,16 @@ void UBGraphicsTriangle::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
if (mResizing1)
{
QPointF delta = event->pos() - event->lastPos();
- if (rect().width() + delta.x() < sMinWidth)
- delta.setX(sMinWidth - rect().width());
+ if (mOrientation == TopLeft || mOrientation == BottomLeft)
+ {
+ if (rect().width() + delta.x() < sMinWidth)
+ delta.setX(sMinWidth - rect().width());
+ }
+ else
+ {
+ if (rect().width() - delta.x() < sMinWidth)
+ delta.setX(sMinWidth - rect().width());
+ }
if (mOrientation == TopLeft || mOrientation == BottomLeft)
{
setRect(QRectF(
@@ -388,11 +611,11 @@ void UBGraphicsTriangle::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
}
else
{
- setRect(
- rect().left() - delta.x(),
+ setRect(QRectF(
+ rect().left() + delta.x(),
rect().top(),
- rect().width() + delta.x(),
- rect().height(),
+ rect().width() - delta.x(),
+ rect().height()),
mOrientation
);
}
@@ -400,15 +623,30 @@ void UBGraphicsTriangle::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
if (mResizing2)
{
QPointF delta = event->pos() - event->lastPos();
- if (rect().height() + delta.y() < sMinHeight)
- delta.setY(sMinHeight - rect().height());
- qDebug() << delta;
- setRect(QRect(
- rect().left(),
- rect().top() + delta.y(),
- rect().width(),
- rect().height() - delta.y()),
- mOrientation);
+ if (mOrientation == BottomRight || mOrientation == BottomLeft)
+ {
+ if (rect().height() - delta.y() < sMinHeight)
+ delta.setY(sMinHeight - rect().height());
+ }
+ else
+ {
+ if (rect().height() + delta.y() < sMinHeight)
+ delta.setY(sMinHeight - rect().height());
+ }
+ if (mOrientation == BottomRight || mOrientation == BottomLeft)
+ setRect(QRectF(
+ rect().left(),
+ rect().top() + delta.y(),
+ rect().width(),
+ rect().height() - delta.y()),
+ mOrientation);
+ else
+ setRect(QRectF(
+ rect().left(),
+ rect().top(),
+ rect().width(),
+ rect().height() + delta.y()),
+ mOrientation);
}
if (mRotating)
{
@@ -425,6 +663,8 @@ void UBGraphicsTriangle::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
{
if (mResizing1 || mResizing2 || mRotating)
{
+ if (mRotating)
+ updateResizeCursor();
mResizing1 = false;
mResizing2 = false;
mRotating = false;
@@ -496,9 +736,10 @@ void UBGraphicsTriangle::hoverEnterEvent(QGraphicsSceneHoverEvent *event)
mVFlipSvgItem->setVisible(true);
mRotateSvgItem->setVisible(true);
- if (resize1Polygon().containsPoint(event->pos().toPoint(), Qt::OddEvenFill) ||
- resize2Polygon().containsPoint(event->pos().toPoint(), Qt::OddEvenFill))
- setCursor(moveResizeCursor());
+ if (resize1Polygon().containsPoint(event->pos().toPoint(), Qt::OddEvenFill))
+ setCursor(resizeCursor1());
+ else if(resize2Polygon().containsPoint(event->pos().toPoint(), Qt::OddEvenFill))
+ setCursor(resizeCursor2());
else if (closeButtonRect().contains(event->pos()))
setCursor(closeCursor());
else if (hFlipRect().contains(event->pos())
@@ -537,9 +778,10 @@ void UBGraphicsTriangle::hoverMoveEvent(QGraphicsSceneHoverEvent *event)
mHFlipSvgItem->setVisible(mShowButtons);
mRotateSvgItem->setVisible(mShowButtons);
- if (resize1Polygon().containsPoint(event->pos().toPoint(), Qt::OddEvenFill) ||
- resize2Polygon().containsPoint(event->pos().toPoint(), Qt::OddEvenFill))
- setCursor(moveResizeCursor());
+ if (resize1Polygon().containsPoint(event->pos().toPoint(), Qt::OddEvenFill))
+ setCursor(resizeCursor1());
+ else if (resize2Polygon().containsPoint(event->pos().toPoint(), Qt::OddEvenFill))
+ setCursor(resizeCursor2());
else if (closeButtonRect().contains(event->pos()))
setCursor(closeCursor());
else if (hFlipRect().contains(event->pos())
diff --git a/src/tools/UBGraphicsTriangle.h b/src/tools/UBGraphicsTriangle.h
index 69e9f436..1ff52999 100644
--- a/src/tools/UBGraphicsTriangle.h
+++ b/src/tools/UBGraphicsTriangle.h
@@ -67,6 +67,8 @@ class UBGraphicsTriangle : public UBAbstractDrawRuler, public QGraphicsPolygonIt
protected:
+ void updateResizeCursor();
+
virtual void paint (QPainter *painter, const QStyleOptionGraphicsItem *styleOption, QWidget *widget);
virtual void rotateAroundCenter(qreal angle);
@@ -80,7 +82,9 @@ class UBGraphicsTriangle : public UBAbstractDrawRuler, public QGraphicsPolygonIt
QRectF vFlipRect() const;
QRectF rotateRect() const;
- QCursor moveResizeCursor() const;
+ QCursor resizeCursor1() const;
+ QCursor resizeCursor2() const;
+
QCursor flipCursor() const;
virtual void mousePressEvent(QGraphicsSceneMouseEvent *event);
@@ -92,9 +96,12 @@ class UBGraphicsTriangle : public UBAbstractDrawRuler, public QGraphicsPolygonIt
private:
+ QCursor mResizeCursor1;
+ QCursor mResizeCursor2;
+
QTransform calculateRotationTransform();
qreal angle;
- void rotateAroundCenter(QTransform& transform);
+ void rotateAroundCenter(QTransform& transform, QPointF center);
bool mResizing1;
bool mResizing2;
@@ -112,10 +119,16 @@ class UBGraphicsTriangle : public UBAbstractDrawRuler, public QGraphicsPolygonIt
UBGraphicsTriangleOrientation mOrientation;
+ QPointF A1, B1, C1, A2, B2, C2; // coordinates of points in ext and int triangles
+ qreal C;
+ qreal W1, H1; // Neccessary for filling
+ QPointF CC; // Hyp. fillining gradient - top point
+ void calculatePoints(const QRectF& rect);
+
static const int d = 70; // width of triangle border
static const int sArrowLength = 30;
- static const int sMinWidth = 200;
- static const int sMinHeight = 150;
+ static const int sMinWidth = 380;
+ static const int sMinHeight = 200;
};
#endif /* UBGRAPHICSTRIANGLE_H_ */