HGGitLab
Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
A
app
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
CI / CD Analytics
Repository Analytics
Value Stream Analytics
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
luoliangyi
app
Commits
735ab83d
Commit
735ab83d
authored
Apr 06, 2022
by
luoliangyi
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
1.解决在linux系统上点击右键菜单,m_pushItemIndex不会重置的问题
2.增加多张旋转功能 3.增加色彩设置功能
parent
2ca82532
Changes
17
Hide whitespace changes
Inline
Side-by-side
Showing
17 changed files
with
1267 additions
and
4 deletions
+1267
-4
app/Scanner/Scanner/Scanner.pro
app/Scanner/Scanner/Scanner.pro
+14
-2
app/Scanner/Scanner/dialog_imgproc_adjust.cpp
app/Scanner/Scanner/dialog_imgproc_adjust.cpp
+118
-0
app/Scanner/Scanner/dialog_imgproc_adjust.h
app/Scanner/Scanner/dialog_imgproc_adjust.h
+50
-0
app/Scanner/Scanner/dialog_imgproc_adjust.ui
app/Scanner/Scanner/dialog_imgproc_adjust.ui
+169
-0
app/Scanner/Scanner/dialog_multirotate.cpp
app/Scanner/Scanner/dialog_multirotate.cpp
+44
-0
app/Scanner/Scanner/dialog_multirotate.h
app/Scanner/Scanner/dialog_multirotate.h
+35
-0
app/Scanner/Scanner/dialog_multirotate.ui
app/Scanner/Scanner/dialog_multirotate.ui
+171
-0
app/Scanner/Scanner/dialog_multirotateimagefile.cpp
app/Scanner/Scanner/dialog_multirotateimagefile.cpp
+131
-0
app/Scanner/Scanner/dialog_multirotateimagefile.h
app/Scanner/Scanner/dialog_multirotateimagefile.h
+49
-0
app/Scanner/Scanner/dialog_multirotateimagefile.ui
app/Scanner/Scanner/dialog_multirotateimagefile.ui
+78
-0
app/Scanner/Scanner/mainwindow.cpp
app/Scanner/Scanner/mainwindow.cpp
+129
-0
app/Scanner/Scanner/mainwindow.h
app/Scanner/Scanner/mainwindow.h
+6
-0
app/Scanner/Scanner/mainwindow.ui
app/Scanner/Scanner/mainwindow.ui
+2
-2
app/Scanner/Scanner/widget_imgproc_base.cpp
app/Scanner/Scanner/widget_imgproc_base.cpp
+48
-0
app/Scanner/Scanner/widget_imgproc_base.h
app/Scanner/Scanner/widget_imgproc_base.h
+35
-0
app/Scanner/Scanner/widget_imgproc_base.ui
app/Scanner/Scanner/widget_imgproc_base.ui
+186
-0
ui/HGImgThumb.cpp
ui/HGImgThumb.cpp
+2
-0
No files found.
app/Scanner/Scanner/Scanner.pro
View file @
735ab83d
...
...
@@ -56,13 +56,17 @@ SOURCES += \
dialog_exportimagefile
.
cpp
\
dialog_fullscreen
.
cpp
\
dialog_imageinfo
.
cpp
\
dialog_imgproc_adjust
.
cpp
\
dialog_multirotate
.
cpp
\
dialog_multirotateimagefile
.
cpp
\
dialog_openimageindex
.
cpp
\
dialog_saveas
.
cpp
\
dialog_savequality
.
cpp
\
main
.
cpp
\
mainwindow
.
cpp
\
..
/../../
ui
/
HGImgView
.
cpp
\
..
/../../
ui
/
HGImgThumb
.
cpp
..
/../../
ui
/
HGImgThumb
.
cpp
\
widget_imgproc_base
.
cpp
HEADERS
+=
\
..
/../../
ui
/
HGUIGlobal
.
h
\
...
...
@@ -70,22 +74,30 @@ HEADERS += \
dialog_exportimagefile
.
h
\
dialog_fullscreen
.
h
\
dialog_imageinfo
.
h
\
dialog_imgproc_adjust
.
h
\
dialog_multirotate
.
h
\
dialog_multirotateimagefile
.
h
\
dialog_openimageindex
.
h
\
dialog_saveas
.
h
\
dialog_savequality
.
h
\
mainwindow
.
h
\
..
/../../
ui
/
HGImgView
.
h
\
..
/../../
ui
/
HGImgThumb
.
h
..
/../../
ui
/
HGImgThumb
.
h
\
widget_imgproc_base
.
h
FORMS
+=
\
dialog_export
.
ui
\
dialog_exportimagefile
.
ui
\
dialog_fullscreen
.
ui
\
dialog_imageinfo
.
ui
\
dialog_imgproc_adjust
.
ui
\
dialog_multirotate
.
ui
\
dialog_multirotateimagefile
.
ui
\
dialog_openimageindex
.
ui
\
dialog_saveas
.
ui
\
dialog_savequality
.
ui
\
mainwindow
.
ui
\
widget_imgproc_base
.
ui
TRANSLATIONS
+=
\
Scanner_zh_CN
.
ts
...
...
app/Scanner/Scanner/dialog_imgproc_adjust.cpp
0 → 100644
View file @
735ab83d
#include "dialog_imgproc_adjust.h"
#include "ui_dialog_imgproc_adjust.h"
#include "imgproc/HGImgProc.h"
Dialog_ImgProc_Adjust
::
Dialog_ImgProc_Adjust
(
HGImage
img
,
QWidget
*
parent
)
:
QDialog
(
parent
),
ui
(
new
Ui
::
Dialog_ImgProc_Adjust
)
{
ui
->
setupUi
(
this
);
ui
->
view_before
->
addImage
(
img
);
ui
->
view_after
->
addImage
(
img
);
ui
->
gbox_before
->
setVisible
(
ui
->
cbtn_preview
->
isChecked
());
ui
->
gbox_after
->
setVisible
(
ui
->
cbtn_preview
->
isChecked
());
m_base_widget
=
new
Widget_Imgproc_Base
(
this
);
reinterpret_cast
<
QVBoxLayout
*>
(
this
->
layout
())
->
insertWidget
(
2
,
m_base_widget
);
connect
(
m_base_widget
,
SIGNAL
(
brightness_change
(
int
)),
this
,
SLOT
(
on_brightness_change
(
int
)));
connect
(
m_base_widget
,
SIGNAL
(
contrast_change
(
int
)),
this
,
SLOT
(
on_contrast_change
(
int
)));
connect
(
m_base_widget
,
SIGNAL
(
gamma_change
(
double
)),
this
,
SLOT
(
on_gamma_change
(
double
)));
m_brightness
=
0
;
m_contrast
=
0
;
m_gamma
=
1.0
;
}
Dialog_ImgProc_Adjust
::~
Dialog_ImgProc_Adjust
()
{
delete
ui
;
}
HGImage
Dialog_ImgProc_Adjust
::
getBeforeImage
()
{
HGImage
img
=
nullptr
;
ui
->
view_before
->
getImage
(
&
img
);
return
img
;
}
HGImage
Dialog_ImgProc_Adjust
::
getAfterImage
()
{
HGImage
img
=
nullptr
;
ui
->
view_after
->
getImage
(
&
img
);
return
img
;
}
void
Dialog_ImgProc_Adjust
::
on_brightness_change
(
int
value
)
{
m_brightness
=
value
;
process
();
}
void
Dialog_ImgProc_Adjust
::
on_contrast_change
(
int
value
)
{
m_contrast
=
value
;
process
();
}
void
Dialog_ImgProc_Adjust
::
on_gamma_change
(
double
value
)
{
m_gamma
=
value
;
process
();
}
void
Dialog_ImgProc_Adjust
::
on_cbtn_preview_toggled
(
bool
checked
)
{
reinterpret_cast
<
QVBoxLayout
*>
(
this
->
layout
())
->
setStretch
(
1
,
checked
?
1
:
0
);
ui
->
gbox_before
->
setVisible
(
checked
);
ui
->
gbox_after
->
setVisible
(
checked
);
}
void
Dialog_ImgProc_Adjust
::
on_cbtn_applyImg_toggled
(
bool
checked
)
{
HGImage
img
=
nullptr
;
if
(
checked
)
ui
->
view_after
->
getImage
(
&
img
);
else
ui
->
view_before
->
getImage
(
&
img
);
assert
(
nullptr
!=
img
);
emit
applyToImage
(
img
);
}
void
Dialog_ImgProc_Adjust
::
on_buttonBox_clicked
(
QAbstractButton
*
button
)
{
if
(
ui
->
buttonBox
->
standardButton
(
button
)
==
QDialogButtonBox
::
RestoreDefaults
)
{
m_base_widget
->
setDefault
();
m_brightness
=
0
;
m_contrast
=
0
;
m_gamma
=
1.0
;
process
();
}
}
void
Dialog_ImgProc_Adjust
::
process
()
{
HGImage
img
=
nullptr
;
ui
->
view_before
->
getImage
(
&
img
);
assert
(
nullptr
!=
img
);
HGImageInfo
imgInfo
;
HGBase_GetImageInfo
(
img
,
&
imgInfo
);
HGImage
destImg
=
nullptr
;
HGBase_CreateImage
(
imgInfo
.
width
,
imgInfo
.
height
,
imgInfo
.
type
,
imgInfo
.
origin
,
&
destImg
);
if
(
nullptr
!=
destImg
)
{
HGImgProc_ImageAdjustColors
(
img
,
destImg
,
m_brightness
,
m_contrast
,
(
HGFloat
)
m_gamma
);
ui
->
view_after
->
addImage
(
destImg
);
HGBase_DestroyImage
(
destImg
);
if
(
ui
->
cbtn_applyImg
->
isChecked
())
{
HGImage
emitImg
=
nullptr
;
ui
->
view_after
->
getImage
(
&
emitImg
);
assert
(
nullptr
!=
emitImg
);
emit
applyToImage
(
emitImg
);
}
}
}
app/Scanner/Scanner/dialog_imgproc_adjust.h
0 → 100644
View file @
735ab83d
#ifndef DIALOG_IMGPROC_ADJUST_H
#define DIALOG_IMGPROC_ADJUST_H
#include <QDialog>
#include <QAbstractButton>
#include "widget_imgproc_base.h"
#include "base/HGImage.h"
namespace
Ui
{
class
Dialog_ImgProc_Adjust
;
}
class
Dialog_ImgProc_Adjust
:
public
QDialog
{
Q_OBJECT
public:
explicit
Dialog_ImgProc_Adjust
(
HGImage
img
,
QWidget
*
parent
=
nullptr
);
~
Dialog_ImgProc_Adjust
();
HGImage
getBeforeImage
();
HGImage
getAfterImage
();
signals:
void
applyToImage
(
HGImage
img
);
private
slots
:
void
on_brightness_change
(
int
value
);
void
on_contrast_change
(
int
value
);
void
on_gamma_change
(
double
value
);
void
on_cbtn_preview_toggled
(
bool
checked
);
void
on_cbtn_applyImg_toggled
(
bool
checked
);
void
on_buttonBox_clicked
(
QAbstractButton
*
button
);
private:
void
process
();
private:
Ui
::
Dialog_ImgProc_Adjust
*
ui
;
Widget_Imgproc_Base
*
m_base_widget
;
int
m_brightness
;
int
m_contrast
;
double
m_gamma
;
};
#endif // DIALOG_IMGPROC_ADJUST_H
app/Scanner/Scanner/dialog_imgproc_adjust.ui
0 → 100644
View file @
735ab83d
<?xml version="1.0" encoding="UTF-8"?>
<ui
version=
"4.0"
>
<class>
Dialog_ImgProc_Adjust
</class>
<widget
class=
"QDialog"
name=
"Dialog_ImgProc_Adjust"
>
<property
name=
"geometry"
>
<rect>
<x>
0
</x>
<y>
0
</y>
<width>
463
</width>
<height>
543
</height>
</rect>
</property>
<property
name=
"windowTitle"
>
<string>
Adjust
</string>
</property>
<layout
class=
"QVBoxLayout"
name=
"verticalLayout"
stretch=
"0,0,0,0,0"
>
<item>
<layout
class=
"QHBoxLayout"
name=
"horizontalLayout_4"
stretch=
"0,1"
>
<item>
<widget
class=
"QCheckBox"
name=
"cbtn_preview"
>
<property
name=
"text"
>
<string>
Show preview
</string>
</property>
</widget>
</item>
<item>
<widget
class=
"Line"
name=
"line"
>
<property
name=
"orientation"
>
<enum>
Qt::Horizontal
</enum>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout
class=
"QHBoxLayout"
name=
"horizontalLayout_3"
>
<item>
<widget
class=
"QGroupBox"
name=
"gbox_before"
>
<property
name=
"title"
>
<string>
Before
</string>
</property>
<layout
class=
"QHBoxLayout"
name=
"horizontalLayout"
>
<item>
<widget
class=
"HGImgView"
name=
"view_before"
native=
"true"
>
<property
name=
"minimumSize"
>
<size>
<width>
150
</width>
<height>
100
</height>
</size>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget
class=
"QGroupBox"
name=
"gbox_after"
>
<property
name=
"title"
>
<string>
After
</string>
</property>
<layout
class=
"QHBoxLayout"
name=
"horizontalLayout_2"
>
<item>
<widget
class=
"HGImgView"
name=
"view_after"
native=
"true"
>
<property
name=
"minimumSize"
>
<size>
<width>
150
</width>
<height>
100
</height>
</size>
</property>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</item>
<item>
<layout
class=
"QHBoxLayout"
name=
"horizontalLayout_8"
>
<item>
<widget
class=
"QCheckBox"
name=
"cbtn_applyImg"
>
<property
name=
"text"
>
<string>
Apply to image
</string>
</property>
</widget>
</item>
<item>
<spacer
name=
"horizontalSpacer_2"
>
<property
name=
"orientation"
>
<enum>
Qt::Horizontal
</enum>
</property>
<property
name=
"sizeHint"
stdset=
"0"
>
<size>
<width>
40
</width>
<height>
20
</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item>
<spacer
name=
"verticalSpacer"
>
<property
name=
"orientation"
>
<enum>
Qt::Vertical
</enum>
</property>
<property
name=
"sizeHint"
stdset=
"0"
>
<size>
<width>
20
</width>
<height>
40
</height>
</size>
</property>
</spacer>
</item>
<item>
<widget
class=
"QDialogButtonBox"
name=
"buttonBox"
>
<property
name=
"orientation"
>
<enum>
Qt::Horizontal
</enum>
</property>
<property
name=
"standardButtons"
>
<set>
QDialogButtonBox::Cancel|QDialogButtonBox::Ok|QDialogButtonBox::RestoreDefaults
</set>
</property>
</widget>
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>
HGImgView
</class>
<extends>
QWidget
</extends>
<header
location=
"global"
>
HGImgView.h
</header>
<container>
1
</container>
</customwidget>
</customwidgets>
<resources/>
<connections>
<connection>
<sender>
buttonBox
</sender>
<signal>
accepted()
</signal>
<receiver>
Dialog_ImgProc_Adjust
</receiver>
<slot>
accept()
</slot>
<hints>
<hint
type=
"sourcelabel"
>
<x>
248
</x>
<y>
254
</y>
</hint>
<hint
type=
"destinationlabel"
>
<x>
157
</x>
<y>
274
</y>
</hint>
</hints>
</connection>
<connection>
<sender>
buttonBox
</sender>
<signal>
rejected()
</signal>
<receiver>
Dialog_ImgProc_Adjust
</receiver>
<slot>
reject()
</slot>
<hints>
<hint
type=
"sourcelabel"
>
<x>
316
</x>
<y>
260
</y>
</hint>
<hint
type=
"destinationlabel"
>
<x>
286
</x>
<y>
274
</y>
</hint>
</hints>
</connection>
</connections>
</ui>
app/Scanner/Scanner/dialog_multirotate.cpp
0 → 100644
View file @
735ab83d
#include "dialog_multirotate.h"
#include "ui_dialog_multirotate.h"
#include <QButtonGroup>
Dialog_MultiRotate
::
Dialog_MultiRotate
(
QWidget
*
parent
)
:
QDialog
(
parent
),
ui
(
new
Ui
::
Dialog_MultiRotate
),
m_group_rotation
(
new
QButtonGroup
),
m_group_page
(
new
QButtonGroup
),
m_rotate_type
(
0
),
m_rotate_page_type
(
0
)
{
ui
->
setupUi
(
this
);
m_group_rotation
->
addButton
(
ui
->
rbtn_clockwise
,
0
);
m_group_rotation
->
addButton
(
ui
->
rbtn_180degree
,
1
);
m_group_rotation
->
addButton
(
ui
->
rbtn_anticlockwise
,
2
);
m_group_page
->
addButton
(
ui
->
rbtn_currPage
,
0
);
m_group_page
->
addButton
(
ui
->
rbtn_selectedPage
,
1
);
m_group_page
->
addButton
(
ui
->
rbtn_evenPage
,
2
);
m_group_page
->
addButton
(
ui
->
rbtn_oddPage
,
3
);
m_group_page
->
addButton
(
ui
->
rbtn_allPage
,
4
);
connect
(
m_group_rotation
,
SIGNAL
(
buttonClicked
(
int
)),
this
,
SLOT
(
on_rotation_rbtn_clicked
(
int
)));
connect
(
m_group_page
,
SIGNAL
(
buttonClicked
(
int
)),
this
,
SLOT
(
on_page_rbtn_clicked
(
int
)));
}
Dialog_MultiRotate
::~
Dialog_MultiRotate
()
{
delete
m_group_page
;
delete
m_group_rotation
;
delete
ui
;
}
void
Dialog_MultiRotate
::
on_rotation_rbtn_clicked
(
int
id
)
{
m_rotate_type
=
id
;
}
void
Dialog_MultiRotate
::
on_page_rbtn_clicked
(
int
id
)
{
m_rotate_page_type
=
id
;
}
app/Scanner/Scanner/dialog_multirotate.h
0 → 100644
View file @
735ab83d
#ifndef DIALOG_MULTIROTATE_H
#define DIALOG_MULTIROTATE_H
#include <QDialog>
class
QButtonGroup
;
namespace
Ui
{
class
Dialog_MultiRotate
;
}
class
Dialog_MultiRotate
:
public
QDialog
{
Q_OBJECT
public:
explicit
Dialog_MultiRotate
(
QWidget
*
parent
=
nullptr
);
~
Dialog_MultiRotate
();
int
getRotateType
()
{
return
m_rotate_type
;
}
int
getRotatePageType
()
{
return
m_rotate_page_type
;
}
private
slots
:
void
on_rotation_rbtn_clicked
(
int
id
);
void
on_page_rbtn_clicked
(
int
id
);
private:
Ui
::
Dialog_MultiRotate
*
ui
;
QButtonGroup
*
m_group_rotation
,
*
m_group_page
;
int
m_rotate_type
;
int
m_rotate_page_type
;
};
#endif // DIALOG_MULTIROTATE_H
app/Scanner/Scanner/dialog_multirotate.ui
0 → 100644
View file @
735ab83d
<?xml version="1.0" encoding="UTF-8"?>
<ui
version=
"4.0"
>
<class>
Dialog_MultiRotate
</class>
<widget
class=
"QDialog"
name=
"Dialog_MultiRotate"
>
<property
name=
"geometry"
>
<rect>
<x>
0
</x>
<y>
0
</y>
<width>
350
</width>
<height>
250
</height>
</rect>
</property>
<property
name=
"minimumSize"
>
<size>
<width>
350
</width>
<height>
250
</height>
</size>
</property>
<property
name=
"maximumSize"
>
<size>
<width>
350
</width>
<height>
250
</height>
</size>
</property>
<property
name=
"windowTitle"
>
<string>
Multiple rotation
</string>
</property>
<layout
class=
"QVBoxLayout"
name=
"verticalLayout_3"
>
<item>
<layout
class=
"QHBoxLayout"
name=
"horizontalLayout"
>
<item>
<widget
class=
"QGroupBox"
name=
"gbox_rotation"
>
<property
name=
"title"
>
<string>
Rotation
</string>
</property>
<layout
class=
"QVBoxLayout"
name=
"verticalLayout"
>
<item>
<widget
class=
"QRadioButton"
name=
"rbtn_clockwise"
>
<property
name=
"text"
>
<string>
90°
</string>
</property>
<property
name=
"checked"
>
<bool>
true
</bool>
</property>
</widget>
</item>
<item>
<widget
class=
"QRadioButton"
name=
"rbtn_180degree"
>
<property
name=
"text"
>
<string>
180°
</string>
</property>
</widget>
</item>
<item>
<widget
class=
"QRadioButton"
name=
"rbtn_anticlockwise"
>
<property
name=
"text"
>
<string>
-90°
</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget
class=
"QGroupBox"
name=
"gbox_pages"
>
<property
name=
"title"
>
<string>
Pages
</string>
</property>
<layout
class=
"QVBoxLayout"
name=
"verticalLayout_2"
>
<item>
<widget
class=
"QRadioButton"
name=
"rbtn_currPage"
>
<property
name=
"text"
>
<string>
Current page
</string>
</property>
<property
name=
"checked"
>
<bool>
true
</bool>
</property>
</widget>
</item>
<item>
<widget
class=
"QRadioButton"
name=
"rbtn_selectedPage"
>
<property
name=
"text"
>
<string>
Selected pages
</string>
</property>
</widget>
</item>
<item>
<widget
class=
"QRadioButton"
name=
"rbtn_evenPage"
>
<property
name=
"text"
>
<string>
All odd pages
</string>
</property>
</widget>
</item>
<item>
<widget
class=
"QRadioButton"
name=
"rbtn_oddPage"
>
<property
name=
"text"
>
<string>
All even pages
</string>
</property>
</widget>
</item>
<item>
<widget
class=
"QRadioButton"
name=
"rbtn_allPage"
>
<property
name=
"text"
>
<string>
All pages
</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget
class=
"QDialogButtonBox"
name=
"buttonBox"
>
<property
name=
"orientation"
>
<enum>
Qt::Vertical
</enum>
</property>
<property
name=
"standardButtons"
>
<set>
QDialogButtonBox::Cancel|QDialogButtonBox::Ok
</set>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget
class=
"QLabel"
name=
"label"
>
<property
name=
"text"
>
<string>
Attentions:
This operation will NOT rotate the files that may contain multiple pages, such as .pdf, .tif, etc.
</string>
</property>
<property
name=
"wordWrap"
>
<bool>
true
</bool>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections>
<connection>
<sender>
buttonBox
</sender>
<signal>
accepted()
</signal>
<receiver>
Dialog_MultiRotate
</receiver>
<slot>
accept()
</slot>
<hints>
<hint
type=
"sourcelabel"
>
<x>
248
</x>
<y>
254
</y>
</hint>
<hint
type=
"destinationlabel"
>
<x>
157
</x>
<y>
274
</y>
</hint>
</hints>
</connection>
<connection>
<sender>
buttonBox
</sender>
<signal>
rejected()
</signal>
<receiver>
Dialog_MultiRotate
</receiver>
<slot>
reject()
</slot>
<hints>
<hint
type=
"sourcelabel"
>
<x>
316
</x>
<y>
260
</y>
</hint>
<hint
type=
"destinationlabel"
>
<x>
286
</x>
<y>
274
</y>
</hint>
</hints>
</connection>
</connections>
</ui>
app/Scanner/Scanner/dialog_multirotateimagefile.cpp
0 → 100644
View file @
735ab83d
#include "dialog_multirotateimagefile.h"
#include "ui_dialog_multirotateimagefile.h"
#include "imgfmt/HGImgFmt.h"
#include "HGUIGlobal.h"
Dialog_MultiRotateImageFile
::
Dialog_MultiRotateImageFile
(
const
QStringList
&
fileList
,
int
rotateType
,
QWidget
*
parent
)
:
QDialog
(
parent
),
ui
(
new
Ui
::
Dialog_MultiRotateImageFile
),
m_fileList
(
fileList
),
m_rotateType
(
rotateType
)
{
ui
->
setupUi
(
this
);
ui
->
progressBar
->
setMinimum
(
0
);
ui
->
progressBar
->
setMaximum
(
fileList
.
size
());
ui
->
progressBar
->
setValue
(
0
);
connect
(
this
,
SIGNAL
(
updateProgress
(
int
)),
this
,
SLOT
(
on_updateProgress
(
int
)),
Qt
::
QueuedConnection
);
connect
(
this
,
SIGNAL
(
updateImageFile
(
QString
)),
this
,
SLOT
(
on_updateImageFile
(
QString
)),
Qt
::
QueuedConnection
);
connect
(
this
,
SIGNAL
(
finish
()),
this
,
SLOT
(
on_finish
()),
Qt
::
QueuedConnection
);
m_stopThread
=
false
;
HGBase_OpenThread
(
ThreadFunc
,
this
,
&
m_thread
);
}
Dialog_MultiRotateImageFile
::~
Dialog_MultiRotateImageFile
()
{
if
(
nullptr
!=
m_thread
)
{
HGBase_CloseThread
(
m_thread
);
m_thread
=
nullptr
;
}
delete
ui
;
}
void
Dialog_MultiRotateImageFile
::
ThreadFunc
(
HGThread
thread
,
HGPointer
param
)
{
(
void
)
thread
;
Dialog_MultiRotateImageFile
*
p
=
(
Dialog_MultiRotateImageFile
*
)
param
;
for
(
int
i
=
0
;
i
<
(
int
)
p
->
m_fileList
.
count
();
++
i
)
{
if
(
p
->
m_stopThread
)
{
break
;
}
emit
p
->
updateProgress
(
i
);
HGImgFmtReader
imgFmtReader
=
nullptr
;
HGImgFmt_OpenImageReader
(
getStdString
(
p
->
m_fileList
[
i
]).
c_str
(),
0
,
&
imgFmtReader
);
if
(
nullptr
!=
imgFmtReader
)
{
HGUInt
pageCount
=
0
;
HGImgFmt_GetImagePageCount
(
imgFmtReader
,
&
pageCount
);
if
(
1
==
pageCount
)
{
HGImage
img
=
nullptr
;
HGImgFmt_LoadImageFromReader
(
imgFmtReader
,
0
,
nullptr
,
HGBASE_IMGTYPE_RGB
,
HGBASE_IMGORIGIN_TOP
,
&
img
);
if
(
nullptr
!=
img
)
{
HGImageInfo
imgInfo
;
HGBase_GetImageInfo
(
img
,
&
imgInfo
);
if
(
0
==
p
->
m_rotateType
)
{
HGImage
img2
=
nullptr
;
HGBase_CreateImage
(
imgInfo
.
height
,
imgInfo
.
width
,
imgInfo
.
type
,
imgInfo
.
origin
,
&
img2
);
HGBase_ImageRotateLeft
(
img
,
img2
);
HGBase_DestroyImage
(
img
);
img
=
img2
;
}
else
if
(
1
==
p
->
m_rotateType
)
{
HGBase_ImageRotate180
(
img
,
img
);
}
else
if
(
2
==
p
->
m_rotateType
)
{
HGImage
img2
=
nullptr
;
HGBase_CreateImage
(
imgInfo
.
height
,
imgInfo
.
width
,
imgInfo
.
type
,
imgInfo
.
origin
,
&
img2
);
HGBase_ImageRotateRight
(
img
,
img2
);
HGBase_DestroyImage
(
img
);
img
=
img2
;
}
if
(
HGBASE_ERR_OK
==
HGImgFmt_SaveImage
(
img
,
0
,
nullptr
,
0
,
getStdString
(
p
->
m_fileList
[
i
]).
c_str
()))
{
emit
p
->
updateImageFile
(
p
->
m_fileList
[
i
]);
}
HGBase_DestroyImage
(
img
);
}
}
HGImgFmt_CloseImageReader
(
imgFmtReader
);
}
}
emit
p
->
finish
();
}
void
Dialog_MultiRotateImageFile
::
on_updateProgress
(
int
value
)
{
ui
->
progressBar
->
setValue
(
value
);
}
void
Dialog_MultiRotateImageFile
::
on_updateImageFile
(
QString
fileName
)
{
emit
refreshImageFile
(
fileName
);
}
void
Dialog_MultiRotateImageFile
::
on_finish
()
{
close
();
}
void
Dialog_MultiRotateImageFile
::
on_pushButton_clicked
()
{
m_stopThread
=
true
;
HGBase_CloseThread
(
m_thread
);
m_thread
=
nullptr
;
}
void
Dialog_MultiRotateImageFile
::
closeEvent
(
QCloseEvent
*
e
)
{
(
void
)
e
;
m_stopThread
=
true
;
HGBase_CloseThread
(
m_thread
);
m_thread
=
nullptr
;
}
app/Scanner/Scanner/dialog_multirotateimagefile.h
0 → 100644
View file @
735ab83d
#ifndef DIALOG_MULTIROTATEIMAGEFILE_H
#define DIALOG_MULTIROTATEIMAGEFILE_H
#include <QDialog>
#include "base/HGThread.h"
namespace
Ui
{
class
Dialog_MultiRotateImageFile
;
}
class
Dialog_MultiRotateImageFile
:
public
QDialog
{
Q_OBJECT
public:
explicit
Dialog_MultiRotateImageFile
(
const
QStringList
&
fileList
,
int
rotateType
,
QWidget
*
parent
=
nullptr
);
~
Dialog_MultiRotateImageFile
();
signals:
void
refreshImageFile
(
const
QString
&
fileName
);
private:
static
void
ThreadFunc
(
HGThread
thread
,
HGPointer
param
);
signals:
void
updateProgress
(
int
value
);
void
updateImageFile
(
QString
fileName
);
void
finish
();
private
slots
:
void
on_updateProgress
(
int
value
);
void
on_updateImageFile
(
QString
fileName
);
void
on_finish
();
void
on_pushButton_clicked
();
protected:
virtual
void
closeEvent
(
QCloseEvent
*
e
);
private:
Ui
::
Dialog_MultiRotateImageFile
*
ui
;
QStringList
m_fileList
;
int
m_rotateType
;
bool
m_stopThread
;
HGThread
m_thread
;
};
#endif // DIALOG_MULTIROTATEIMAGEFILE_H
app/Scanner/Scanner/dialog_multirotateimagefile.ui
0 → 100644
View file @
735ab83d
<?xml version="1.0" encoding="UTF-8"?>
<ui
version=
"4.0"
>
<class>
Dialog_MultiRotateImageFile
</class>
<widget
class=
"QDialog"
name=
"Dialog_MultiRotateImageFile"
>
<property
name=
"geometry"
>
<rect>
<x>
0
</x>
<y>
0
</y>
<width>
400
</width>
<height>
300
</height>
</rect>
</property>
<property
name=
"windowTitle"
>
<string>
Dialog
</string>
</property>
<layout
class=
"QVBoxLayout"
name=
"verticalLayout"
>
<item>
<spacer
name=
"horizontalSpacer"
>
<property
name=
"orientation"
>
<enum>
Qt::Horizontal
</enum>
</property>
<property
name=
"sizeHint"
stdset=
"0"
>
<size>
<width>
40
</width>
<height>
20
</height>
</size>
</property>
</spacer>
</item>
<item>
<widget
class=
"QProgressBar"
name=
"progressBar"
>
<property
name=
"value"
>
<number>
0
</number>
</property>
</widget>
</item>
<item>
<layout
class=
"QHBoxLayout"
name=
"horizontalLayout"
>
<item>
<spacer
name=
"horizontalSpacer_2"
>
<property
name=
"orientation"
>
<enum>
Qt::Horizontal
</enum>
</property>
<property
name=
"sizeHint"
stdset=
"0"
>
<size>
<width>
40
</width>
<height>
20
</height>
</size>
</property>
</spacer>
</item>
<item>
<widget
class=
"QPushButton"
name=
"pushButton"
>
<property
name=
"text"
>
<string>
stop
</string>
</property>
</widget>
</item>
<item>
<spacer
name=
"horizontalSpacer_3"
>
<property
name=
"orientation"
>
<enum>
Qt::Horizontal
</enum>
</property>
<property
name=
"sizeHint"
stdset=
"0"
>
<size>
<width>
40
</width>
<height>
20
</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>
app/Scanner/Scanner/mainwindow.cpp
View file @
735ab83d
...
...
@@ -10,6 +10,9 @@
#include "dialog_exportimagefile.h"
#include "dialog_imageinfo.h"
#include "dialog_fullscreen.h"
#include "dialog_imgproc_adjust.h"
#include "dialog_multirotate.h"
#include "dialog_multirotateimagefile.h"
#include "imgfmt/HGPdf.h"
#include "imgfmt/HGImgFmt.h"
#include "HGUIGlobal.h"
...
...
@@ -422,6 +425,16 @@ void MainWindow::on_act_thumbGrid_triggered(bool checked)
m_thumb
->
setType
(
HGImgThumb
::
ThumbType_Vert
);
}
void
MainWindow
::
on_dialog_adjust_applyToImage
(
HGImage
img
)
{
m_view
->
addImage
(
img
);
}
void
MainWindow
::
on_dialog_multirotate_refreshImgFile
(
const
QString
&
fileName
)
{
m_thumb
->
refreshItem
(
fileName
);
}
void
MainWindow
::
on_act_thumbnailBar_triggered
(
bool
checked
)
{
ui
->
dockWidget
->
setVisible
(
checked
);
...
...
@@ -571,6 +584,9 @@ void MainWindow::updateActionStatus()
ui
->
act_90Right
->
setEnabled
(
nullptr
!=
img
);
ui
->
act_180
->
setEnabled
(
nullptr
!=
img
);
ui
->
menu_Auto_Image_Size
->
setEnabled
(
nullptr
!=
img
);
ui
->
act_adjust
->
setEnabled
(
nullptr
!=
img
);
ui
->
act_multiRotate
->
setEnabled
(
0
!=
count
);
ui
->
menu_Rotate
->
setEnabled
(
0
!=
count
||
nullptr
!=
img
);
}
void
MainWindow
::
on_act_openPageNum_triggered
()
...
...
@@ -692,7 +708,25 @@ void MainWindow::on_act_lastPage_triggered()
void
MainWindow
::
on_act_adjust_triggered
()
{
HGImage
img
=
nullptr
;
m_view
->
getImage
(
&
img
);
if
(
nullptr
==
img
)
{
return
;
}
Dialog_ImgProc_Adjust
dlg
(
img
,
this
);
connect
(
&
dlg
,
SIGNAL
(
applyToImage
(
HGImage
)),
this
,
SLOT
(
on_dialog_adjust_applyToImage
(
HGImage
)));
if
(
dlg
.
exec
())
{
m_view
->
addImage
(
dlg
.
getAfterImage
());
m_modify
=
true
;
}
else
{
m_view
->
addImage
(
dlg
.
getBeforeImage
());
}
disconnect
(
&
dlg
,
SIGNAL
(
applyToImage
(
HGImage
)),
this
,
SLOT
(
on_dialog_adjust_applyToImage
(
HGImage
)));
}
void
MainWindow
::
on_act_open_triggered
()
...
...
@@ -1016,3 +1050,98 @@ void MainWindow::closeEvent(QCloseEvent *e)
(
void
)
e
;
on_act_closeAll_triggered
();
}
void
MainWindow
::
on_act_multiRotate_triggered
()
{
int
count
=
0
;
m_thumb
->
getItemCount
(
&
count
);
if
(
0
==
count
)
{
return
;
}
Dialog_MultiRotate
dlg
(
this
);
if
(
dlg
.
exec
())
{
int
rotateType
=
dlg
.
getRotateType
();
int
rotatePageType
=
dlg
.
getRotatePageType
();
QStringList
fileList
;
switch
(
rotatePageType
)
{
case
0
:
{
if
(
-
1
!=
m_currIndex
)
{
assert
(
!
m_currFilePath
.
isEmpty
());
fileList
.
append
(
m_currFilePath
);
}
}
break
;
case
1
:
{
for
(
int
i
=
0
;
i
<
count
;
++
i
)
{
bool
selected
=
false
;
m_thumb
->
itemIsSelect
(
i
,
&
selected
);
if
(
selected
)
{
QString
fileName
;
m_thumb
->
getItemFileName
(
i
,
fileName
);
fileList
.
append
(
fileName
);
}
}
}
break
;
case
2
:
{
for
(
int
i
=
0
;
i
<
count
;
++
i
)
{
if
((
i
+
1
)
%
2
!=
0
)
{
QString
fileName
;
m_thumb
->
getItemFileName
(
i
,
fileName
);
fileList
.
append
(
fileName
);
}
}
}
break
;
case
3
:
{
for
(
int
i
=
0
;
i
<
count
;
++
i
)
{
if
((
i
+
1
)
%
2
==
0
)
{
QString
fileName
;
m_thumb
->
getItemFileName
(
i
,
fileName
);
fileList
.
append
(
fileName
);
}
}
}
break
;
case
4
:
{
for
(
int
i
=
0
;
i
<
count
;
++
i
)
{
QString
fileName
;
m_thumb
->
getItemFileName
(
i
,
fileName
);
fileList
.
append
(
fileName
);
}
}
break
;
}
if
(
!
fileList
.
isEmpty
())
{
Dialog_MultiRotateImageFile
processDlg
(
fileList
,
rotateType
,
this
);
connect
(
&
processDlg
,
SIGNAL
(
refreshImageFile
(
const
QString
&
)),
this
,
SLOT
(
on_dialog_multirotate_refreshImgFile
(
const
QString
&
)));
processDlg
.
exec
();
disconnect
(
&
processDlg
,
SIGNAL
(
refreshImageFile
(
const
QString
&
)),
this
,
SLOT
(
on_dialog_multirotate_refreshImgFile
(
const
QString
&
)));
}
}
}
void
MainWindow
::
on_act_autoCrop_triggered
()
{
}
app/Scanner/Scanner/mainwindow.h
View file @
735ab83d
...
...
@@ -52,6 +52,8 @@ private slots:
void
on_thumbContextMenu
(
int
index
);
void
on_viewerDrop
(
const
QString
&
fileName
);
void
on_act_thumbGrid_triggered
(
bool
checked
);
void
on_dialog_adjust_applyToImage
(
HGImage
img
);
void
on_dialog_multirotate_refreshImgFile
(
const
QString
&
fileName
);
void
on_act_thumbnailBar_triggered
(
bool
checked
);
...
...
@@ -93,6 +95,10 @@ private slots:
void
on_act_imageInfo_triggered
();
void
on_act_multiRotate_triggered
();
void
on_act_autoCrop_triggered
();
protected:
virtual
void
closeEvent
(
QCloseEvent
*
e
);
...
...
app/Scanner/Scanner/mainwindow.ui
View file @
735ab83d
...
...
@@ -115,7 +115,7 @@
<property
name=
"title"
>
<string>
menu_image
</string>
</property>
<widget
class=
"QMenu"
name=
"menuRotate"
>
<widget
class=
"QMenu"
name=
"menu
_
Rotate"
>
<property
name=
"title"
>
<string>
menuRotate
</string>
</property>
...
...
@@ -125,7 +125,7 @@
<addaction
name=
"act_multiRotate"
/>
</widget>
<addaction
name=
"act_adjust"
/>
<addaction
name=
"menuRotate"
/>
<addaction
name=
"menu
_
Rotate"
/>
<addaction
name=
"act_autoCrop"
/>
</widget>
<widget
class=
"QMenu"
name=
"menu_user"
>
...
...
app/Scanner/Scanner/widget_imgproc_base.cpp
0 → 100644
View file @
735ab83d
#include "widget_imgproc_base.h"
#include "ui_widget_imgproc_base.h"
Widget_Imgproc_Base
::
Widget_Imgproc_Base
(
QWidget
*
parent
)
:
QWidget
(
parent
),
ui
(
new
Ui
::
Widget_Imgproc_Base
)
{
ui
->
setupUi
(
this
);
connect
(
ui
->
slider_brightness
,
SIGNAL
(
valueChanged
(
int
)),
ui
->
spin_brightness
,
SLOT
(
setValue
(
int
)));
connect
(
ui
->
slider_contrast
,
SIGNAL
(
valueChanged
(
int
)),
ui
->
spin_contrast
,
SLOT
(
setValue
(
int
)));
}
Widget_Imgproc_Base
::~
Widget_Imgproc_Base
()
{
qDebug
(
"~Widget_Imgproc_Base"
);
delete
ui
;
}
void
Widget_Imgproc_Base
::
setDefault
()
{
ui
->
spin_brightness
->
setValue
(
0
);
ui
->
spin_contrast
->
setValue
(
0
);
ui
->
dspin_gamma
->
setValue
(
1.0
);
}
void
Widget_Imgproc_Base
::
on_spin_brightness_valueChanged
(
int
arg1
)
{
ui
->
slider_brightness
->
setValue
(
arg1
);
emit
brightness_change
(
arg1
);
}
void
Widget_Imgproc_Base
::
on_spin_contrast_valueChanged
(
int
arg1
)
{
ui
->
slider_contrast
->
setValue
(
arg1
);
emit
contrast_change
(
arg1
);
}
void
Widget_Imgproc_Base
::
on_slider_gamma_valueChanged
(
int
value
)
{
ui
->
dspin_gamma
->
setValue
(
static_cast
<
double
>
(
value
/
100.0
));
}
void
Widget_Imgproc_Base
::
on_dspin_gamma_valueChanged
(
double
arg1
)
{
ui
->
slider_gamma
->
setValue
(
static_cast
<
int
>
(
arg1
*
100
));
emit
gamma_change
(
arg1
);
}
app/Scanner/Scanner/widget_imgproc_base.h
0 → 100644
View file @
735ab83d
#ifndef WIDGET_IMGPROC_BASE_H
#define WIDGET_IMGPROC_BASE_H
#include <QWidget>
namespace
Ui
{
class
Widget_Imgproc_Base
;
}
class
Widget_Imgproc_Base
:
public
QWidget
{
Q_OBJECT
public:
explicit
Widget_Imgproc_Base
(
QWidget
*
parent
=
nullptr
);
~
Widget_Imgproc_Base
();
void
setDefault
();
signals:
void
brightness_change
(
int
);
void
contrast_change
(
int
);
void
gamma_change
(
double
);
private
slots
:
void
on_spin_brightness_valueChanged
(
int
arg1
);
void
on_spin_contrast_valueChanged
(
int
arg1
);
void
on_slider_gamma_valueChanged
(
int
position
);
void
on_dspin_gamma_valueChanged
(
double
arg1
);
private:
Ui
::
Widget_Imgproc_Base
*
ui
;
};
#endif // WIDGET_IMGPROC_BASE_H
app/Scanner/Scanner/widget_imgproc_base.ui
0 → 100644
View file @
735ab83d
<?xml version="1.0" encoding="UTF-8"?>
<ui
version=
"4.0"
>
<class>
Widget_Imgproc_Base
</class>
<widget
class=
"QWidget"
name=
"Widget_Imgproc_Base"
>
<property
name=
"geometry"
>
<rect>
<x>
0
</x>
<y>
0
</y>
<width>
489
</width>
<height>
284
</height>
</rect>
</property>
<property
name=
"windowTitle"
>
<string>
Form
</string>
</property>
<layout
class=
"QVBoxLayout"
name=
"verticalLayout"
>
<item>
<widget
class=
"QGroupBox"
name=
"gbox_brightness"
>
<property
name=
"title"
>
<string>
Brightness
</string>
</property>
<layout
class=
"QHBoxLayout"
name=
"horizontalLayout_5"
stretch=
"0,0"
>
<item>
<widget
class=
"QSlider"
name=
"slider_brightness"
>
<property
name=
"minimum"
>
<number>
-255
</number>
</property>
<property
name=
"maximum"
>
<number>
255
</number>
</property>
<property
name=
"value"
>
<number>
0
</number>
</property>
<property
name=
"orientation"
>
<enum>
Qt::Horizontal
</enum>
</property>
<property
name=
"tickPosition"
>
<enum>
QSlider::TicksAbove
</enum>
</property>
<property
name=
"tickInterval"
>
<number>
32
</number>
</property>
</widget>
</item>
<item>
<widget
class=
"QSpinBox"
name=
"spin_brightness"
>
<property
name=
"minimumSize"
>
<size>
<width>
150
</width>
<height>
0
</height>
</size>
</property>
<property
name=
"minimum"
>
<number>
-255
</number>
</property>
<property
name=
"maximum"
>
<number>
255
</number>
</property>
<property
name=
"value"
>
<number>
0
</number>
</property>
<property
name=
"displayIntegerBase"
>
<number>
10
</number>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget
class=
"QGroupBox"
name=
"gbox_contrast"
>
<property
name=
"title"
>
<string>
Contrast
</string>
</property>
<layout
class=
"QHBoxLayout"
name=
"horizontalLayout_6"
>
<item>
<widget
class=
"QSlider"
name=
"slider_contrast"
>
<property
name=
"minimum"
>
<number>
-127
</number>
</property>
<property
name=
"maximum"
>
<number>
127
</number>
</property>
<property
name=
"value"
>
<number>
0
</number>
</property>
<property
name=
"orientation"
>
<enum>
Qt::Horizontal
</enum>
</property>
<property
name=
"invertedAppearance"
>
<bool>
false
</bool>
</property>
<property
name=
"invertedControls"
>
<bool>
false
</bool>
</property>
<property
name=
"tickPosition"
>
<enum>
QSlider::TicksAbove
</enum>
</property>
<property
name=
"tickInterval"
>
<number>
16
</number>
</property>
</widget>
</item>
<item>
<widget
class=
"QSpinBox"
name=
"spin_contrast"
>
<property
name=
"minimumSize"
>
<size>
<width>
150
</width>
<height>
0
</height>
</size>
</property>
<property
name=
"minimum"
>
<number>
-127
</number>
</property>
<property
name=
"maximum"
>
<number>
127
</number>
</property>
<property
name=
"value"
>
<number>
0
</number>
</property>
<property
name=
"displayIntegerBase"
>
<number>
10
</number>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget
class=
"QGroupBox"
name=
"gbox_gamma"
>
<property
name=
"title"
>
<string>
Gamma correction
</string>
</property>
<layout
class=
"QHBoxLayout"
name=
"horizontalLayout_7"
>
<item>
<widget
class=
"QSlider"
name=
"slider_gamma"
>
<property
name=
"minimum"
>
<number>
1
</number>
</property>
<property
name=
"maximum"
>
<number>
500
</number>
</property>
<property
name=
"value"
>
<number>
100
</number>
</property>
<property
name=
"orientation"
>
<enum>
Qt::Horizontal
</enum>
</property>
<property
name=
"tickPosition"
>
<enum>
QSlider::TicksAbove
</enum>
</property>
<property
name=
"tickInterval"
>
<number>
25
</number>
</property>
</widget>
</item>
<item>
<widget
class=
"QDoubleSpinBox"
name=
"dspin_gamma"
>
<property
name=
"minimumSize"
>
<size>
<width>
150
</width>
<height>
0
</height>
</size>
</property>
<property
name=
"minimum"
>
<double>
0.010000000000000
</double>
</property>
<property
name=
"maximum"
>
<double>
5.000000000000000
</double>
</property>
<property
name=
"singleStep"
>
<double>
0.010000000000000
</double>
</property>
<property
name=
"value"
>
<double>
1.000000000000000
</double>
</property>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>
ui/HGImgThumb.cpp
View file @
735ab83d
...
...
@@ -2963,6 +2963,8 @@ void HGImgThumb::contextMenuEvent(QContextMenuEvent* e)
return
;
}
m_pushItemIndex
=
-
1
;
MouseStatus
mouseMoveStatus
=
MouseStatus_Null
;
int
index
=
getItemIndex
(
e
->
pos
(),
mouseMoveStatus
);
if
(
MouseStatus_Null
==
mouseMoveStatus
)
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment