mirror of
https://bitbucket.org/smil3y/kde-extraapps.git
synced 2025-02-23 18:32:53 +00:00
import libksane, skanlite and ksaneplugin (bootstrap will fail)
This commit is contained in:
parent
2023560860
commit
b839a26abc
112 changed files with 17574 additions and 0 deletions
|
@ -40,6 +40,8 @@ macro_optional_add_subdirectory (kdenetwork-filesharing)
|
|||
macro_optional_add_subdirectory (kfilemetadata)
|
||||
# macro_optional_add_subdirectory (kfilereplace)
|
||||
macro_optional_add_subdirectory (lokalize)
|
||||
# FIXME: make skanlite and ksaneplugin find libksane
|
||||
macro_optional_add_subdirectory (libksane)
|
||||
macro_optional_add_subdirectory (libkscreen)
|
||||
# FIXME: make kget find libktorrent
|
||||
macro_optional_add_subdirectory (libktorrent)
|
||||
|
@ -53,6 +55,7 @@ macro_optional_add_subdirectory (kolourpaint)
|
|||
macro_optional_add_subdirectory (kompare)
|
||||
macro_optional_add_subdirectory (krdc)
|
||||
macro_optional_add_subdirectory (krfb)
|
||||
macro_optional_add_subdirectory (ksaneplugin)
|
||||
macro_optional_add_subdirectory (ksnapshot)
|
||||
macro_optional_add_subdirectory (ksystemlog)
|
||||
macro_optional_add_subdirectory (ktimer)
|
||||
|
@ -61,5 +64,6 @@ macro_optional_add_subdirectory (kuser)
|
|||
macro_optional_add_subdirectory (okular)
|
||||
macro_optional_add_subdirectory (partitionmanager)
|
||||
macro_optional_add_subdirectory (print-manager)
|
||||
macro_optional_add_subdirectory (skanlite)
|
||||
macro_optional_add_subdirectory (svgpart)
|
||||
macro_optional_add_subdirectory (thumbnailers)
|
||||
|
|
25
ksaneplugin/CMakeLists.txt
Normal file
25
ksaneplugin/CMakeLists.txt
Normal file
|
@ -0,0 +1,25 @@
|
|||
|
||||
project(ksaneplugin)
|
||||
|
||||
SET(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_SOURCE_DIR}/cmake/modules )
|
||||
|
||||
find_package(KDE4 REQUIRED)
|
||||
include(KDE4Defaults)
|
||||
include(MacroLibrary)
|
||||
include(MacroOptionalAddSubdirectory)
|
||||
|
||||
find_package(KSane REQUIRED)
|
||||
include_directories(${KSANE_INCLUDE_DIR})
|
||||
add_definitions (${QT_DEFINITIONS} ${QT_QTDBUS_DEFINITIONS} ${KDE4_DEFINITIONS} -DQT_USE_FAST_CONCATENATION -DQT_USE_FAST_OPERATOR_PLUS)
|
||||
include_directories (${QDBUS_INCLUDE_DIRS} ${CMAKE_SOURCE_DIR} ${CMAKE_BINARY_DIR} ${KDE4_INCLUDES})
|
||||
|
||||
########### target ###############
|
||||
kde4_add_plugin(ksaneplugin sanedialog.cpp)
|
||||
|
||||
target_link_libraries(ksaneplugin ${KDE4_KDEUI_LIBS} ${KDE4_KIO_LIBS} ${KSANE_LIBRARY})
|
||||
|
||||
install(TARGETS ksaneplugin DESTINATION ${PLUGIN_INSTALL_DIR} )
|
||||
|
||||
########### install files ###############
|
||||
install( FILES ksane_scan_service.desktop DESTINATION ${SERVICES_INSTALL_DIR} )
|
||||
|
510
ksaneplugin/COPYING
Normal file
510
ksaneplugin/COPYING
Normal file
|
@ -0,0 +1,510 @@
|
|||
|
||||
GNU LESSER GENERAL PUBLIC LICENSE
|
||||
Version 2.1, February 1999
|
||||
|
||||
Copyright (C) 1991, 1999 Free Software Foundation, Inc.
|
||||
51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
[This is the first released version of the Lesser GPL. It also counts
|
||||
as the successor of the GNU Library Public License, version 2, hence
|
||||
the version number 2.1.]
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
Licenses are intended to guarantee your freedom to share and change
|
||||
free software--to make sure the software is free for all its users.
|
||||
|
||||
This license, the Lesser General Public License, applies to some
|
||||
specially designated software packages--typically libraries--of the
|
||||
Free Software Foundation and other authors who decide to use it. You
|
||||
can use it too, but we suggest you first think carefully about whether
|
||||
this license or the ordinary General Public License is the better
|
||||
strategy to use in any particular case, based on the explanations
|
||||
below.
|
||||
|
||||
When we speak of free software, we are referring to freedom of use,
|
||||
not price. Our General Public Licenses are designed to make sure that
|
||||
you have the freedom to distribute copies of free software (and charge
|
||||
for this service if you wish); that you receive source code or can get
|
||||
it if you want it; that you can change the software and use pieces of
|
||||
it in new free programs; and that you are informed that you can do
|
||||
these things.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid
|
||||
distributors to deny you these rights or to ask you to surrender these
|
||||
rights. These restrictions translate to certain responsibilities for
|
||||
you if you distribute copies of the library or if you modify it.
|
||||
|
||||
For example, if you distribute copies of the library, whether gratis
|
||||
or for a fee, you must give the recipients all the rights that we gave
|
||||
you. You must make sure that they, too, receive or can get the source
|
||||
code. If you link other code with the library, you must provide
|
||||
complete object files to the recipients, so that they can relink them
|
||||
with the library after making changes to the library and recompiling
|
||||
it. And you must show them these terms so they know their rights.
|
||||
|
||||
We protect your rights with a two-step method: (1) we copyright the
|
||||
library, and (2) we offer you this license, which gives you legal
|
||||
permission to copy, distribute and/or modify the library.
|
||||
|
||||
To protect each distributor, we want to make it very clear that
|
||||
there is no warranty for the free library. Also, if the library is
|
||||
modified by someone else and passed on, the recipients should know
|
||||
that what they have is not the original version, so that the original
|
||||
author's reputation will not be affected by problems that might be
|
||||
introduced by others.
|
||||
|
||||
Finally, software patents pose a constant threat to the existence of
|
||||
any free program. We wish to make sure that a company cannot
|
||||
effectively restrict the users of a free program by obtaining a
|
||||
restrictive license from a patent holder. Therefore, we insist that
|
||||
any patent license obtained for a version of the library must be
|
||||
consistent with the full freedom of use specified in this license.
|
||||
|
||||
Most GNU software, including some libraries, is covered by the
|
||||
ordinary GNU General Public License. This license, the GNU Lesser
|
||||
General Public License, applies to certain designated libraries, and
|
||||
is quite different from the ordinary General Public License. We use
|
||||
this license for certain libraries in order to permit linking those
|
||||
libraries into non-free programs.
|
||||
|
||||
When a program is linked with a library, whether statically or using
|
||||
a shared library, the combination of the two is legally speaking a
|
||||
combined work, a derivative of the original library. The ordinary
|
||||
General Public License therefore permits such linking only if the
|
||||
entire combination fits its criteria of freedom. The Lesser General
|
||||
Public License permits more lax criteria for linking other code with
|
||||
the library.
|
||||
|
||||
We call this license the "Lesser" General Public License because it
|
||||
does Less to protect the user's freedom than the ordinary General
|
||||
Public License. It also provides other free software developers Less
|
||||
of an advantage over competing non-free programs. These disadvantages
|
||||
are the reason we use the ordinary General Public License for many
|
||||
libraries. However, the Lesser license provides advantages in certain
|
||||
special circumstances.
|
||||
|
||||
For example, on rare occasions, there may be a special need to
|
||||
encourage the widest possible use of a certain library, so that it
|
||||
becomes a de-facto standard. To achieve this, non-free programs must
|
||||
be allowed to use the library. A more frequent case is that a free
|
||||
library does the same job as widely used non-free libraries. In this
|
||||
case, there is little to gain by limiting the free library to free
|
||||
software only, so we use the Lesser General Public License.
|
||||
|
||||
In other cases, permission to use a particular library in non-free
|
||||
programs enables a greater number of people to use a large body of
|
||||
free software. For example, permission to use the GNU C Library in
|
||||
non-free programs enables many more people to use the whole GNU
|
||||
operating system, as well as its variant, the GNU/Linux operating
|
||||
system.
|
||||
|
||||
Although the Lesser General Public License is Less protective of the
|
||||
users' freedom, it does ensure that the user of a program that is
|
||||
linked with the Library has the freedom and the wherewithal to run
|
||||
that program using a modified version of the Library.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow. Pay close attention to the difference between a
|
||||
"work based on the library" and a "work that uses the library". The
|
||||
former contains code derived from the library, whereas the latter must
|
||||
be combined with the library in order to run.
|
||||
|
||||
GNU LESSER GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License Agreement applies to any software library or other
|
||||
program which contains a notice placed by the copyright holder or
|
||||
other authorized party saying it may be distributed under the terms of
|
||||
this Lesser General Public License (also called "this License").
|
||||
Each licensee is addressed as "you".
|
||||
|
||||
A "library" means a collection of software functions and/or data
|
||||
prepared so as to be conveniently linked with application programs
|
||||
(which use some of those functions and data) to form executables.
|
||||
|
||||
The "Library", below, refers to any such software library or work
|
||||
which has been distributed under these terms. A "work based on the
|
||||
Library" means either the Library or any derivative work under
|
||||
copyright law: that is to say, a work containing the Library or a
|
||||
portion of it, either verbatim or with modifications and/or translated
|
||||
straightforwardly into another language. (Hereinafter, translation is
|
||||
included without limitation in the term "modification".)
|
||||
|
||||
"Source code" for a work means the preferred form of the work for
|
||||
making modifications to it. For a library, complete source code means
|
||||
all the source code for all modules it contains, plus any associated
|
||||
interface definition files, plus the scripts used to control
|
||||
compilation and installation of the library.
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running a program using the Library is not restricted, and output from
|
||||
such a program is covered only if its contents constitute a work based
|
||||
on the Library (independent of the use of the Library in a tool for
|
||||
writing it). Whether that is true depends on what the Library does
|
||||
and what the program that uses the Library does.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Library's
|
||||
complete source code as you receive it, in any medium, provided that
|
||||
you conspicuously and appropriately publish on each copy an
|
||||
appropriate copyright notice and disclaimer of warranty; keep intact
|
||||
all the notices that refer to this License and to the absence of any
|
||||
warranty; and distribute a copy of this License along with the
|
||||
Library.
|
||||
|
||||
You may charge a fee for the physical act of transferring a copy,
|
||||
and you may at your option offer warranty protection in exchange for a
|
||||
fee.
|
||||
|
||||
2. You may modify your copy or copies of the Library or any portion
|
||||
of it, thus forming a work based on the Library, and copy and
|
||||
distribute such modifications or work under the terms of Section 1
|
||||
above, provided that you also meet all of these conditions:
|
||||
|
||||
a) The modified work must itself be a software library.
|
||||
|
||||
b) You must cause the files modified to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
|
||||
c) You must cause the whole of the work to be licensed at no
|
||||
charge to all third parties under the terms of this License.
|
||||
|
||||
d) If a facility in the modified Library refers to a function or a
|
||||
table of data to be supplied by an application program that uses
|
||||
the facility, other than as an argument passed when the facility
|
||||
is invoked, then you must make a good faith effort to ensure that,
|
||||
in the event an application does not supply such function or
|
||||
table, the facility still operates, and performs whatever part of
|
||||
its purpose remains meaningful.
|
||||
|
||||
(For example, a function in a library to compute square roots has
|
||||
a purpose that is entirely well-defined independent of the
|
||||
application. Therefore, Subsection 2d requires that any
|
||||
application-supplied function or table used by this function must
|
||||
be optional: if the application does not supply it, the square
|
||||
root function must still compute square roots.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Library,
|
||||
and can be reasonably considered independent and separate works in
|
||||
themselves, then this License, and its terms, do not apply to those
|
||||
sections when you distribute them as separate works. But when you
|
||||
distribute the same sections as part of a whole which is a work based
|
||||
on the Library, the distribution of the whole must be on the terms of
|
||||
this License, whose permissions for other licensees extend to the
|
||||
entire whole, and thus to each and every part regardless of who wrote
|
||||
it.
|
||||
|
||||
Thus, it is not the intent of this section to claim rights or contest
|
||||
your rights to work written entirely by you; rather, the intent is to
|
||||
exercise the right to control the distribution of derivative or
|
||||
collective works based on the Library.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Library
|
||||
with the Library (or with a work based on the Library) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
3. You may opt to apply the terms of the ordinary GNU General Public
|
||||
License instead of this License to a given copy of the Library. To do
|
||||
this, you must alter all the notices that refer to this License, so
|
||||
that they refer to the ordinary GNU General Public License, version 2,
|
||||
instead of to this License. (If a newer version than version 2 of the
|
||||
ordinary GNU General Public License has appeared, then you can specify
|
||||
that version instead if you wish.) Do not make any other change in
|
||||
these notices.
|
||||
|
||||
Once this change is made in a given copy, it is irreversible for
|
||||
that copy, so the ordinary GNU General Public License applies to all
|
||||
subsequent copies and derivative works made from that copy.
|
||||
|
||||
This option is useful when you wish to copy part of the code of
|
||||
the Library into a program that is not a library.
|
||||
|
||||
4. You may copy and distribute the Library (or a portion or
|
||||
derivative of it, under Section 2) in object code or executable form
|
||||
under the terms of Sections 1 and 2 above provided that you accompany
|
||||
it with the complete corresponding machine-readable source code, which
|
||||
must be distributed under the terms of Sections 1 and 2 above on a
|
||||
medium customarily used for software interchange.
|
||||
|
||||
If distribution of object code is made by offering access to copy
|
||||
from a designated place, then offering equivalent access to copy the
|
||||
source code from the same place satisfies the requirement to
|
||||
distribute the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
5. A program that contains no derivative of any portion of the
|
||||
Library, but is designed to work with the Library by being compiled or
|
||||
linked with it, is called a "work that uses the Library". Such a
|
||||
work, in isolation, is not a derivative work of the Library, and
|
||||
therefore falls outside the scope of this License.
|
||||
|
||||
However, linking a "work that uses the Library" with the Library
|
||||
creates an executable that is a derivative of the Library (because it
|
||||
contains portions of the Library), rather than a "work that uses the
|
||||
library". The executable is therefore covered by this License.
|
||||
Section 6 states terms for distribution of such executables.
|
||||
|
||||
When a "work that uses the Library" uses material from a header file
|
||||
that is part of the Library, the object code for the work may be a
|
||||
derivative work of the Library even though the source code is not.
|
||||
Whether this is true is especially significant if the work can be
|
||||
linked without the Library, or if the work is itself a library. The
|
||||
threshold for this to be true is not precisely defined by law.
|
||||
|
||||
If such an object file uses only numerical parameters, data
|
||||
structure layouts and accessors, and small macros and small inline
|
||||
functions (ten lines or less in length), then the use of the object
|
||||
file is unrestricted, regardless of whether it is legally a derivative
|
||||
work. (Executables containing this object code plus portions of the
|
||||
Library will still fall under Section 6.)
|
||||
|
||||
Otherwise, if the work is a derivative of the Library, you may
|
||||
distribute the object code for the work under the terms of Section 6.
|
||||
Any executables containing that work also fall under Section 6,
|
||||
whether or not they are linked directly with the Library itself.
|
||||
|
||||
6. As an exception to the Sections above, you may also combine or
|
||||
link a "work that uses the Library" with the Library to produce a
|
||||
work containing portions of the Library, and distribute that work
|
||||
under terms of your choice, provided that the terms permit
|
||||
modification of the work for the customer's own use and reverse
|
||||
engineering for debugging such modifications.
|
||||
|
||||
You must give prominent notice with each copy of the work that the
|
||||
Library is used in it and that the Library and its use are covered by
|
||||
this License. You must supply a copy of this License. If the work
|
||||
during execution displays copyright notices, you must include the
|
||||
copyright notice for the Library among them, as well as a reference
|
||||
directing the user to the copy of this License. Also, you must do one
|
||||
of these things:
|
||||
|
||||
a) Accompany the work with the complete corresponding
|
||||
machine-readable source code for the Library including whatever
|
||||
changes were used in the work (which must be distributed under
|
||||
Sections 1 and 2 above); and, if the work is an executable linked
|
||||
with the Library, with the complete machine-readable "work that
|
||||
uses the Library", as object code and/or source code, so that the
|
||||
user can modify the Library and then relink to produce a modified
|
||||
executable containing the modified Library. (It is understood
|
||||
that the user who changes the contents of definitions files in the
|
||||
Library will not necessarily be able to recompile the application
|
||||
to use the modified definitions.)
|
||||
|
||||
b) Use a suitable shared library mechanism for linking with the
|
||||
Library. A suitable mechanism is one that (1) uses at run time a
|
||||
copy of the library already present on the user's computer system,
|
||||
rather than copying library functions into the executable, and (2)
|
||||
will operate properly with a modified version of the library, if
|
||||
the user installs one, as long as the modified version is
|
||||
interface-compatible with the version that the work was made with.
|
||||
|
||||
c) Accompany the work with a written offer, valid for at least
|
||||
three years, to give the same user the materials specified in
|
||||
Subsection 6a, above, for a charge no more than the cost of
|
||||
performing this distribution.
|
||||
|
||||
d) If distribution of the work is made by offering access to copy
|
||||
from a designated place, offer equivalent access to copy the above
|
||||
specified materials from the same place.
|
||||
|
||||
e) Verify that the user has already received a copy of these
|
||||
materials or that you have already sent this user a copy.
|
||||
|
||||
For an executable, the required form of the "work that uses the
|
||||
Library" must include any data and utility programs needed for
|
||||
reproducing the executable from it. However, as a special exception,
|
||||
the materials to be distributed need not include anything that is
|
||||
normally distributed (in either source or binary form) with the major
|
||||
components (compiler, kernel, and so on) of the operating system on
|
||||
which the executable runs, unless that component itself accompanies
|
||||
the executable.
|
||||
|
||||
It may happen that this requirement contradicts the license
|
||||
restrictions of other proprietary libraries that do not normally
|
||||
accompany the operating system. Such a contradiction means you cannot
|
||||
use both them and the Library together in an executable that you
|
||||
distribute.
|
||||
|
||||
7. You may place library facilities that are a work based on the
|
||||
Library side-by-side in a single library together with other library
|
||||
facilities not covered by this License, and distribute such a combined
|
||||
library, provided that the separate distribution of the work based on
|
||||
the Library and of the other library facilities is otherwise
|
||||
permitted, and provided that you do these two things:
|
||||
|
||||
a) Accompany the combined library with a copy of the same work
|
||||
based on the Library, uncombined with any other library
|
||||
facilities. This must be distributed under the terms of the
|
||||
Sections above.
|
||||
|
||||
b) Give prominent notice with the combined library of the fact
|
||||
that part of it is a work based on the Library, and explaining
|
||||
where to find the accompanying uncombined form of the same work.
|
||||
|
||||
8. You may not copy, modify, sublicense, link with, or distribute
|
||||
the Library except as expressly provided under this License. Any
|
||||
attempt otherwise to copy, modify, sublicense, link with, or
|
||||
distribute the Library is void, and will automatically terminate your
|
||||
rights under this License. However, parties who have received copies,
|
||||
or rights, from you under this License will not have their licenses
|
||||
terminated so long as such parties remain in full compliance.
|
||||
|
||||
9. You are not required to accept this License, since you have not
|
||||
signed it. However, nothing else grants you permission to modify or
|
||||
distribute the Library or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Library (or any work based on the
|
||||
Library), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Library or works based on it.
|
||||
|
||||
10. Each time you redistribute the Library (or any work based on the
|
||||
Library), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute, link with or modify the Library
|
||||
subject to these terms and conditions. You may not impose any further
|
||||
restrictions on the recipients' exercise of the rights granted herein.
|
||||
You are not responsible for enforcing compliance by third parties with
|
||||
this License.
|
||||
|
||||
11. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues),
|
||||
conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot
|
||||
distribute so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you
|
||||
may not distribute the Library at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Library by
|
||||
all those who receive copies directly or indirectly through you, then
|
||||
the only way you could satisfy both it and this License would be to
|
||||
refrain entirely from distribution of the Library.
|
||||
|
||||
If any portion of this section is held invalid or unenforceable under
|
||||
any particular circumstance, the balance of the section is intended to
|
||||
apply, and the section as a whole is intended to apply in other
|
||||
circumstances.
|
||||
|
||||
It is not the purpose of this section to induce you to infringe any
|
||||
patents or other property right claims or to contest validity of any
|
||||
such claims; this section has the sole purpose of protecting the
|
||||
integrity of the free software distribution system which is
|
||||
implemented by public license practices. Many people have made
|
||||
generous contributions to the wide range of software distributed
|
||||
through that system in reliance on consistent application of that
|
||||
system; it is up to the author/donor to decide if he or she is willing
|
||||
to distribute software through any other system and a licensee cannot
|
||||
impose that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
12. If the distribution and/or use of the Library is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Library under this License
|
||||
may add an explicit geographical distribution limitation excluding those
|
||||
countries, so that distribution is permitted only in or among
|
||||
countries not thus excluded. In such case, this License incorporates
|
||||
the limitation as if written in the body of this License.
|
||||
|
||||
13. The Free Software Foundation may publish revised and/or new
|
||||
versions of the Lesser General Public License from time to time.
|
||||
Such new versions will be similar in spirit to the present version,
|
||||
but may differ in detail to address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Library
|
||||
specifies a version number of this License which applies to it and
|
||||
"any later version", you have the option of following the terms and
|
||||
conditions either of that version or of any later version published by
|
||||
the Free Software Foundation. If the Library does not specify a
|
||||
license version number, you may choose any version ever published by
|
||||
the Free Software Foundation.
|
||||
|
||||
14. If you wish to incorporate parts of the Library into other free
|
||||
programs whose distribution conditions are incompatible with these,
|
||||
write to the author to ask for permission. For software which is
|
||||
copyrighted by the Free Software Foundation, write to the Free
|
||||
Software Foundation; we sometimes make exceptions for this. Our
|
||||
decision will be guided by the two goals of preserving the free status
|
||||
of all derivatives of our free software and of promoting the sharing
|
||||
and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
|
||||
15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
|
||||
WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
|
||||
EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
|
||||
OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
|
||||
KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
|
||||
LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
|
||||
THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||
|
||||
16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
|
||||
WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
|
||||
AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
|
||||
FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
|
||||
CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
|
||||
LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
|
||||
RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
|
||||
FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
|
||||
SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
|
||||
DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Libraries
|
||||
|
||||
If you develop a new library, and you want it to be of the greatest
|
||||
possible use to the public, we recommend making it free software that
|
||||
everyone can redistribute and change. You can do so by permitting
|
||||
redistribution under these terms (or, alternatively, under the terms
|
||||
of the ordinary General Public License).
|
||||
|
||||
To apply these terms, attach the following notices to the library.
|
||||
It is safest to attach them to the start of each source file to most
|
||||
effectively convey the exclusion of warranty; and each file should
|
||||
have at least the "copyright" line and a pointer to where the full
|
||||
notice is found.
|
||||
|
||||
|
||||
<one line to give the library's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or
|
||||
your school, if any, to sign a "copyright disclaimer" for the library,
|
||||
if necessary. Here is a sample; alter the names:
|
||||
|
||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the
|
||||
library `Frob' (a library for tweaking knobs) written by James
|
||||
Random Hacker.
|
||||
|
||||
<signature of Ty Coon>, 1 April 1990
|
||||
Ty Coon, President of Vice
|
||||
|
||||
That's all there is to it!
|
||||
|
||||
|
2
ksaneplugin/Messages.sh
Normal file
2
ksaneplugin/Messages.sh
Normal file
|
@ -0,0 +1,2 @@
|
|||
#! /usr/bin/env bash
|
||||
$XGETTEXT *.cpp -o $podir/ksaneplugin.pot
|
22
ksaneplugin/cmake/modules/COPYING-CMAKE-SCRIPTS
Normal file
22
ksaneplugin/cmake/modules/COPYING-CMAKE-SCRIPTS
Normal file
|
@ -0,0 +1,22 @@
|
|||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
1. Redistributions of source code must retain the copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
2. Redistributions in binary form must reproduce the copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
3. The name of the author may not be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
44
ksaneplugin/cmake/modules/FindKSane.cmake
Normal file
44
ksaneplugin/cmake/modules/FindKSane.cmake
Normal file
|
@ -0,0 +1,44 @@
|
|||
# cmake macro to test if libksane is installed
|
||||
#
|
||||
# KSANE_FOUND - system has KSANE libs
|
||||
# KSANE_INCLUDE_DIR - the KSANE include directory
|
||||
# KSANE_LIBRARY - The library needed to use KSANE
|
||||
|
||||
if (KSANE_INCLUDE_DIR)
|
||||
# Already in cache, be silent
|
||||
set(KSANE_FIND_QUIETLY TRUE)
|
||||
endif (KSANE_INCLUDE_DIR)
|
||||
|
||||
FIND_FILE(KSANE_LOCAL_FOUND libksane/version.h.cmake ${CMAKE_SOURCE_DIR}/libs/libksane NO_DEFAULT_PATH)
|
||||
|
||||
if (KSANE_LOCAL_FOUND)
|
||||
set(KSANE_INCLUDE_DIR ${CMAKE_SOURCE_DIR}/libs/libksane)
|
||||
set(KSANE_DEFINITIONS -I${KSANE_INCLUDE_DIR})
|
||||
set(KSANE_LIBRARY ksane)
|
||||
message(STATUS "Found KSane library in local sub-folder: ${KSANE_LIBRARY}")
|
||||
set(KSANE_FOUND TRUE)
|
||||
MARK_AS_ADVANCED(KSANE_INCLUDE_DIR KSANE_LIBRARY)
|
||||
else (KSANE_LOCAL_FOUND)
|
||||
|
||||
FIND_PATH(KSANE_INCLUDE_DIR libksane/ksane.h ${KDE4_INCLUDES})
|
||||
|
||||
FIND_LIBRARY(KSANE_LIBRARY ksane PATH ${KDE4_LIB_DIR})
|
||||
|
||||
if (KSANE_INCLUDE_DIR AND KSANE_LIBRARY)
|
||||
set(KSANE_FOUND TRUE)
|
||||
else (KSANE_INCLUDE_DIR AND KSANE_LIBRARY)
|
||||
set(KSANE_FOUND FALSE)
|
||||
endif (KSANE_INCLUDE_DIR AND KSANE_LIBRARY)
|
||||
|
||||
if (KSANE_FOUND)
|
||||
if (NOT KSane_FIND_QUIETLY)
|
||||
message(STATUS "Found libksane: ${KSANE_LIBRARY}")
|
||||
endif (NOT KSane_FIND_QUIETLY)
|
||||
else (KSANE_FOUND)
|
||||
if (KSane_FIND_REQUIRED)
|
||||
message(FATAL_ERROR "Could not find libksane")
|
||||
endif (KSane_FIND_REQUIRED)
|
||||
endif (KSANE_FOUND)
|
||||
endif (KSANE_LOCAL_FOUND)
|
||||
|
||||
MARK_AS_ADVANCED(KSANE_INCLUDE_DIR KSANE_LIBRARY)
|
81
ksaneplugin/ksane_scan_service.desktop
Normal file
81
ksaneplugin/ksane_scan_service.desktop
Normal file
|
@ -0,0 +1,81 @@
|
|||
[Desktop Entry]
|
||||
Type=Service
|
||||
Name=KDE Scan Service
|
||||
Name[af]=Kde Skandeer Diens
|
||||
Name[ar]=خدمة المسح لكدي
|
||||
Name[ast]=Serviciu de dixitalización de KDE
|
||||
Name[bg]=Услуга за сканиране
|
||||
Name[br]=Damanterien skramm
|
||||
Name[bs]=KDE‑ov servis za skeniranje
|
||||
Name[ca]=Servei d'escaneig del KDE
|
||||
Name[ca@valencia]=Servei d'escaneig del KDE
|
||||
Name[cs]=Skenovací služba pro KDE
|
||||
Name[cy]=Gwasanaeth Sganio KDE
|
||||
Name[da]=KDE Skanneservice
|
||||
Name[de]=Scan-Dienst von KDE
|
||||
Name[el]=Υπηρεσία σάρωσης του KDE
|
||||
Name[en_GB]=KDE Scan Service
|
||||
Name[eo]=KDE skana servo
|
||||
Name[es]=Servicio de digitalización de KDE
|
||||
Name[et]=KDE skaneerimisteenus
|
||||
Name[eu]=KDEren eskaneatze zerbitzua
|
||||
Name[fa]=خدمت پویش KDE
|
||||
Name[fi]=KDE :n skannauspalvelu
|
||||
Name[fr]=Service de numérisation de KDE
|
||||
Name[ga]=Seirbhís Scanta KDE
|
||||
Name[gl]=Servizo de escáner de KDE
|
||||
Name[he]=שירות הסריקה של KDE
|
||||
Name[hi]=केडीई स्कैन सर्विस
|
||||
Name[hne]=केडीई स्कैन सर्विस
|
||||
Name[hr]=KDE skan servis
|
||||
Name[hu]=KDE lapolvasó szolgáltatás
|
||||
Name[ia]=Servicio de scander de KDE
|
||||
Name[is]=KDE myndlesaraþjónusta
|
||||
Name[it]=Servizio di scansione di KDE
|
||||
Name[ja]=KDE スキャンサービス
|
||||
Name[kk]=KDE сканер қызметі
|
||||
Name[km]=សេវាស្កេនរបស់ KDE
|
||||
Name[ko]=KDE 스캔 서비스
|
||||
Name[ku]=KDE Servîsa Venihêrînê
|
||||
Name[lt]=KDE skanavimo tarnyba
|
||||
Name[lv]=KDE skenēšanas serviss
|
||||
Name[mr]=केडीई स्कॅन सेवा
|
||||
Name[ms]=Perkhidmatan Imbas KDE
|
||||
Name[nb]=KDE skannetjeneste
|
||||
Name[nds]=Bildinleesdeenst för KDE
|
||||
Name[ne]=केडीई स्क्यान सेवा
|
||||
Name[nl]=KDE Scannerdiensten
|
||||
Name[nn]=KDE Skanningsteneste
|
||||
Name[pa]=KDE ਸਕੈਨ ਸਰਵਿਸ
|
||||
Name[pl]=Usługa skanowania KDE
|
||||
Name[pt]=Serviço de Digitalização do KDE
|
||||
Name[pt_BR]=Serviço de digitalização do KDE
|
||||
Name[ro]=Serviciu de scanare KDE
|
||||
Name[ru]=Служба сканирования KDE
|
||||
Name[se]=KDE skánnenbálválus
|
||||
Name[si]=KDE ස්කෑන් සේවාව
|
||||
Name[sk]=Skenovacia služba pre KDE
|
||||
Name[sl]=Storitev optičnega branja za KDE
|
||||
Name[sr]=КДЕ‑ов сервис за скенирање
|
||||
Name[sr@ijekavian]=КДЕ‑ов сервис за скенирање
|
||||
Name[sr@ijekavianlatin]=KDE‑ov servis za skeniranje
|
||||
Name[sr@latin]=KDE‑ov servis za skeniranje
|
||||
Name[sv]=KDE:s bildläsartjänst
|
||||
Name[ta]=கேடிஇ வருடு சேவை
|
||||
Name[tg]=Сканеронӣ дар KDE
|
||||
Name[th]=บริการสแกนภาพ-K
|
||||
Name[tr]=KDE Tarayıcı Servisi
|
||||
Name[ug]=KDE شويلىلاش مۇلازىمىتى
|
||||
Name[uk]=Служба сканування KDE
|
||||
Name[uz]=KDE skan qilish xizmati
|
||||
Name[uz@cyrillic]=KDE скан қилиш хизмати
|
||||
Name[vi]=Dịch vụ quét của KDE
|
||||
Name[wa]=Siervice di scanaedje di KDE
|
||||
Name[xh]=Inkonzo yemita yovavanyo ye KDE
|
||||
Name[x-test]=xxKDE Scan Servicexx
|
||||
Name[zh_CN]=KDE 扫描服务
|
||||
Name[zh_HK]=KDE 掃描服務
|
||||
Name[zh_TW]=KDE 掃描服務
|
||||
X-KDE-Library=ksaneplugin
|
||||
InitialPreference=3
|
||||
X-KDE-ServiceTypes=KScan/KScanDialog
|
114
ksaneplugin/sanedialog.cpp
Normal file
114
ksaneplugin/sanedialog.cpp
Normal file
|
@ -0,0 +1,114 @@
|
|||
/* ============================================================
|
||||
*
|
||||
* Date : 2008-04-17
|
||||
* Description : Sane plugin interface for KDE
|
||||
*
|
||||
* Copyright (C) 2008 by Kare Sars <kare dot sars at iki dot fi>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) version 3, or any
|
||||
* later version accepted by the membership of KDE e.V. (or its
|
||||
* successor approved by the membership of KDE e.V.), which shall
|
||||
* act as a proxy defined in Section 6 of version 3 of the license.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* ============================================================ */
|
||||
|
||||
#include "sanedialog.h"
|
||||
|
||||
#include <KLocale>
|
||||
#include <KDebug>
|
||||
#include <KPluginLoader>
|
||||
#include <KMessageBox>
|
||||
#include <KSharedConfig>
|
||||
|
||||
K_PLUGIN_FACTORY(SaneDialogFactory, registerPlugin<SaneDialog>();)
|
||||
K_EXPORT_PLUGIN(SaneDialogFactory("ksaneplugin"))
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
SaneDialog::SaneDialog(QWidget *parent, const QVariantList &)
|
||||
: KScanDialog(Plain, Close, parent)
|
||||
{
|
||||
ksanew = new KSaneIface::KSaneWidget(this);
|
||||
addPage(ksanew, QString());
|
||||
|
||||
connect(ksanew, SIGNAL(imageReady(QByteArray &, int, int, int, int)),
|
||||
this, SLOT(imageReady(QByteArray &, int, int, int, int)));
|
||||
|
||||
openDev = QString();
|
||||
}
|
||||
|
||||
|
||||
bool SaneDialog::setup()
|
||||
{
|
||||
if(!ksanew) {
|
||||
// new failed
|
||||
return false;
|
||||
}
|
||||
if (!openDev.isEmpty()) {
|
||||
return true;
|
||||
}
|
||||
// need to select a scanner
|
||||
openDev = ksanew->selectDevice(0);
|
||||
if (openDev.isEmpty()) {
|
||||
// either no scanner was found or then cancel was pressed.
|
||||
return false;
|
||||
}
|
||||
if (ksanew->openDevice(openDev) == false) {
|
||||
// could not open the scanner
|
||||
KMessageBox::sorry(0, i18n("Opening the selected scanner failed."));
|
||||
openDev = QString();
|
||||
return false;
|
||||
}
|
||||
|
||||
// restore scan dialog size and all options for the selected device if available
|
||||
KSharedConfigPtr configPtr = KSharedConfig::openConfig("scannersettings");
|
||||
restoreDialogSize(KConfigGroup(configPtr, "ScanDialog"));
|
||||
QString groupName = openDev;
|
||||
if (configPtr->hasGroup(groupName)) {
|
||||
KConfigGroup group(configPtr, groupName);
|
||||
QStringList keys = group.keyList();
|
||||
for (int i = 0; i < keys.count(); i++)
|
||||
ksanew->setOptVal(keys[i], group.readEntry(keys[i]));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
SaneDialog::~SaneDialog()
|
||||
{
|
||||
if (ksanew && !openDev.isEmpty()) {
|
||||
// save scan dialog size and all options for the selected device if available
|
||||
KSharedConfigPtr configPtr = KSharedConfig::openConfig("scannersettings");
|
||||
KConfigGroup group(configPtr, "ScanDialog");
|
||||
saveDialogSize(group, KConfigGroup::Persistent);
|
||||
group = configPtr->group(openDev);
|
||||
QMap<QString, QString> opts;
|
||||
ksanew->getOptVals(opts);
|
||||
QMap<QString, QString>::const_iterator i = opts.constBegin();
|
||||
for (; i != opts.constEnd(); ++i)
|
||||
group.writeEntry(i.key(), i.value(), KConfigGroup::Persistent);
|
||||
}
|
||||
}
|
||||
|
||||
void SaneDialog::imageReady(QByteArray &data, int w, int h, int bpl, int f)
|
||||
{
|
||||
/* copy the image data into img */
|
||||
QImage img = ksanew->toQImage(data, w, h, bpl, (KSaneIface::KSaneWidget::ImageFormat)f);
|
||||
emit finalImage(img, nextId());
|
||||
}
|
||||
|
||||
|
||||
#include "sanedialog.moc"
|
52
ksaneplugin/sanedialog.h
Normal file
52
ksaneplugin/sanedialog.h
Normal file
|
@ -0,0 +1,52 @@
|
|||
/* ============================================================
|
||||
*
|
||||
* Date : 2008-04-17
|
||||
* Description : Sane plugin interface for KDE
|
||||
*
|
||||
* Copyright (C) 2008 by Kare Sars <kare dot sars at iki dot fi>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) version 3, or any
|
||||
* later version accepted by the membership of KDE e.V. (or its
|
||||
* successor approved by the membership of KDE e.V.), which shall
|
||||
* act as a proxy defined in Section 6 of version 3 of the license.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* ============================================================ */
|
||||
|
||||
#ifndef SANEDIALOG_H
|
||||
#define SANEDIALOG_H
|
||||
|
||||
#include <kscan.h>
|
||||
#include <libksane/ksane.h>
|
||||
|
||||
|
||||
class SaneDialog : public KScanDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit SaneDialog( QWidget *parent = 0, const QVariantList &args = QVariantList() );
|
||||
~SaneDialog();
|
||||
|
||||
virtual bool setup();
|
||||
|
||||
protected slots:
|
||||
void imageReady(QByteArray &, int, int, int, int);
|
||||
|
||||
private:
|
||||
KSaneIface::KSaneWidget *ksanew;
|
||||
QString openDev;
|
||||
};
|
||||
|
||||
|
||||
#endif // SCAN_H
|
3
libksane/.directory
Normal file
3
libksane/.directory
Normal file
|
@ -0,0 +1,3 @@
|
|||
[Dolphin]
|
||||
Timestamp=2015,1,1,1,18,6
|
||||
Version=3
|
2
libksane/.gitignore
vendored
Normal file
2
libksane/.gitignore
vendored
Normal file
|
@ -0,0 +1,2 @@
|
|||
*.kate-swp
|
||||
tests/databases/*/*.db
|
8
libksane/AUTHORS
Normal file
8
libksane/AUTHORS
Normal file
|
@ -0,0 +1,8 @@
|
|||
AUTHORS AND MAINTAINERS:
|
||||
|
||||
Kare Sars <kare dot sars at iki dot fi>
|
||||
Caulier Gilles <caulier dot gilles at gmail dot com>
|
||||
|
||||
CONTRIBUTORS:
|
||||
|
||||
Angelo Naselli <anaselli at linux dot it>
|
83
libksane/CMakeLists.txt
Normal file
83
libksane/CMakeLists.txt
Normal file
|
@ -0,0 +1,83 @@
|
|||
PROJECT(libksane)
|
||||
|
||||
MESSAGE(STATUS "----------------------------------------------------------------------------------")
|
||||
MESSAGE(STATUS "Starting CMake configuration for: libksane")
|
||||
|
||||
# building separately or as part of kdegraphics ?
|
||||
IF(NOT KDE4_FOUND)
|
||||
FIND_PACKAGE(KDE4 REQUIRED)
|
||||
ENDIF(NOT KDE4_FOUND)
|
||||
|
||||
# Check if sane API is available.
|
||||
IF (NOT WIN32)
|
||||
FIND_PACKAGE(Sane)
|
||||
macro_log_feature(SANE_FOUND "SANE development toolkit" "Scanner Access Now Easy (SANE) development package" "http://www.sane-project.org" TRUE "" "Needed by libksane")
|
||||
ENDIF (NOT WIN32)
|
||||
|
||||
ADD_DEFINITIONS (${QT_DEFINITIONS} ${KDE4_DEFINITIONS})
|
||||
INCLUDE_DIRECTORIES (${CMAKE_SOURCE_DIR}
|
||||
${CMAKE_BINARY_DIR}
|
||||
${KDE4_INCLUDES}
|
||||
${CMAKE_CURRENT_BINARY_DIR}/libksane)
|
||||
|
||||
# =======================================================
|
||||
# Information to update before to release this library.
|
||||
|
||||
# Library version history:
|
||||
# API ABI
|
||||
# 0.1.0 => 0.1.0
|
||||
# 0.1.1 => 0.1.1
|
||||
# 0.2.0 => 0.2.0
|
||||
|
||||
# Library API version
|
||||
SET(KSANE_LIB_MAJOR_VERSION "0")
|
||||
SET(KSANE_LIB_MINOR_VERSION "3")
|
||||
SET(KSANE_LIB_PATCH_VERSION "0")
|
||||
|
||||
# Suffix to add at end of version string. Usual values are:
|
||||
# "-git" : alpha code unstable from git. Do not use in production
|
||||
# "-beta1" : beta1 release.
|
||||
# "-beta2" : beta2 release.
|
||||
# "-beta3" : beta3 release.
|
||||
# "-rc" : release candidate.
|
||||
# "" : final relase. Can be used in production.
|
||||
SET(KSANE_LIB_SUFFIX_VERSION "")
|
||||
|
||||
# Library ABI version used by linker.
|
||||
# For details : http://www.gnu.org/software/libtool/manual/libtool.html#Updating-version-info
|
||||
SET(KSANE_LIB_SO_CUR_VERSION "0")
|
||||
SET(KSANE_LIB_SO_REV_VERSION "2")
|
||||
SET(KSANE_LIB_SO_AGE_VERSION "0")
|
||||
|
||||
# =======================================================
|
||||
# Set env. variables accordinly.
|
||||
|
||||
SET(KSANE_LIB_VERSION_STRING "${KSANE_LIB_MAJOR_VERSION}.${KSANE_LIB_MINOR_VERSION}.${KSANE_LIB_PATCH_VERSION}${KSANE_LIB_SUFFIX_VERSION}")
|
||||
SET(KSANE_LIB_VERSION_ID "0x0${KSANE_LIB_MAJOR_VERSION}0${KSANE_LIB_MINOR_VERSION}0${KSANE_LIB_PATCH_VERSION}")
|
||||
|
||||
SET(KSANE_LIB_SO_VERSION_STRING "${KSANE_LIB_SO_CUR_VERSION}.${KSANE_LIB_SO_REV_VERSION}.${KSANE_LIB_SO_AGE_VERSION}")
|
||||
|
||||
# =======================================================
|
||||
|
||||
ADD_DEFINITIONS(-DKDE_DEFAULT_DEBUG_AREA=51004)
|
||||
|
||||
CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/libksane/version.h.cmake.in ${CMAKE_CURRENT_BINARY_DIR}/libksane/version.h)
|
||||
|
||||
# =======================================================
|
||||
|
||||
# To prevent warnings from M$ compiler
|
||||
IF(WIN32 AND MSVC)
|
||||
ADD_DEFINITIONS(-D_CRT_SECURE_NO_WARNINGS)
|
||||
ADD_DEFINITIONS(-D_ATL_SECURE_NO_WARNINGS)
|
||||
ADD_DEFINITIONS(-D_AFX_SECURE_NO_WARNINGS)
|
||||
ENDIF(WIN32 AND MSVC)
|
||||
|
||||
# =======================================================
|
||||
|
||||
IF (SANE_FOUND)
|
||||
ADD_SUBDIRECTORY(libksane)
|
||||
ELSE (SANE_FOUND)
|
||||
ADD_SUBDIRECTORY(ksanetwain)
|
||||
ENDIF (SANE_FOUND)
|
||||
|
||||
macro_display_feature_log()
|
340
libksane/COPYING
Normal file
340
libksane/COPYING
Normal file
|
@ -0,0 +1,340 @@
|
|||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 2, June 1991
|
||||
|
||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
License is intended to guarantee your freedom to share and change free
|
||||
software--to make sure the software is free for all its users. This
|
||||
General Public License applies to most of the Free Software
|
||||
Foundation's software and to any other program whose authors commit to
|
||||
using it. (Some other Free Software Foundation software is covered by
|
||||
the GNU Library General Public License instead.) You can apply it to
|
||||
your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
this service if you wish), that you receive source code or can get it
|
||||
if you want it, that you can change the software or use pieces of it
|
||||
in new free programs; and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid
|
||||
anyone to deny you these rights or to ask you to surrender the rights.
|
||||
These restrictions translate to certain responsibilities for you if you
|
||||
distribute copies of the software, or if you modify it.
|
||||
|
||||
For example, if you distribute copies of such a program, whether
|
||||
gratis or for a fee, you must give the recipients all the rights that
|
||||
you have. You must make sure that they, too, receive or can get the
|
||||
source code. And you must show them these terms so they know their
|
||||
rights.
|
||||
|
||||
We protect your rights with two steps: (1) copyright the software, and
|
||||
(2) offer you this license which gives you legal permission to copy,
|
||||
distribute and/or modify the software.
|
||||
|
||||
Also, for each author's protection and ours, we want to make certain
|
||||
that everyone understands that there is no warranty for this free
|
||||
software. If the software is modified by someone else and passed on, we
|
||||
want its recipients to know that what they have is not the original, so
|
||||
that any problems introduced by others will not reflect on the original
|
||||
authors' reputations.
|
||||
|
||||
Finally, any free program is threatened constantly by software
|
||||
patents. We wish to avoid the danger that redistributors of a free
|
||||
program will individually obtain patent licenses, in effect making the
|
||||
program proprietary. To prevent this, we have made it clear that any
|
||||
patent must be licensed for everyone's free use or not licensed at all.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License applies to any program or other work which contains
|
||||
a notice placed by the copyright holder saying it may be distributed
|
||||
under the terms of this General Public License. The "Program", below,
|
||||
refers to any such program or work, and a "work based on the Program"
|
||||
means either the Program or any derivative work under copyright law:
|
||||
that is to say, a work containing the Program or a portion of it,
|
||||
either verbatim or with modifications and/or translated into another
|
||||
language. (Hereinafter, translation is included without limitation in
|
||||
the term "modification".) Each licensee is addressed as "you".
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running the Program is not restricted, and the output from the Program
|
||||
is covered only if its contents constitute a work based on the
|
||||
Program (independent of having been made by running the Program).
|
||||
Whether that is true depends on what the Program does.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Program's
|
||||
source code as you receive it, in any medium, provided that you
|
||||
conspicuously and appropriately publish on each copy an appropriate
|
||||
copyright notice and disclaimer of warranty; keep intact all the
|
||||
notices that refer to this License and to the absence of any warranty;
|
||||
and give any other recipients of the Program a copy of this License
|
||||
along with the Program.
|
||||
|
||||
You may charge a fee for the physical act of transferring a copy, and
|
||||
you may at your option offer warranty protection in exchange for a fee.
|
||||
|
||||
2. You may modify your copy or copies of the Program or any portion
|
||||
of it, thus forming a work based on the Program, and copy and
|
||||
distribute such modifications or work under the terms of Section 1
|
||||
above, provided that you also meet all of these conditions:
|
||||
|
||||
a) You must cause the modified files to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
|
||||
b) You must cause any work that you distribute or publish, that in
|
||||
whole or in part contains or is derived from the Program or any
|
||||
part thereof, to be licensed as a whole at no charge to all third
|
||||
parties under the terms of this License.
|
||||
|
||||
c) If the modified program normally reads commands interactively
|
||||
when run, you must cause it, when started running for such
|
||||
interactive use in the most ordinary way, to print or display an
|
||||
announcement including an appropriate copyright notice and a
|
||||
notice that there is no warranty (or else, saying that you provide
|
||||
a warranty) and that users may redistribute the program under
|
||||
these conditions, and telling the user how to view a copy of this
|
||||
License. (Exception: if the Program itself is interactive but
|
||||
does not normally print such an announcement, your work based on
|
||||
the Program is not required to print an announcement.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Program,
|
||||
and can be reasonably considered independent and separate works in
|
||||
themselves, then this License, and its terms, do not apply to those
|
||||
sections when you distribute them as separate works. But when you
|
||||
distribute the same sections as part of a whole which is a work based
|
||||
on the Program, the distribution of the whole must be on the terms of
|
||||
this License, whose permissions for other licensees extend to the
|
||||
entire whole, and thus to each and every part regardless of who wrote it.
|
||||
|
||||
Thus, it is not the intent of this section to claim rights or contest
|
||||
your rights to work written entirely by you; rather, the intent is to
|
||||
exercise the right to control the distribution of derivative or
|
||||
collective works based on the Program.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Program
|
||||
with the Program (or with a work based on the Program) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
3. You may copy and distribute the Program (or a work based on it,
|
||||
under Section 2) in object code or executable form under the terms of
|
||||
Sections 1 and 2 above provided that you also do one of the following:
|
||||
|
||||
a) Accompany it with the complete corresponding machine-readable
|
||||
source code, which must be distributed under the terms of Sections
|
||||
1 and 2 above on a medium customarily used for software interchange; or,
|
||||
|
||||
b) Accompany it with a written offer, valid for at least three
|
||||
years, to give any third party, for a charge no more than your
|
||||
cost of physically performing source distribution, a complete
|
||||
machine-readable copy of the corresponding source code, to be
|
||||
distributed under the terms of Sections 1 and 2 above on a medium
|
||||
customarily used for software interchange; or,
|
||||
|
||||
c) Accompany it with the information you received as to the offer
|
||||
to distribute corresponding source code. (This alternative is
|
||||
allowed only for noncommercial distribution and only if you
|
||||
received the program in object code or executable form with such
|
||||
an offer, in accord with Subsection b above.)
|
||||
|
||||
The source code for a work means the preferred form of the work for
|
||||
making modifications to it. For an executable work, complete source
|
||||
code means all the source code for all modules it contains, plus any
|
||||
associated interface definition files, plus the scripts used to
|
||||
control compilation and installation of the executable. However, as a
|
||||
special exception, the source code distributed need not include
|
||||
anything that is normally distributed (in either source or binary
|
||||
form) with the major components (compiler, kernel, and so on) of the
|
||||
operating system on which the executable runs, unless that component
|
||||
itself accompanies the executable.
|
||||
|
||||
If distribution of executable or object code is made by offering
|
||||
access to copy from a designated place, then offering equivalent
|
||||
access to copy the source code from the same place counts as
|
||||
distribution of the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
4. You may not copy, modify, sublicense, or distribute the Program
|
||||
except as expressly provided under this License. Any attempt
|
||||
otherwise to copy, modify, sublicense or distribute the Program is
|
||||
void, and will automatically terminate your rights under this License.
|
||||
However, parties who have received copies, or rights, from you under
|
||||
this License will not have their licenses terminated so long as such
|
||||
parties remain in full compliance.
|
||||
|
||||
5. You are not required to accept this License, since you have not
|
||||
signed it. However, nothing else grants you permission to modify or
|
||||
distribute the Program or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Program (or any work based on the
|
||||
Program), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Program or works based on it.
|
||||
|
||||
6. Each time you redistribute the Program (or any work based on the
|
||||
Program), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute or modify the Program subject to
|
||||
these terms and conditions. You may not impose any further
|
||||
restrictions on the recipients' exercise of the rights granted herein.
|
||||
You are not responsible for enforcing compliance by third parties to
|
||||
this License.
|
||||
|
||||
7. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues),
|
||||
conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot
|
||||
distribute so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you
|
||||
may not distribute the Program at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Program by
|
||||
all those who receive copies directly or indirectly through you, then
|
||||
the only way you could satisfy both it and this License would be to
|
||||
refrain entirely from distribution of the Program.
|
||||
|
||||
If any portion of this section is held invalid or unenforceable under
|
||||
any particular circumstance, the balance of the section is intended to
|
||||
apply and the section as a whole is intended to apply in other
|
||||
circumstances.
|
||||
|
||||
It is not the purpose of this section to induce you to infringe any
|
||||
patents or other property right claims or to contest validity of any
|
||||
such claims; this section has the sole purpose of protecting the
|
||||
integrity of the free software distribution system, which is
|
||||
implemented by public license practices. Many people have made
|
||||
generous contributions to the wide range of software distributed
|
||||
through that system in reliance on consistent application of that
|
||||
system; it is up to the author/donor to decide if he or she is willing
|
||||
to distribute software through any other system and a licensee cannot
|
||||
impose that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
8. If the distribution and/or use of the Program is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Program under this License
|
||||
may add an explicit geographical distribution limitation excluding
|
||||
those countries, so that distribution is permitted only in or among
|
||||
countries not thus excluded. In such case, this License incorporates
|
||||
the limitation as if written in the body of this License.
|
||||
|
||||
9. The Free Software Foundation may publish revised and/or new versions
|
||||
of the General Public License from time to time. Such new versions will
|
||||
be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Program
|
||||
specifies a version number of this License which applies to it and "any
|
||||
later version", you have the option of following the terms and conditions
|
||||
either of that version or of any later version published by the Free
|
||||
Software Foundation. If the Program does not specify a version number of
|
||||
this License, you may choose any version ever published by the Free Software
|
||||
Foundation.
|
||||
|
||||
10. If you wish to incorporate parts of the Program into other free
|
||||
programs whose distribution conditions are different, write to the author
|
||||
to ask for permission. For software which is copyrighted by the Free
|
||||
Software Foundation, write to the Free Software Foundation; we sometimes
|
||||
make exceptions for this. Our decision will be guided by the two goals
|
||||
of preserving the free status of all derivatives of our free software and
|
||||
of promoting the sharing and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
|
||||
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
||||
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
||||
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
|
||||
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
|
||||
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
|
||||
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
|
||||
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
|
||||
REPAIR OR CORRECTION.
|
||||
|
||||
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
|
||||
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
|
||||
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
|
||||
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
|
||||
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
|
||||
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
free software which everyone can redistribute and change under these terms.
|
||||
|
||||
To do so, attach the following notices to the program. It is safest
|
||||
to attach them to the start of each source file to most effectively
|
||||
convey the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program is interactive, make it output a short notice like this
|
||||
when it starts in an interactive mode:
|
||||
|
||||
Gnomovision version 69, Copyright (C) year name of author
|
||||
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
|
||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||
parts of the General Public License. Of course, the commands you use may
|
||||
be called something other than `show w' and `show c'; they could even be
|
||||
mouse-clicks or menu items--whatever suits your program.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or your
|
||||
school, if any, to sign a "copyright disclaimer" for the program, if
|
||||
necessary. Here is a sample; alter the names:
|
||||
|
||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
|
||||
`Gnomovision' (which makes passes at compilers) written by James Hacker.
|
||||
|
||||
<signature of Ty Coon>, 1 April 1989
|
||||
Ty Coon, President of Vice
|
||||
|
||||
This General Public License does not permit incorporating your program into
|
||||
proprietary programs. If your program is a subroutine library, you may
|
||||
consider it more useful to permit linking proprietary applications with the
|
||||
library. If this is what you want to do, use the GNU Library General
|
||||
Public License instead of this License.
|
22
libksane/COPYING-CMAKE-SCRIPTS
Normal file
22
libksane/COPYING-CMAKE-SCRIPTS
Normal file
|
@ -0,0 +1,22 @@
|
|||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
1. Redistributions of source code must retain the copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
2. Redistributions in binary form must reproduce the copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
3. The name of the author may not be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
510
libksane/COPYING.LIB
Normal file
510
libksane/COPYING.LIB
Normal file
|
@ -0,0 +1,510 @@
|
|||
|
||||
GNU LESSER GENERAL PUBLIC LICENSE
|
||||
Version 2.1, February 1999
|
||||
|
||||
Copyright (C) 1991, 1999 Free Software Foundation, Inc.
|
||||
51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
[This is the first released version of the Lesser GPL. It also counts
|
||||
as the successor of the GNU Library Public License, version 2, hence
|
||||
the version number 2.1.]
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
Licenses are intended to guarantee your freedom to share and change
|
||||
free software--to make sure the software is free for all its users.
|
||||
|
||||
This license, the Lesser General Public License, applies to some
|
||||
specially designated software packages--typically libraries--of the
|
||||
Free Software Foundation and other authors who decide to use it. You
|
||||
can use it too, but we suggest you first think carefully about whether
|
||||
this license or the ordinary General Public License is the better
|
||||
strategy to use in any particular case, based on the explanations
|
||||
below.
|
||||
|
||||
When we speak of free software, we are referring to freedom of use,
|
||||
not price. Our General Public Licenses are designed to make sure that
|
||||
you have the freedom to distribute copies of free software (and charge
|
||||
for this service if you wish); that you receive source code or can get
|
||||
it if you want it; that you can change the software and use pieces of
|
||||
it in new free programs; and that you are informed that you can do
|
||||
these things.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid
|
||||
distributors to deny you these rights or to ask you to surrender these
|
||||
rights. These restrictions translate to certain responsibilities for
|
||||
you if you distribute copies of the library or if you modify it.
|
||||
|
||||
For example, if you distribute copies of the library, whether gratis
|
||||
or for a fee, you must give the recipients all the rights that we gave
|
||||
you. You must make sure that they, too, receive or can get the source
|
||||
code. If you link other code with the library, you must provide
|
||||
complete object files to the recipients, so that they can relink them
|
||||
with the library after making changes to the library and recompiling
|
||||
it. And you must show them these terms so they know their rights.
|
||||
|
||||
We protect your rights with a two-step method: (1) we copyright the
|
||||
library, and (2) we offer you this license, which gives you legal
|
||||
permission to copy, distribute and/or modify the library.
|
||||
|
||||
To protect each distributor, we want to make it very clear that
|
||||
there is no warranty for the free library. Also, if the library is
|
||||
modified by someone else and passed on, the recipients should know
|
||||
that what they have is not the original version, so that the original
|
||||
author's reputation will not be affected by problems that might be
|
||||
introduced by others.
|
||||
|
||||
Finally, software patents pose a constant threat to the existence of
|
||||
any free program. We wish to make sure that a company cannot
|
||||
effectively restrict the users of a free program by obtaining a
|
||||
restrictive license from a patent holder. Therefore, we insist that
|
||||
any patent license obtained for a version of the library must be
|
||||
consistent with the full freedom of use specified in this license.
|
||||
|
||||
Most GNU software, including some libraries, is covered by the
|
||||
ordinary GNU General Public License. This license, the GNU Lesser
|
||||
General Public License, applies to certain designated libraries, and
|
||||
is quite different from the ordinary General Public License. We use
|
||||
this license for certain libraries in order to permit linking those
|
||||
libraries into non-free programs.
|
||||
|
||||
When a program is linked with a library, whether statically or using
|
||||
a shared library, the combination of the two is legally speaking a
|
||||
combined work, a derivative of the original library. The ordinary
|
||||
General Public License therefore permits such linking only if the
|
||||
entire combination fits its criteria of freedom. The Lesser General
|
||||
Public License permits more lax criteria for linking other code with
|
||||
the library.
|
||||
|
||||
We call this license the "Lesser" General Public License because it
|
||||
does Less to protect the user's freedom than the ordinary General
|
||||
Public License. It also provides other free software developers Less
|
||||
of an advantage over competing non-free programs. These disadvantages
|
||||
are the reason we use the ordinary General Public License for many
|
||||
libraries. However, the Lesser license provides advantages in certain
|
||||
special circumstances.
|
||||
|
||||
For example, on rare occasions, there may be a special need to
|
||||
encourage the widest possible use of a certain library, so that it
|
||||
becomes a de-facto standard. To achieve this, non-free programs must
|
||||
be allowed to use the library. A more frequent case is that a free
|
||||
library does the same job as widely used non-free libraries. In this
|
||||
case, there is little to gain by limiting the free library to free
|
||||
software only, so we use the Lesser General Public License.
|
||||
|
||||
In other cases, permission to use a particular library in non-free
|
||||
programs enables a greater number of people to use a large body of
|
||||
free software. For example, permission to use the GNU C Library in
|
||||
non-free programs enables many more people to use the whole GNU
|
||||
operating system, as well as its variant, the GNU/Linux operating
|
||||
system.
|
||||
|
||||
Although the Lesser General Public License is Less protective of the
|
||||
users' freedom, it does ensure that the user of a program that is
|
||||
linked with the Library has the freedom and the wherewithal to run
|
||||
that program using a modified version of the Library.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow. Pay close attention to the difference between a
|
||||
"work based on the library" and a "work that uses the library". The
|
||||
former contains code derived from the library, whereas the latter must
|
||||
be combined with the library in order to run.
|
||||
|
||||
GNU LESSER GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License Agreement applies to any software library or other
|
||||
program which contains a notice placed by the copyright holder or
|
||||
other authorized party saying it may be distributed under the terms of
|
||||
this Lesser General Public License (also called "this License").
|
||||
Each licensee is addressed as "you".
|
||||
|
||||
A "library" means a collection of software functions and/or data
|
||||
prepared so as to be conveniently linked with application programs
|
||||
(which use some of those functions and data) to form executables.
|
||||
|
||||
The "Library", below, refers to any such software library or work
|
||||
which has been distributed under these terms. A "work based on the
|
||||
Library" means either the Library or any derivative work under
|
||||
copyright law: that is to say, a work containing the Library or a
|
||||
portion of it, either verbatim or with modifications and/or translated
|
||||
straightforwardly into another language. (Hereinafter, translation is
|
||||
included without limitation in the term "modification".)
|
||||
|
||||
"Source code" for a work means the preferred form of the work for
|
||||
making modifications to it. For a library, complete source code means
|
||||
all the source code for all modules it contains, plus any associated
|
||||
interface definition files, plus the scripts used to control
|
||||
compilation and installation of the library.
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running a program using the Library is not restricted, and output from
|
||||
such a program is covered only if its contents constitute a work based
|
||||
on the Library (independent of the use of the Library in a tool for
|
||||
writing it). Whether that is true depends on what the Library does
|
||||
and what the program that uses the Library does.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Library's
|
||||
complete source code as you receive it, in any medium, provided that
|
||||
you conspicuously and appropriately publish on each copy an
|
||||
appropriate copyright notice and disclaimer of warranty; keep intact
|
||||
all the notices that refer to this License and to the absence of any
|
||||
warranty; and distribute a copy of this License along with the
|
||||
Library.
|
||||
|
||||
You may charge a fee for the physical act of transferring a copy,
|
||||
and you may at your option offer warranty protection in exchange for a
|
||||
fee.
|
||||
|
||||
2. You may modify your copy or copies of the Library or any portion
|
||||
of it, thus forming a work based on the Library, and copy and
|
||||
distribute such modifications or work under the terms of Section 1
|
||||
above, provided that you also meet all of these conditions:
|
||||
|
||||
a) The modified work must itself be a software library.
|
||||
|
||||
b) You must cause the files modified to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
|
||||
c) You must cause the whole of the work to be licensed at no
|
||||
charge to all third parties under the terms of this License.
|
||||
|
||||
d) If a facility in the modified Library refers to a function or a
|
||||
table of data to be supplied by an application program that uses
|
||||
the facility, other than as an argument passed when the facility
|
||||
is invoked, then you must make a good faith effort to ensure that,
|
||||
in the event an application does not supply such function or
|
||||
table, the facility still operates, and performs whatever part of
|
||||
its purpose remains meaningful.
|
||||
|
||||
(For example, a function in a library to compute square roots has
|
||||
a purpose that is entirely well-defined independent of the
|
||||
application. Therefore, Subsection 2d requires that any
|
||||
application-supplied function or table used by this function must
|
||||
be optional: if the application does not supply it, the square
|
||||
root function must still compute square roots.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Library,
|
||||
and can be reasonably considered independent and separate works in
|
||||
themselves, then this License, and its terms, do not apply to those
|
||||
sections when you distribute them as separate works. But when you
|
||||
distribute the same sections as part of a whole which is a work based
|
||||
on the Library, the distribution of the whole must be on the terms of
|
||||
this License, whose permissions for other licensees extend to the
|
||||
entire whole, and thus to each and every part regardless of who wrote
|
||||
it.
|
||||
|
||||
Thus, it is not the intent of this section to claim rights or contest
|
||||
your rights to work written entirely by you; rather, the intent is to
|
||||
exercise the right to control the distribution of derivative or
|
||||
collective works based on the Library.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Library
|
||||
with the Library (or with a work based on the Library) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
3. You may opt to apply the terms of the ordinary GNU General Public
|
||||
License instead of this License to a given copy of the Library. To do
|
||||
this, you must alter all the notices that refer to this License, so
|
||||
that they refer to the ordinary GNU General Public License, version 2,
|
||||
instead of to this License. (If a newer version than version 2 of the
|
||||
ordinary GNU General Public License has appeared, then you can specify
|
||||
that version instead if you wish.) Do not make any other change in
|
||||
these notices.
|
||||
|
||||
Once this change is made in a given copy, it is irreversible for
|
||||
that copy, so the ordinary GNU General Public License applies to all
|
||||
subsequent copies and derivative works made from that copy.
|
||||
|
||||
This option is useful when you wish to copy part of the code of
|
||||
the Library into a program that is not a library.
|
||||
|
||||
4. You may copy and distribute the Library (or a portion or
|
||||
derivative of it, under Section 2) in object code or executable form
|
||||
under the terms of Sections 1 and 2 above provided that you accompany
|
||||
it with the complete corresponding machine-readable source code, which
|
||||
must be distributed under the terms of Sections 1 and 2 above on a
|
||||
medium customarily used for software interchange.
|
||||
|
||||
If distribution of object code is made by offering access to copy
|
||||
from a designated place, then offering equivalent access to copy the
|
||||
source code from the same place satisfies the requirement to
|
||||
distribute the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
5. A program that contains no derivative of any portion of the
|
||||
Library, but is designed to work with the Library by being compiled or
|
||||
linked with it, is called a "work that uses the Library". Such a
|
||||
work, in isolation, is not a derivative work of the Library, and
|
||||
therefore falls outside the scope of this License.
|
||||
|
||||
However, linking a "work that uses the Library" with the Library
|
||||
creates an executable that is a derivative of the Library (because it
|
||||
contains portions of the Library), rather than a "work that uses the
|
||||
library". The executable is therefore covered by this License.
|
||||
Section 6 states terms for distribution of such executables.
|
||||
|
||||
When a "work that uses the Library" uses material from a header file
|
||||
that is part of the Library, the object code for the work may be a
|
||||
derivative work of the Library even though the source code is not.
|
||||
Whether this is true is especially significant if the work can be
|
||||
linked without the Library, or if the work is itself a library. The
|
||||
threshold for this to be true is not precisely defined by law.
|
||||
|
||||
If such an object file uses only numerical parameters, data
|
||||
structure layouts and accessors, and small macros and small inline
|
||||
functions (ten lines or less in length), then the use of the object
|
||||
file is unrestricted, regardless of whether it is legally a derivative
|
||||
work. (Executables containing this object code plus portions of the
|
||||
Library will still fall under Section 6.)
|
||||
|
||||
Otherwise, if the work is a derivative of the Library, you may
|
||||
distribute the object code for the work under the terms of Section 6.
|
||||
Any executables containing that work also fall under Section 6,
|
||||
whether or not they are linked directly with the Library itself.
|
||||
|
||||
6. As an exception to the Sections above, you may also combine or
|
||||
link a "work that uses the Library" with the Library to produce a
|
||||
work containing portions of the Library, and distribute that work
|
||||
under terms of your choice, provided that the terms permit
|
||||
modification of the work for the customer's own use and reverse
|
||||
engineering for debugging such modifications.
|
||||
|
||||
You must give prominent notice with each copy of the work that the
|
||||
Library is used in it and that the Library and its use are covered by
|
||||
this License. You must supply a copy of this License. If the work
|
||||
during execution displays copyright notices, you must include the
|
||||
copyright notice for the Library among them, as well as a reference
|
||||
directing the user to the copy of this License. Also, you must do one
|
||||
of these things:
|
||||
|
||||
a) Accompany the work with the complete corresponding
|
||||
machine-readable source code for the Library including whatever
|
||||
changes were used in the work (which must be distributed under
|
||||
Sections 1 and 2 above); and, if the work is an executable linked
|
||||
with the Library, with the complete machine-readable "work that
|
||||
uses the Library", as object code and/or source code, so that the
|
||||
user can modify the Library and then relink to produce a modified
|
||||
executable containing the modified Library. (It is understood
|
||||
that the user who changes the contents of definitions files in the
|
||||
Library will not necessarily be able to recompile the application
|
||||
to use the modified definitions.)
|
||||
|
||||
b) Use a suitable shared library mechanism for linking with the
|
||||
Library. A suitable mechanism is one that (1) uses at run time a
|
||||
copy of the library already present on the user's computer system,
|
||||
rather than copying library functions into the executable, and (2)
|
||||
will operate properly with a modified version of the library, if
|
||||
the user installs one, as long as the modified version is
|
||||
interface-compatible with the version that the work was made with.
|
||||
|
||||
c) Accompany the work with a written offer, valid for at least
|
||||
three years, to give the same user the materials specified in
|
||||
Subsection 6a, above, for a charge no more than the cost of
|
||||
performing this distribution.
|
||||
|
||||
d) If distribution of the work is made by offering access to copy
|
||||
from a designated place, offer equivalent access to copy the above
|
||||
specified materials from the same place.
|
||||
|
||||
e) Verify that the user has already received a copy of these
|
||||
materials or that you have already sent this user a copy.
|
||||
|
||||
For an executable, the required form of the "work that uses the
|
||||
Library" must include any data and utility programs needed for
|
||||
reproducing the executable from it. However, as a special exception,
|
||||
the materials to be distributed need not include anything that is
|
||||
normally distributed (in either source or binary form) with the major
|
||||
components (compiler, kernel, and so on) of the operating system on
|
||||
which the executable runs, unless that component itself accompanies
|
||||
the executable.
|
||||
|
||||
It may happen that this requirement contradicts the license
|
||||
restrictions of other proprietary libraries that do not normally
|
||||
accompany the operating system. Such a contradiction means you cannot
|
||||
use both them and the Library together in an executable that you
|
||||
distribute.
|
||||
|
||||
7. You may place library facilities that are a work based on the
|
||||
Library side-by-side in a single library together with other library
|
||||
facilities not covered by this License, and distribute such a combined
|
||||
library, provided that the separate distribution of the work based on
|
||||
the Library and of the other library facilities is otherwise
|
||||
permitted, and provided that you do these two things:
|
||||
|
||||
a) Accompany the combined library with a copy of the same work
|
||||
based on the Library, uncombined with any other library
|
||||
facilities. This must be distributed under the terms of the
|
||||
Sections above.
|
||||
|
||||
b) Give prominent notice with the combined library of the fact
|
||||
that part of it is a work based on the Library, and explaining
|
||||
where to find the accompanying uncombined form of the same work.
|
||||
|
||||
8. You may not copy, modify, sublicense, link with, or distribute
|
||||
the Library except as expressly provided under this License. Any
|
||||
attempt otherwise to copy, modify, sublicense, link with, or
|
||||
distribute the Library is void, and will automatically terminate your
|
||||
rights under this License. However, parties who have received copies,
|
||||
or rights, from you under this License will not have their licenses
|
||||
terminated so long as such parties remain in full compliance.
|
||||
|
||||
9. You are not required to accept this License, since you have not
|
||||
signed it. However, nothing else grants you permission to modify or
|
||||
distribute the Library or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Library (or any work based on the
|
||||
Library), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Library or works based on it.
|
||||
|
||||
10. Each time you redistribute the Library (or any work based on the
|
||||
Library), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute, link with or modify the Library
|
||||
subject to these terms and conditions. You may not impose any further
|
||||
restrictions on the recipients' exercise of the rights granted herein.
|
||||
You are not responsible for enforcing compliance by third parties with
|
||||
this License.
|
||||
|
||||
11. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues),
|
||||
conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot
|
||||
distribute so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you
|
||||
may not distribute the Library at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Library by
|
||||
all those who receive copies directly or indirectly through you, then
|
||||
the only way you could satisfy both it and this License would be to
|
||||
refrain entirely from distribution of the Library.
|
||||
|
||||
If any portion of this section is held invalid or unenforceable under
|
||||
any particular circumstance, the balance of the section is intended to
|
||||
apply, and the section as a whole is intended to apply in other
|
||||
circumstances.
|
||||
|
||||
It is not the purpose of this section to induce you to infringe any
|
||||
patents or other property right claims or to contest validity of any
|
||||
such claims; this section has the sole purpose of protecting the
|
||||
integrity of the free software distribution system which is
|
||||
implemented by public license practices. Many people have made
|
||||
generous contributions to the wide range of software distributed
|
||||
through that system in reliance on consistent application of that
|
||||
system; it is up to the author/donor to decide if he or she is willing
|
||||
to distribute software through any other system and a licensee cannot
|
||||
impose that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
12. If the distribution and/or use of the Library is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Library under this License
|
||||
may add an explicit geographical distribution limitation excluding those
|
||||
countries, so that distribution is permitted only in or among
|
||||
countries not thus excluded. In such case, this License incorporates
|
||||
the limitation as if written in the body of this License.
|
||||
|
||||
13. The Free Software Foundation may publish revised and/or new
|
||||
versions of the Lesser General Public License from time to time.
|
||||
Such new versions will be similar in spirit to the present version,
|
||||
but may differ in detail to address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Library
|
||||
specifies a version number of this License which applies to it and
|
||||
"any later version", you have the option of following the terms and
|
||||
conditions either of that version or of any later version published by
|
||||
the Free Software Foundation. If the Library does not specify a
|
||||
license version number, you may choose any version ever published by
|
||||
the Free Software Foundation.
|
||||
|
||||
14. If you wish to incorporate parts of the Library into other free
|
||||
programs whose distribution conditions are incompatible with these,
|
||||
write to the author to ask for permission. For software which is
|
||||
copyrighted by the Free Software Foundation, write to the Free
|
||||
Software Foundation; we sometimes make exceptions for this. Our
|
||||
decision will be guided by the two goals of preserving the free status
|
||||
of all derivatives of our free software and of promoting the sharing
|
||||
and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
|
||||
15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
|
||||
WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
|
||||
EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
|
||||
OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
|
||||
KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
|
||||
LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
|
||||
THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||
|
||||
16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
|
||||
WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
|
||||
AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
|
||||
FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
|
||||
CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
|
||||
LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
|
||||
RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
|
||||
FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
|
||||
SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
|
||||
DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Libraries
|
||||
|
||||
If you develop a new library, and you want it to be of the greatest
|
||||
possible use to the public, we recommend making it free software that
|
||||
everyone can redistribute and change. You can do so by permitting
|
||||
redistribution under these terms (or, alternatively, under the terms
|
||||
of the ordinary General Public License).
|
||||
|
||||
To apply these terms, attach the following notices to the library.
|
||||
It is safest to attach them to the start of each source file to most
|
||||
effectively convey the exclusion of warranty; and each file should
|
||||
have at least the "copyright" line and a pointer to where the full
|
||||
notice is found.
|
||||
|
||||
|
||||
<one line to give the library's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or
|
||||
your school, if any, to sign a "copyright disclaimer" for the library,
|
||||
if necessary. Here is a sample; alter the names:
|
||||
|
||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the
|
||||
library `Frob' (a library for tweaking knobs) written by James
|
||||
Random Hacker.
|
||||
|
||||
<signature of Ty Coon>, 1 April 1990
|
||||
Ty Coon, President of Vice
|
||||
|
||||
That's all there is to it!
|
||||
|
||||
|
33
libksane/COPYING.twain
Normal file
33
libksane/COPYING.twain
Normal file
|
@ -0,0 +1,33 @@
|
|||
The file twain.h may be copied under the TWAIN License as specified at
|
||||
http://www.twain.org/license.shtm
|
||||
|
||||
The TWAIN License
|
||||
|
||||
The TWAIN Working Group grants customer ("Customer") the worldwide,
|
||||
royalty-free, non-exclusive license to reproduce and distribute the
|
||||
software and documentation of the TWAIN toolkit ("TWAIN Toolkit"). The
|
||||
TWAIN Toolkit was designed to be used by third parties to assist them
|
||||
in becoming compliant with the TWAIN standard, but it has not been
|
||||
developed to the standards of a commercial product. Consequently, the
|
||||
TWAIN toolkit is provided AS IS without any warranty. THE TWAIN
|
||||
Working Group disclaims all warranties in the TWAIN toolkit whether
|
||||
implied, express or statutory, including, without limitation, the
|
||||
implied warranties of merchantability, noninfringement of third party
|
||||
rights and fitness for a particular purpose. The TWAIN Working Group
|
||||
disclaims all liability for damages, whether direct, indirect,
|
||||
special, incidental, or consequential, arising from the reproduction,
|
||||
distribution, modification, or other use of the TWAIN Toolkit.
|
||||
|
||||
As a condition of this license, Customer agrees to include in software
|
||||
programs based in whole or in part on the TWAIN Toolkit the following
|
||||
providions in (i) the header or similar file in such software and (ii)
|
||||
prominently in its documentation and to require its sublicensees to
|
||||
include these provisions in similar locations: The TWAIN Toolkit is
|
||||
distributed as is. The developer and distributors of the TWAIN Toolkit
|
||||
expressly disclaim all implied, express or statutory warranties
|
||||
including, without limitation, the implied warranties of
|
||||
merchantability, noninfringement of third party rights and fitness for
|
||||
a particular purpose. Neither the developers nor the distributors will
|
||||
be liable for damages, whether direct, indirect, special, incidental,
|
||||
or consequential, as a result of the reproduction, modification,
|
||||
distribution or other use of the TWAIN Toolkit.
|
12
libksane/ChangeLog
Normal file
12
libksane/ChangeLog
Normal file
|
@ -0,0 +1,12 @@
|
|||
0.1.2
|
||||
|
||||
- Add support for button parameters
|
||||
- Move the progress bar so that it is more visible during scan
|
||||
|
||||
0.1.1
|
||||
|
||||
- Add toQImage() for a nicer API
|
||||
|
||||
0.1.0
|
||||
|
||||
- Initial release
|
5
libksane/NEWS
Normal file
5
libksane/NEWS
Normal file
|
@ -0,0 +1,5 @@
|
|||
0.1.0
|
||||
------------------------------------------------------------------------
|
||||
First implementation
|
||||
|
||||
For details and info about previous versions, see ChangeLog.
|
72
libksane/README
Normal file
72
libksane/README
Normal file
|
@ -0,0 +1,72 @@
|
|||
SANE Library interface for KDE
|
||||
|
||||
This library is a part of Kipi-Plugins project (http://www.digikam.org)
|
||||
|
||||
-- AUTHORS ------------------------------------------------------------
|
||||
|
||||
See AUTHORS file for details.
|
||||
|
||||
-- ABOUT --------------------------------------------------------------
|
||||
|
||||
Libksane is a KDE interface for SANE library to control flat scanners.
|
||||
|
||||
This library is used by kipi-plugins, digiKam and others kipi host programs.
|
||||
|
||||
The library documentation is available on header files.
|
||||
|
||||
-- DEPENDENCIES -------------------------------------------------------
|
||||
|
||||
CMake >= 2.4.x http://www.cmake.org
|
||||
libqt >= 4.2.x http://www.qtsoftware.com
|
||||
libkde >= 4.0.x http://www.kde.org
|
||||
libsane >= 1.0.18 http://www.sane-project.org
|
||||
|
||||
-- INSTALL ------------------------------------------------------------
|
||||
|
||||
In order to compile, especially when QT3/Qt4 are installed at the same time,
|
||||
just use something like that:
|
||||
|
||||
# export VERBOSE=1
|
||||
# export QTDIR=/usr/lib/qt4/
|
||||
# export PATH=$QTDIR/bin:$PATH
|
||||
# cmake .
|
||||
# make
|
||||
|
||||
Usual CMake options:
|
||||
|
||||
-DCMAKE_INSTALL_PREFIX : decide where the program will be install on your computer.
|
||||
-DCMAKE_BUILD_TYPE : decide which type of build you want. You can chose between "debugfull", "debug", "profile", "relwithdebinfo" and "release". The default is "relwithdebinfo" (-O2 -g).
|
||||
|
||||
Compared to old KDE3 autoconf options:
|
||||
|
||||
"cmake . -DCMAKE_BUILD_TYPE=debugfull" is equivalent to "./configure --enable-debug=full"
|
||||
"cmake . -DCMAKE_INSTALL_PREFIX=/usr" is equivalent to "./configure --prefix=/usr"
|
||||
|
||||
More details can be found ata this url: http://techbase.kde.org/Development/Tutorials/CMake#Environment_Variables
|
||||
|
||||
Note: To know KDE install path on your computer, use 'kde-config --prefix' command line like this (with full debug object enabled):
|
||||
|
||||
"cmake . -DCMAKE_BUILD_TYPE=debugfull -DCMAKE_INSTALL_PREFIX=`kde4-config --prefix`"
|
||||
|
||||
-- CONTACT ------------------------------------------------------------
|
||||
|
||||
If you have questions, comments, suggestions to make do email at:
|
||||
|
||||
kde-imaging@kde.org
|
||||
|
||||
IRC channel from freenode.net server:
|
||||
|
||||
#kde-imaging
|
||||
|
||||
-- BUGS ---------------------------------------------------------------
|
||||
|
||||
IMPORTANT : the bugreports and wishlist are hosted by the KDE bugs report
|
||||
system who can be contacted by the standard Kde help menu of plugins dialog.
|
||||
A mail will be automatically sent to the Kipi mailing list.
|
||||
There is no need to contact directly the Kipi mailing list for a bug report
|
||||
or a devel wish.
|
||||
|
||||
The current Kipi bugs and devel wish reported to the Kde bugs report can be see
|
||||
at this url :
|
||||
|
||||
http://bugs.kde.org/buglist.cgi?product=kipiplugins&component=libksane&bug_status=UNCONFIRMED&bug_status=NEW&bug_status=ASSIGNED&bug_status=REOPENED
|
49
libksane/TODO
Normal file
49
libksane/TODO
Normal file
|
@ -0,0 +1,49 @@
|
|||
TODO list of new features:
|
||||
|
||||
* Cleanup the code for closing the device
|
||||
* Progressive final scan: scan can provide huge image especially in 16 bits color depth.
|
||||
Send image data to host application by block, not the whole image at once.
|
||||
|
||||
|
||||
|
||||
# KSaneCore (most signals/slots from KSaneWidget)
|
||||
QList<KSaneOption*> options() const // handles to sane options
|
||||
KSaneBasicOptions* createBasicOptions(QWidget *parent=0) const // A widget with current "basic options"
|
||||
KSaneSpecialOptions* createSpecialOptions(QWidget *parent=0) const // A widget with the rest of the options
|
||||
void signalPreviewUpdated(QImage *img);
|
||||
|
||||
KSaneCore never displays popups and always emits userMessage like signals for user information
|
||||
|
||||
|
||||
# KSaneOption
|
||||
virtual QWidget* createWidget(QWidget* parent=0) const; // Create a KSaneOptionWidget and connect it to the option
|
||||
QString saneName() const; // Technical name of the sane option
|
||||
QString title() const; // Translated option title
|
||||
QString description() const; // Translated option description
|
||||
|
||||
Cleanup public API
|
||||
|
||||
# KSaneOptionWidget
|
||||
Remove label and custom label size code
|
||||
|
||||
# KSaneBasicOptions(QWidget *parent=0) // Use private header for basic/Special selection
|
||||
bool loadOptions(const QList<KSaneOption*> &options)
|
||||
|
||||
# KSaneSpecialOptions(QWidget *parent=0) // Use private header for basic/Special selection
|
||||
bool loadOptions(const QList<KSaneOption*> &options)
|
||||
|
||||
# KSanePreview
|
||||
Figure out how to minimize copying the image data to all possible preview widgets
|
||||
void "connectToCore"(KSaneCore*) // connect to previewUpdated(..), scanProgress(), ...
|
||||
|
||||
# KSaneWidget
|
||||
Use KSaneCore + KSaneBasicOptions + KSaneSpecialOptions + KSanePreview to create a GUI like the current
|
||||
Forward userMessage signals if connected or popup a dialog
|
||||
|
||||
|
||||
#General cleanup:
|
||||
-> enum xxx { }; for easier signal/slot handling
|
||||
float -> qreal
|
||||
|
||||
# Pure Qt library option?
|
||||
|
10
libksane/cmake/templates/KSaneConfig.cmake.in
Normal file
10
libksane/cmake/templates/KSaneConfig.cmake.in
Normal file
|
@ -0,0 +1,10 @@
|
|||
GET_FILENAME_COMPONENT(_IMPORT_PREFIX "${CMAKE_CURRENT_LIST_FILE}" PATH)
|
||||
GET_FILENAME_COMPONENT(_IMPORT_PREFIX "${_IMPORT_PREFIX}" PATH)
|
||||
GET_FILENAME_COMPONENT(_IMPORT_PREFIX "${_IMPORT_PREFIX}" PATH)
|
||||
GET_FILENAME_COMPONENT(_IMPORT_PREFIX "${_IMPORT_PREFIX}" PATH)
|
||||
|
||||
find_library(KSANE_LIBRARY NAMES ksane HINTS ${_IMPORT_PREFIX}/lib NO_DEFAULT_PATH)
|
||||
find_path(KSANE_INCLUDE_DIR NAMES libksane/ksane.h HINTS ${_IMPORT_PREFIX}/include NO_DEFAULT_PATH)
|
||||
SET(KSANE_LIBRARY "${KSANE_LIBRARY}" CACHE FILEPATH "KSane image scanning library")
|
||||
SET(KSANE_INCLUDE_DIR "${KSANE_INCLUDE_DIR}" CACHE PATH "Include path for KSane library")
|
||||
SET(KSANE_FOUND TRUE)
|
15
libksane/cmake/templates/libksane.lsm.cmake.in
Normal file
15
libksane/cmake/templates/libksane.lsm.cmake.in
Normal file
|
@ -0,0 +1,15 @@
|
|||
Begin4
|
||||
Title: libksane
|
||||
Version: ${KSANE_LIB_VERSION_STRING}
|
||||
Entered-date: 2007-09-13
|
||||
Description: libksane is a C++ library for SANE interface to control flat scanners.
|
||||
Keywords: kde image sane scanner digiKam kipi-plugins
|
||||
Author: caulier dot gilles at gmail dot com (Gilles Caulier)
|
||||
kare dot sars at iki dot fi (Kare Sars)
|
||||
Maintained-by:
|
||||
Primary-site: http://www.digikam.org
|
||||
Alternate-site: http://www.digikam.org
|
||||
Original-site:
|
||||
Platforms:
|
||||
Copying-policy: LGPL
|
||||
End
|
12
libksane/cmake/templates/libksane.pc.cmake.in
Normal file
12
libksane/cmake/templates/libksane.pc.cmake.in
Normal file
|
@ -0,0 +1,12 @@
|
|||
prefix=${CMAKE_INSTALL_PREFIX}
|
||||
exec_prefix=${BIN_INSTALL_DIR}
|
||||
libdir=${LIB_INSTALL_DIR}
|
||||
includedir=${INCLUDE_INSTALL_DIR}
|
||||
|
||||
Name: libksane
|
||||
Description: libksane is a C++ library for SANE interface to control flat scanners.
|
||||
URL: http://www.digikam.org
|
||||
Requires:
|
||||
Version: ${KSANE_LIB_VERSION_STRING}
|
||||
Libs: -L${LIB_INSTALL_DIR} -lksane
|
||||
Cflags: -I${INCLUDE_INSTALL_DIR}
|
35
libksane/ksanetwain/CMakeLists.txt
Normal file
35
libksane/ksanetwain/CMakeLists.txt
Normal file
|
@ -0,0 +1,35 @@
|
|||
CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/../libksane/version.h.cmake.in ${CMAKE_CURRENT_BINARY_DIR}/version.h)
|
||||
|
||||
INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/../libksane
|
||||
${CMAKE_CURRENT_BINARY_DIR})
|
||||
|
||||
IF( WIN32 )
|
||||
ADD_DEFINITIONS( -DMAKE_KSANE_LIB )
|
||||
ENDIF()
|
||||
|
||||
set(ktwain_src
|
||||
twainiface.cpp
|
||||
ktwain_widget.cpp
|
||||
)
|
||||
|
||||
KDE4_ADD_LIBRARY(ksane SHARED ${ktwain_src})
|
||||
|
||||
TARGET_LINK_LIBRARIES(ksane ${KDE4_KDEUI_LIBS})
|
||||
|
||||
SET_TARGET_PROPERTIES(ksane PROPERTIES
|
||||
VERSION ${KSANE_LIB_SO_VERSION_STRING}
|
||||
SOVERSION ${KSANE_LIB_SO_CUR_VERSION}
|
||||
LINK_FLAGS -Wl,-subsystem,console
|
||||
)
|
||||
|
||||
install(TARGETS ksane ${INSTALL_TARGETS_DEFAULT_ARGS} )
|
||||
|
||||
INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/../libksane/ksane.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../libksane/libksane_export.h
|
||||
${CMAKE_CURRENT_BINARY_DIR}/version.h
|
||||
DESTINATION ${INCLUDE_INSTALL_DIR}/libksane COMPONENT Devel)
|
||||
|
||||
configure_file(../cmake/templates/KSaneConfig.cmake.in ${CMAKE_CURRENT_BINARY_DIR}/KSaneConfig.cmake @ONLY)
|
||||
|
||||
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/KSaneConfig.cmake
|
||||
DESTINATION ${LIB_INSTALL_DIR}/cmake/KSane)
|
149
libksane/ksanetwain/ktwain_widget.cpp
Normal file
149
libksane/ksanetwain/ktwain_widget.cpp
Normal file
|
@ -0,0 +1,149 @@
|
|||
/* ============================================================
|
||||
*
|
||||
* This file is part of the KDE project
|
||||
*
|
||||
* Date : 2009-05-11
|
||||
* Description : Sane interface for KDE
|
||||
*
|
||||
* Copyright (C) 2009 by Kare Sars <kare dot sars at iki dot fi>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) version 3, or any
|
||||
* later version accepted by the membership of KDE e.V. (or its
|
||||
* successor approved by the membership of KDE e.V.), which shall
|
||||
* act as a proxy defined in Section 6 of version 3 of the license.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* ============================================================ */
|
||||
|
||||
#include "../libksane/ksane.h"
|
||||
#include "../libksane/ksane.moc"
|
||||
|
||||
// Qt includes
|
||||
#include <QMap>
|
||||
#include <QHBoxLayout>
|
||||
#include <QTimer>
|
||||
#include <QDebug>
|
||||
|
||||
// KDE includes
|
||||
#include <klocalizedstring.h>
|
||||
#include <kpushbutton.h>
|
||||
|
||||
// Local includes
|
||||
#include "twainiface.h"
|
||||
|
||||
namespace KSaneIface
|
||||
{
|
||||
|
||||
|
||||
KSaneWidget::KSaneWidget(QWidget* parent)
|
||||
: QWidget(parent), d(new KSaneWidgetPrivate)
|
||||
{
|
||||
KPushButton *openDialog = new KPushButton;
|
||||
openDialog->setText(i18n("Open scan dialog"));
|
||||
QHBoxLayout *lay = new QHBoxLayout;
|
||||
lay->addWidget(openDialog);
|
||||
setLayout(lay);
|
||||
|
||||
connect(openDialog, SIGNAL(clicked()), d, SLOT(ReOpenDialog()));
|
||||
|
||||
// Forward signals from the private class
|
||||
//connect(d, SIGNAL(scanProgress(int)), this, SIGNAL(scanProgress(int)));
|
||||
connect(d, SIGNAL(ImageReady(QByteArray&,int,int,int,int)),
|
||||
this, SIGNAL(imageReady(QByteArray&,int,int,int,int)));
|
||||
//connect(d, SIGNAL(scanDone(int,QString)), this, SIGNAL(scanDone(int,QString)));
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
KSaneWidget::~KSaneWidget()
|
||||
{
|
||||
delete d;
|
||||
}
|
||||
|
||||
QString KSaneWidget::selectDevice(QWidget* parent)
|
||||
{
|
||||
//qDebug() << "KSaneWidget::selectDevice";
|
||||
return d->SelectSource();
|
||||
}
|
||||
|
||||
bool KSaneWidget::openDevice(const QString &device_name)
|
||||
{
|
||||
//qDebug() << "KSaneWidget::openDevice" << device_name;
|
||||
if (!d->OpenSource(device_name)) return false;
|
||||
QTimer::singleShot(0, d, SLOT(OpenDialog()));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool KSaneWidget::closeDevice()
|
||||
{
|
||||
//qDebug() << "KSaneWidget::closeDevice";
|
||||
d->CloseDSM();
|
||||
return true;
|
||||
}
|
||||
|
||||
QImage KSaneWidget::toQImage(const QByteArray &data,
|
||||
int width,
|
||||
int height,
|
||||
int bytes_per_line,
|
||||
ImageFormat format)
|
||||
{
|
||||
QImage img = QImage::fromData(data, "BMP");
|
||||
return img;
|
||||
}
|
||||
|
||||
QImage KSaneWidget::toQImageSilent(const QByteArray &data,
|
||||
int width,
|
||||
int height,
|
||||
int bytes_per_line,
|
||||
ImageFormat format)
|
||||
{
|
||||
return KSaneWidget::toQImage(data,
|
||||
width,
|
||||
height,
|
||||
bytes_per_line,
|
||||
format);
|
||||
}
|
||||
|
||||
|
||||
void KSaneWidget::scanFinal()
|
||||
{
|
||||
}
|
||||
|
||||
void KSaneWidget::scanCancel()
|
||||
{
|
||||
emit scanProgress(0);
|
||||
}
|
||||
|
||||
// stubbed functions that will not get an implementation any time soon.
|
||||
QString KSaneWidget::vendor() const {return QString();}
|
||||
QString KSaneWidget::make() const {return QString();}
|
||||
QString KSaneWidget::model() const {return QString();}
|
||||
void KSaneWidget::getOptVals(QMap <QString, QString> &opts) {opts.clear();}
|
||||
bool KSaneWidget::getOptVal(const QString &optname, QString &value){return false;}
|
||||
int KSaneWidget::setOptVals(const QMap <QString, QString> &opts) {return 0;}
|
||||
bool KSaneWidget::setOptVal(const QString &option, const QString &value) {return false;}
|
||||
void KSaneWidget::setScanButtonText(const QString &scanLabel) {}
|
||||
void KSaneWidget::setPreviewButtonText(const QString &previewLabel) {}
|
||||
void KSaneWidget::enableAutoSelect(bool enable) {}
|
||||
float KSaneWidget::currentDPI() {return 0.0;}
|
||||
void KSaneWidget::setPreviewResolution(float dpi){Q_UNUSED(dpi);}
|
||||
void KSaneWidget::setSelection(QPointF lefttop, QPointF rightbottom){Q_UNUSED(lefttop); Q_UNUSED(rightbottom);}
|
||||
void KSaneWidget::setOptionsCollapsed(bool){}
|
||||
void KSaneWidget::setScanButtonHidden(bool){}
|
||||
void KSaneWidget::initGetDeviceList() const {}
|
||||
|
||||
|
||||
} // NameSpace KSaneIface
|
1977
libksane/ksanetwain/twain.h
Normal file
1977
libksane/ksanetwain/twain.h
Normal file
File diff suppressed because it is too large
Load diff
595
libksane/ksanetwain/twainiface.cpp
Normal file
595
libksane/ksanetwain/twainiface.cpp
Normal file
|
@ -0,0 +1,595 @@
|
|||
/* ============================================================
|
||||
*
|
||||
* This file is a part of kdegraphics
|
||||
*
|
||||
* Date : 2009-05-12
|
||||
* Description : Twain interface
|
||||
*
|
||||
* Copyright (C) 2002-2003 Stephan Stapel <stephan dot stapel at web dot de>
|
||||
* Copyright (C) 2008-2009 by Gilles Caulier <caulier dot gilles at gmail dot com>
|
||||
* Copyright (C) 2009 by Kare Sars <kare dot sars at iki dot fi>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) version 3, or any
|
||||
* later version accepted by the membership of KDE e.V. (or its
|
||||
* successor approved by the membership of KDE e.V.), which shall
|
||||
* act as a proxy defined in Section 6 of version 3 of the license.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* ============================================================ */
|
||||
|
||||
// I renamed the class to KSaneWidgetPrivate to remove
|
||||
// the need for a wrapper class with this name. (Kare)
|
||||
|
||||
#include "twainiface.moc"
|
||||
#include "ksane.h"
|
||||
|
||||
#define TWCPP_ANYCOUNT (-1)
|
||||
#define TWCPP_CANCELTHIS (1)
|
||||
#define TWCPP_CANCELALL (2)
|
||||
#define TWCPP_DOTRANSFER (0)
|
||||
|
||||
#include <QtGlobal>
|
||||
#include <QDebug>
|
||||
|
||||
#include <cstring>
|
||||
|
||||
namespace KSaneIface
|
||||
{
|
||||
|
||||
KSaneWidgetPrivate::KSaneWidgetPrivate(): QWidget(0)
|
||||
{
|
||||
// This is a dumy widget not visible. We use Qwidget to dispatch Windows event to
|
||||
// Twain interface. This is not possible to do it using QObject as well.
|
||||
|
||||
m_hMessageWnd = 0;
|
||||
m_hTwainDLL = NULL;
|
||||
m_pDSMProc = NULL;
|
||||
m_bDSOpen = false;
|
||||
m_bDSMOpen = false;
|
||||
m_bSourceEnabled = false;
|
||||
m_bModalUI = true;
|
||||
m_nImageCount = TWCPP_ANYCOUNT;
|
||||
|
||||
InitTwain();
|
||||
}
|
||||
|
||||
KSaneWidgetPrivate::~KSaneWidgetPrivate()
|
||||
{
|
||||
ReleaseTwain();
|
||||
}
|
||||
|
||||
bool KSaneWidgetPrivate::winEvent(MSG* pMsg, long* result)
|
||||
{
|
||||
return ProcessMessage(*pMsg);
|
||||
}
|
||||
|
||||
/** Initializes TWAIN interface . Is already called from the constructor.
|
||||
It should be called again if ReleaseTwain is called.
|
||||
hWnd is the window which has to subclassed in order to receive
|
||||
Twain messaged. Normally - this would be your main application window.
|
||||
*/
|
||||
bool KSaneWidgetPrivate::InitTwain()
|
||||
{
|
||||
char libName[512];
|
||||
|
||||
if((m_hTwainDLL && m_pDSMProc)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
memset(&m_AppId,0,sizeof(m_AppId));
|
||||
|
||||
if(!IsWindow(this->winId())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
m_hMessageWnd = this->winId();
|
||||
strcpy(libName, "TWAIN_32.DLL");
|
||||
|
||||
m_hTwainDLL = LoadLibraryA(libName);
|
||||
if(m_hTwainDLL != NULL)
|
||||
{
|
||||
if(!(m_pDSMProc = (DSMENTRYPROC)GetProcAddress(m_hTwainDLL, (LPCSTR)MAKEINTRESOURCE(1))))
|
||||
{
|
||||
FreeLibrary(m_hTwainDLL);
|
||||
m_hTwainDLL = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if((m_hTwainDLL && m_pDSMProc))
|
||||
{
|
||||
// Expects all the fields in m_AppId to be set except for the id field.
|
||||
m_AppId.Id = 0; // Initialize to 0 (Source Manager will assign real value)
|
||||
m_AppId.Version.MajorNum = 0; // Your app's version number
|
||||
m_AppId.Version.MinorNum = 2;
|
||||
m_AppId.Version.Language = TWLG_USA;
|
||||
m_AppId.Version.Country = TWCY_USA;
|
||||
strcpy(m_AppId.Version.Info, "libksane");
|
||||
|
||||
m_AppId.ProtocolMajor = TWON_PROTOCOLMAJOR;
|
||||
m_AppId.ProtocolMinor = TWON_PROTOCOLMINOR;
|
||||
m_AppId.SupportedGroups = DG_IMAGE | DG_CONTROL;
|
||||
strcpy(m_AppId.Manufacturer, "KDE");
|
||||
strcpy(m_AppId.ProductFamily, "Generic");
|
||||
strcpy(m_AppId.ProductName, "libksane");
|
||||
|
||||
m_bDSMOpen= CallTwainProc(&m_AppId, NULL, DG_CONTROL,
|
||||
DAT_PARENT, MSG_OPENDSM, (TW_MEMREF)&m_hMessageWnd);
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/** Releases the twain interface . Need not be called unless you
|
||||
want to specifically shut it down.
|
||||
*/
|
||||
void KSaneWidgetPrivate::ReleaseTwain()
|
||||
{
|
||||
if((m_hTwainDLL && m_pDSMProc))
|
||||
{
|
||||
CloseDSM();
|
||||
FreeLibrary(m_hTwainDLL);
|
||||
m_hTwainDLL = NULL;
|
||||
m_pDSMProc = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/** Entry point into Twain. For a complete description of this
|
||||
routine please refer to the Twain specification 1.8
|
||||
*/
|
||||
bool KSaneWidgetPrivate::CallTwainProc(pTW_IDENTITY pOrigin, pTW_IDENTITY pDest,
|
||||
TW_UINT32 DG, TW_UINT16 DAT, TW_UINT16 MSG, TW_MEMREF pData)
|
||||
{
|
||||
if (!(m_hTwainDLL && m_pDSMProc)) {
|
||||
m_returnCode = TWRC_FAILURE;
|
||||
return false;
|
||||
}
|
||||
|
||||
m_returnCode = (*m_pDSMProc)(pOrigin, pDest, DG, DAT, MSG, pData);
|
||||
|
||||
if(m_returnCode == TWRC_FAILURE) {
|
||||
(*m_pDSMProc)(pOrigin, pDest, DG_CONTROL, DAT_STATUS, MSG_GET, &m_Status);
|
||||
}
|
||||
return (m_returnCode == TWRC_SUCCESS);
|
||||
}
|
||||
|
||||
/** Called to display a dialog box to select the Twain source to use.
|
||||
This can be overridden if a list of all sources is available
|
||||
to the application. These sources can be enumerated by Twain.
|
||||
it is not yet supportted by KSaneWidgetPrivate.
|
||||
*/
|
||||
QString KSaneWidgetPrivate::SelectSource()
|
||||
{
|
||||
TW_IDENTITY src;
|
||||
memset(&src, 0, sizeof(src));
|
||||
|
||||
// debug printouts
|
||||
bool ret_ok = CallTwainProc(&m_AppId, NULL, DG_CONTROL, DAT_IDENTITY, MSG_GETFIRST, &src);
|
||||
while (ret_ok) {
|
||||
ret_ok = CallTwainProc(&m_AppId, NULL, DG_CONTROL, DAT_IDENTITY, MSG_GETNEXT, &src);
|
||||
}
|
||||
|
||||
// set the default entry selected
|
||||
CallTwainProc(&m_AppId, NULL, DG_CONTROL, DAT_IDENTITY, MSG_GETDEFAULT, &src);
|
||||
|
||||
// now open the selection dialog
|
||||
if (!CallTwainProc(&m_AppId, NULL, DG_CONTROL, DAT_IDENTITY, MSG_USERSELECT, &src)) {
|
||||
return QString();
|
||||
}
|
||||
|
||||
QString source;
|
||||
source += src.ProductName;
|
||||
source += ';';
|
||||
source += src.ProductFamily;
|
||||
source += ';';
|
||||
source += src.Manufacturer;
|
||||
//qDebug()<< source;
|
||||
return source;
|
||||
}
|
||||
|
||||
/** Closes the Data Source
|
||||
*/
|
||||
void KSaneWidgetPrivate::CloseDS()
|
||||
{
|
||||
if(DSOpen()) {
|
||||
if(m_bSourceEnabled) {
|
||||
TW_USERINTERFACE twUI;
|
||||
if(CallTwainProc(&m_AppId, &m_Source, DG_CONTROL,
|
||||
DAT_USERINTERFACE, MSG_DISABLEDS, &twUI)) {
|
||||
m_bSourceEnabled = false;
|
||||
}
|
||||
}
|
||||
CallTwainProc(&m_AppId, NULL, DG_CONTROL,
|
||||
DAT_IDENTITY, MSG_CLOSEDS, (TW_MEMREF)&m_Source);
|
||||
m_bDSOpen = false;
|
||||
}
|
||||
}
|
||||
|
||||
/** Closes the Data Source Manager */
|
||||
void KSaneWidgetPrivate::CloseDSM()
|
||||
{
|
||||
if(m_hTwainDLL && m_pDSMProc && m_bDSMOpen) {
|
||||
CloseDS();
|
||||
CallTwainProc(&m_AppId, NULL, DG_CONTROL, DAT_PARENT, MSG_CLOSEDSM, (TW_MEMREF)&m_hMessageWnd);
|
||||
m_bDSMOpen = false;
|
||||
}
|
||||
}
|
||||
|
||||
/** Returns true if the Data Source is Open */
|
||||
bool KSaneWidgetPrivate::DSOpen() const
|
||||
{
|
||||
//qDebug() << m_hTwainDLL << m_pDSMProc << m_bDSMOpen << m_bDSOpen;
|
||||
return (m_hTwainDLL && m_pDSMProc) && m_bDSMOpen && m_bDSOpen;
|
||||
}
|
||||
|
||||
/** Opens a Data Source */
|
||||
bool KSaneWidgetPrivate::OpenSource(const QString &source)
|
||||
{
|
||||
if (source.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
QStringList splited = source.split(';');
|
||||
if (splited.size() != 3) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// go thorough the list and check if the source is available
|
||||
bool ret_ok = CallTwainProc(&m_AppId, NULL, DG_CONTROL, DAT_IDENTITY, MSG_GETFIRST, &m_Source);
|
||||
while (ret_ok) {
|
||||
//qDebug() << m_Source.Id << m_Source.Version.MajorNum << m_Source.Version.MinorNum;
|
||||
//qDebug() << m_Source.Manufacturer << m_Source.ProductFamily << m_Source.ProductName;
|
||||
if (QString(m_Source.ProductName) == splited[0]) break;
|
||||
ret_ok = CallTwainProc(&m_AppId, NULL, DG_CONTROL, DAT_IDENTITY, MSG_GETNEXT, &m_Source);
|
||||
}
|
||||
|
||||
if (!ret_ok) {
|
||||
// CallTwainProc failed when reading beyond the last source
|
||||
return false;
|
||||
}
|
||||
|
||||
// open the source
|
||||
if (m_hTwainDLL && m_pDSMProc && m_bDSMOpen) {
|
||||
m_bDSOpen = CallTwainProc(&m_AppId, NULL, DG_CONTROL, DAT_IDENTITY, MSG_OPENDS, (TW_MEMREF)&m_Source);
|
||||
//qDebug() << "OpenSource(qst..) m_bDSOpen" << m_bDSOpen;
|
||||
}
|
||||
|
||||
SetImageCount(TWCPP_ANYCOUNT);
|
||||
|
||||
return DSOpen();
|
||||
}
|
||||
|
||||
/** Re-Opens a Data Source */
|
||||
bool KSaneWidgetPrivate::ReOpenDialog()
|
||||
{
|
||||
//qDebug() << "ReOpenSource:" << m_hTwainDLL << m_pDSMProc << m_bDSMOpen << m_bDSOpen;
|
||||
|
||||
if (DSOpen()) {
|
||||
// already open
|
||||
return true;
|
||||
}
|
||||
// open the source
|
||||
if (m_hTwainDLL && m_pDSMProc && m_bDSMOpen) {
|
||||
m_bDSOpen = CallTwainProc(&m_AppId, NULL, DG_CONTROL, DAT_IDENTITY, MSG_OPENDS, (TW_MEMREF)&m_Source);
|
||||
//qDebug() << "ReOpenSource() m_bDSOpen" << m_bDSOpen;
|
||||
}
|
||||
|
||||
SetImageCount(TWCPP_ANYCOUNT);
|
||||
|
||||
if (DSOpen()) {
|
||||
return EnableSource(true);
|
||||
}
|
||||
//else
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/** Should be called from the main message loop of the application. Can always be called,
|
||||
it will not process the message unless a scan is in progress. */
|
||||
bool KSaneWidgetPrivate::ProcessMessage(MSG msg)
|
||||
{
|
||||
// TODO: don't really know why...
|
||||
if (msg.message == 528) return false;
|
||||
|
||||
if (m_hMessageWnd == 0) return false;
|
||||
|
||||
if(m_bSourceEnabled) {
|
||||
TW_UINT16 twRC = TWRC_NOTDSEVENT;
|
||||
|
||||
TW_EVENT twEvent;
|
||||
twEvent.pEvent = (TW_MEMREF)&msg;
|
||||
//memset(&twEvent, 0, sizeof(TW_EVENT));
|
||||
twEvent.TWMessage = MSG_NULL;
|
||||
|
||||
CallTwainProc(&m_AppId, &m_Source, DG_CONTROL,
|
||||
DAT_EVENT, MSG_PROCESSEVENT, (TW_MEMREF)&twEvent);
|
||||
|
||||
if(m_returnCode != TWRC_NOTDSEVENT) {
|
||||
TranslateMessage(twEvent);
|
||||
}
|
||||
return (twRC==TWRC_DSEVENT);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/** Queries the capability of the Twain Data Source */
|
||||
bool KSaneWidgetPrivate::GetCapability(TW_CAPABILITY& twCap, TW_UINT16 cap, TW_UINT16 conType)
|
||||
{
|
||||
if(DSOpen())
|
||||
{
|
||||
twCap.Cap = cap;
|
||||
twCap.ConType = conType;
|
||||
twCap.hContainer = NULL;
|
||||
|
||||
if(CallTwainProc(&m_AppId, &m_Source, DG_CONTROL,
|
||||
DAT_CAPABILITY, MSG_GET, (TW_MEMREF)&twCap))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/** Queries the capability of the Twain Data Source */
|
||||
bool KSaneWidgetPrivate::GetCapability(TW_UINT16 cap, TW_UINT32& value)
|
||||
{
|
||||
TW_CAPABILITY twCap;
|
||||
if(GetCapability(twCap, cap))
|
||||
{
|
||||
pTW_ONEVALUE pVal;
|
||||
pVal = (pTW_ONEVALUE )GlobalLock(twCap.hContainer);
|
||||
|
||||
if(pVal)
|
||||
{
|
||||
value = pVal->Item;
|
||||
GlobalUnlock(pVal);
|
||||
GlobalFree(twCap.hContainer);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/** Sets the capability of the Twain Data Source */
|
||||
bool KSaneWidgetPrivate::SetCapability(TW_UINT16 cap, TW_UINT16 value, bool sign)
|
||||
{
|
||||
if(DSOpen()) {
|
||||
TW_CAPABILITY twCap;
|
||||
pTW_ONEVALUE pVal;
|
||||
bool ret_value = false;
|
||||
twCap.Cap = cap;
|
||||
twCap.ConType = TWON_ONEVALUE;
|
||||
twCap.hContainer = GlobalAlloc(GHND,sizeof(TW_ONEVALUE));
|
||||
|
||||
if(twCap.hContainer) {
|
||||
pVal = (pTW_ONEVALUE)GlobalLock(twCap.hContainer);
|
||||
pVal->ItemType = sign ? TWTY_INT16 : TWTY_UINT16;
|
||||
pVal->Item = (TW_UINT32)value;
|
||||
GlobalUnlock(twCap.hContainer);
|
||||
ret_value = SetCapability(twCap);
|
||||
GlobalFree(twCap.hContainer);
|
||||
}
|
||||
return ret_value;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/** Sets the capability of the Twain Data Source */
|
||||
bool KSaneWidgetPrivate::SetCapability(TW_CAPABILITY& cap)
|
||||
{
|
||||
if(DSOpen()) {
|
||||
return CallTwainProc(&m_AppId, &m_Source, DG_CONTROL,
|
||||
DAT_CAPABILITY, MSG_SET, (TW_MEMREF)&cap);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/** Sets the number of images which can be accpeted by the application at one time */
|
||||
bool KSaneWidgetPrivate::SetImageCount(TW_INT16 nCount)
|
||||
{
|
||||
if(SetCapability(CAP_XFERCOUNT,(TW_UINT16)nCount,true)) {
|
||||
m_nImageCount = nCount;
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
if(m_returnCode == TWRC_CHECKSTATUS) {
|
||||
TW_UINT32 count = 0;
|
||||
|
||||
if(GetCapability(CAP_XFERCOUNT, count)) {
|
||||
nCount = (TW_INT16)count;
|
||||
|
||||
if(SetCapability(CAP_XFERCOUNT, nCount)) {
|
||||
m_nImageCount = nCount;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/** Called to enable the Twain Acquire Dialog. This too can be
|
||||
* overridden but is a helluva job. */
|
||||
bool KSaneWidgetPrivate::OpenDialog()
|
||||
{
|
||||
EnableSource(true);
|
||||
return true;
|
||||
}
|
||||
|
||||
/** Called to enable the Twain Acquire Dialog. This too can be
|
||||
* overridden but is a helluva job. */
|
||||
bool KSaneWidgetPrivate::EnableSource(bool showUI)
|
||||
{
|
||||
//qDebug() << "DSOpen() =" << DSOpen();
|
||||
if(DSOpen() && !m_bSourceEnabled) {
|
||||
TW_USERINTERFACE twUI;
|
||||
twUI.ShowUI = showUI;
|
||||
twUI.hParent = (TW_HANDLE)m_hMessageWnd;
|
||||
|
||||
if(CallTwainProc(&m_AppId, &m_Source, DG_CONTROL,
|
||||
DAT_USERINTERFACE, MSG_ENABLEDS, (TW_MEMREF)&twUI))
|
||||
{
|
||||
m_bSourceEnabled = true;
|
||||
m_bModalUI = twUI.ModalUI;
|
||||
}
|
||||
else {
|
||||
m_bSourceEnabled = false;
|
||||
m_bModalUI = true;
|
||||
}
|
||||
//qDebug() << "EnableSource:ModalUI=" << twUI.ModalUI;
|
||||
return m_bSourceEnabled;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/** Called by ProcessMessage to Translate a TWAIN message */
|
||||
void KSaneWidgetPrivate::TranslateMessage(TW_EVENT& twEvent)
|
||||
{
|
||||
switch(twEvent.TWMessage)
|
||||
{
|
||||
case MSG_XFERREADY:
|
||||
//qDebug() << "MSG_XFERREADY";
|
||||
TransferImage();
|
||||
break;
|
||||
|
||||
case MSG_CLOSEDSREQ:
|
||||
//qDebug() << "MSG_CLOSEDSREQ";
|
||||
CloseDS();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/** Gets Imageinfo for an image which is about to be transferred. */
|
||||
bool KSaneWidgetPrivate::GetImageInfo(TW_IMAGEINFO& info)
|
||||
{
|
||||
if(m_bSourceEnabled) {
|
||||
return CallTwainProc(&m_AppId, &m_Source, DG_IMAGE,
|
||||
DAT_IMAGEINFO, MSG_GET, (TW_MEMREF)&info);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/** Transfers the image or cancels the transfer depending on the state of the TWAIN system */
|
||||
void KSaneWidgetPrivate::TransferImage()
|
||||
{
|
||||
TW_IMAGEINFO info;
|
||||
bool bContinue=true;
|
||||
|
||||
while(bContinue) {
|
||||
if(GetImageInfo(info)) {
|
||||
int permission = TWCPP_DOTRANSFER;
|
||||
|
||||
switch(permission)
|
||||
{
|
||||
case TWCPP_CANCELTHIS:
|
||||
bContinue=EndTransfer();
|
||||
break;
|
||||
|
||||
case TWCPP_CANCELALL:
|
||||
CancelTransfer();
|
||||
bContinue=false;
|
||||
break;
|
||||
|
||||
case TWCPP_DOTRANSFER:
|
||||
bContinue=GetImage(info);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** Ends the current transfer.
|
||||
Returns true if the more images are pending */
|
||||
bool KSaneWidgetPrivate::EndTransfer()
|
||||
{
|
||||
TW_PENDINGXFERS twPend;
|
||||
if(CallTwainProc(&m_AppId, &m_Source, DG_CONTROL,
|
||||
DAT_PENDINGXFERS, MSG_ENDXFER, (TW_MEMREF)&twPend))
|
||||
{
|
||||
return twPend.Count != 0;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/** Aborts all transfers */
|
||||
void KSaneWidgetPrivate::CancelTransfer()
|
||||
{
|
||||
TW_PENDINGXFERS twPend;
|
||||
CallTwainProc(&m_AppId, &m_Source, DG_CONTROL, DAT_PENDINGXFERS, MSG_RESET, (TW_MEMREF)&twPend);
|
||||
}
|
||||
|
||||
/** Calls TWAIN to actually get the image */
|
||||
bool KSaneWidgetPrivate::GetImage(TW_IMAGEINFO& info)
|
||||
{
|
||||
TW_MEMREF pdata;
|
||||
CallTwainProc(&m_AppId, &m_Source, DG_IMAGE, DAT_IMAGENATIVEXFER, MSG_GET, &pdata);
|
||||
|
||||
switch(m_returnCode)
|
||||
{
|
||||
case TWRC_XFERDONE:
|
||||
//qDebug()<< "GetImage:TWRC_XFERDONE";
|
||||
ImageData(pdata, info);
|
||||
break;
|
||||
|
||||
case TWRC_CANCEL:
|
||||
//qDebug()<< "GetImage:TWRC_CANCEL";
|
||||
break;
|
||||
|
||||
case TWRC_FAILURE:
|
||||
//qDebug()<< "GetImage:TWRC_FAILURE";
|
||||
CancelTransfer();
|
||||
return false;
|
||||
break;
|
||||
}
|
||||
|
||||
GlobalFree(pdata);
|
||||
return EndTransfer();
|
||||
}
|
||||
|
||||
void KSaneWidgetPrivate::ImageData(TW_MEMREF pdata, TW_IMAGEINFO& info)
|
||||
{
|
||||
if (pdata && (info.ImageWidth != -1) && (info.ImageLength != - 1))
|
||||
{
|
||||
// Under Windows, Twain interface return a DIB data structure.
|
||||
// See http://en.wikipedia.org/wiki/Device-independent_bitmap#DIBs_in_memory for details.
|
||||
HGLOBAL hDIB = (HGLOBAL)(qptrdiff)pdata;
|
||||
int size = (int)GlobalSize(hDIB);
|
||||
const char* bits = (const char*)GlobalLock(hDIB);
|
||||
|
||||
// DIB is BMP without header. we will add it to load data in QImage using std loader from Qt.
|
||||
QByteArray baBmp;
|
||||
QDataStream ds(&baBmp, QIODevice::WriteOnly);
|
||||
|
||||
ds.writeRawData("BM", 2);
|
||||
|
||||
qint32 filesize = size + 14;
|
||||
ds << filesize;
|
||||
|
||||
qint16 reserved = 0;
|
||||
ds << reserved;
|
||||
ds << reserved;
|
||||
|
||||
qint32 pixOffset = 14 + 40 + 0;
|
||||
ds << pixOffset;
|
||||
|
||||
ds.writeRawData(bits, size);
|
||||
|
||||
emit ImageReady(baBmp, 0,0,0, (int)KSaneWidget::FormatBMP);
|
||||
|
||||
GlobalUnlock(hDIB);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace KSaneIface
|
127
libksane/ksanetwain/twainiface.h
Normal file
127
libksane/ksanetwain/twainiface.h
Normal file
|
@ -0,0 +1,127 @@
|
|||
/* ============================================================
|
||||
*
|
||||
* This file is a part of kdegraphics
|
||||
*
|
||||
* Date : 2009-05-12
|
||||
* Description : Twain interface
|
||||
*
|
||||
* Copyright (C) 2002-2003 Stephan Stapel <stephan dot stapel at web dot de>
|
||||
* Copyright (C) 2008-2009 by Gilles Caulier <caulier dot gilles at gmail dot com>
|
||||
* Copyright (C) 2009 by Kare Sars <kare dot sars at iki dot fi>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) version 3, or any
|
||||
* later version accepted by the membership of KDE e.V. (or its
|
||||
* successor approved by the membership of KDE e.V.), which shall
|
||||
* act as a proxy defined in Section 6 of version 3 of the license.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* ============================================================ */
|
||||
|
||||
#ifndef TWAINIFACE_H
|
||||
#define TWAINIFACE_H
|
||||
|
||||
#include "twain.h"
|
||||
|
||||
// Windows includes
|
||||
#include <windows.h>
|
||||
|
||||
#include <QWidget>
|
||||
|
||||
namespace KSaneIface
|
||||
{
|
||||
|
||||
class KSaneWidgetPrivate : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
|
||||
KSaneWidgetPrivate();
|
||||
~KSaneWidgetPrivate();
|
||||
|
||||
/**
|
||||
* Hook-in. See class documentation for details!
|
||||
* @result One should return false to get the message being
|
||||
* processed by the application (should return false by default!)
|
||||
*/
|
||||
bool winEvent(MSG* pMsg, long *result);
|
||||
|
||||
void CloseDSM();
|
||||
QString SelectSource();
|
||||
bool OpenSource(const QString &device);
|
||||
|
||||
public Q_SLOTS:
|
||||
|
||||
bool OpenDialog();
|
||||
bool ReOpenDialog();
|
||||
|
||||
|
||||
Q_SIGNALS:
|
||||
|
||||
void ImageReady(QByteArray &data, int width, int height, int bytes_per_line, int format);
|
||||
|
||||
private:
|
||||
|
||||
bool InitTwain();
|
||||
void ReleaseTwain();
|
||||
|
||||
bool ProcessMessage(MSG msg);
|
||||
|
||||
bool SetImageCount(TW_INT16 nCount=1);
|
||||
bool DSOpen() const;
|
||||
|
||||
|
||||
bool CallTwainProc(pTW_IDENTITY pOrigin, pTW_IDENTITY pDest,
|
||||
TW_UINT32 DG, TW_UINT16 DAT, TW_UINT16 MSG,
|
||||
TW_MEMREF pData);
|
||||
|
||||
bool EnableSource(bool showUI);
|
||||
void CloseDS();
|
||||
|
||||
bool GetCapability(TW_CAPABILITY& twCap, TW_UINT16 cap, TW_UINT16 conType=TWON_DONTCARE16);
|
||||
bool GetCapability(TW_UINT16 cap, TW_UINT32& value);
|
||||
bool SetCapability(TW_UINT16 cap, TW_UINT16 value, bool sign=false);
|
||||
bool SetCapability(TW_CAPABILITY& twCap);
|
||||
|
||||
bool GetImageInfo(TW_IMAGEINFO& info);
|
||||
|
||||
void TranslateMessage(TW_EVENT& twEvent);
|
||||
void TransferImage();
|
||||
bool EndTransfer();
|
||||
void CancelTransfer();
|
||||
bool GetImage(TW_IMAGEINFO& info);
|
||||
|
||||
void ImageData(TW_MEMREF pdata, TW_IMAGEINFO& info);
|
||||
|
||||
protected:
|
||||
|
||||
bool m_bDSMOpen;
|
||||
bool m_bDSOpen;
|
||||
bool m_bSourceEnabled;
|
||||
bool m_bModalUI;
|
||||
|
||||
int m_nImageCount;
|
||||
|
||||
HINSTANCE m_hTwainDLL;
|
||||
DSMENTRYPROC m_pDSMProc;
|
||||
|
||||
TW_IDENTITY m_AppId;
|
||||
TW_IDENTITY m_Source;
|
||||
TW_STATUS m_Status;
|
||||
TW_INT16 m_returnCode;
|
||||
HWND m_hMessageWnd;
|
||||
};
|
||||
|
||||
} // namespace KSaneIface
|
||||
|
||||
#endif /* TWAINIFACE_H */
|
79
libksane/libksane/CMakeLists.txt
Normal file
79
libksane/libksane/CMakeLists.txt
Normal file
|
@ -0,0 +1,79 @@
|
|||
|
||||
INCLUDE_DIRECTORIES(${SANE_INCLUDE_DIR}
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/options
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/widgets
|
||||
)
|
||||
|
||||
SET(ksane_LIB_SRCS
|
||||
widgets/gamma_disp.cpp
|
||||
widgets/labeled_gamma.cpp
|
||||
widgets/labeled_checkbox.cpp
|
||||
widgets/labeled_entry.cpp
|
||||
widgets/labeled_combo.cpp
|
||||
widgets/labeled_fslider.cpp
|
||||
widgets/labeled_slider.cpp
|
||||
widgets/ksane_button.cpp
|
||||
widgets/ksane_option_widget.cpp
|
||||
ksane_viewer.cpp
|
||||
selectionitem.cpp
|
||||
ksane_device_dialog.cpp
|
||||
ksane_find_devices_thread.cpp
|
||||
ksane_widget.cpp
|
||||
ksane_scan_thread.cpp
|
||||
ksane_preview_thread.cpp
|
||||
ksane_widget_private.cpp
|
||||
splittercollapser.cpp
|
||||
ksane_auth.cpp
|
||||
options/ksane_option.cpp
|
||||
options/ksane_opt_button.cpp
|
||||
options/ksane_opt_checkbox.cpp
|
||||
options/ksane_opt_entry.cpp
|
||||
options/ksane_opt_gamma.cpp
|
||||
options/ksane_opt_slider.cpp
|
||||
options/ksane_opt_fslider.cpp
|
||||
options/ksane_opt_combo.cpp
|
||||
)
|
||||
|
||||
KDE4_ADD_LIBRARY(ksane SHARED ${ksane_LIB_SRCS})
|
||||
|
||||
TARGET_LINK_LIBRARIES(ksane ${KDE4_KDEUI_LIBS}
|
||||
${SANE_LIBRARY}
|
||||
)
|
||||
|
||||
SET_TARGET_PROPERTIES(ksane PROPERTIES VERSION ${KSANE_LIB_SO_VERSION_STRING} SOVERSION ${KSANE_LIB_SO_CUR_VERSION})
|
||||
|
||||
OPTION(COMPILE_VIEWER_TESTAPP "Compile a small test application for the viewer")
|
||||
|
||||
IF (COMPILE_VIEWER_TESTAPP)
|
||||
message("Compile testapp")
|
||||
kde4_add_executable(viewer_test ksane_viewer.cpp ksane_viewer_test.cpp selectionitem.cpp)
|
||||
target_link_libraries(viewer_test ${KDE4_KDEUI_LIBS})
|
||||
ENDIF()
|
||||
|
||||
INSTALL(TARGETS ksane ${INSTALL_TARGETS_DEFAULT_ARGS} )
|
||||
|
||||
CONFIGURE_FILE(../cmake/templates/KSaneConfig.cmake.in ${CMAKE_CURRENT_BINARY_DIR}/KSaneConfig.cmake @ONLY)
|
||||
|
||||
# Check if compilation is done through digiKam SC or not. If yes, do not install header files.
|
||||
IF (NOT DIGIKAMSC_COMPILE_LIBKSANE)
|
||||
|
||||
INSTALL(FILES ksane.h
|
||||
libksane_export.h
|
||||
${CMAKE_CURRENT_BINARY_DIR}/version.h
|
||||
DESTINATION ${INCLUDE_INSTALL_DIR}/libksane COMPONENT Devel)
|
||||
|
||||
IF(NOT WIN32)
|
||||
CONFIGURE_FILE(${CMAKE_SOURCE_DIR}/cmake/templates/libksane.pc.cmake.in ${CMAKE_CURRENT_BINARY_DIR}/libksane.pc)
|
||||
CONFIGURE_FILE(${CMAKE_SOURCE_DIR}/cmake/templates/libksane.lsm.cmake.in ${CMAKE_CURRENT_BINARY_DIR}/libksane.lsm)
|
||||
INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/libksane.pc DESTINATION ${LIB_INSTALL_DIR}/pkgconfig )
|
||||
ENDIF(NOT WIN32)
|
||||
|
||||
# Install find cmake script to the system for client applications.
|
||||
|
||||
INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/KSaneConfig.cmake
|
||||
DESTINATION ${LIB_INSTALL_DIR}/cmake/KSane)
|
||||
|
||||
ENDIF()
|
||||
|
||||
KDE4_INSTALL_ICONS(${ICON_INSTALL_DIR})
|
||||
|
15
libksane/libksane/Mainpage.dox
Normal file
15
libksane/libksane/Mainpage.dox
Normal file
|
@ -0,0 +1,15 @@
|
|||
/** @mainpage libKSane
|
||||
|
||||
@brief A library for dealing with scanners
|
||||
|
||||
LibKSane is a KDE interface for SANE library to control flat scanners.
|
||||
|
||||
This library provides a widget to control a scanner, KSaneWidget. Internally,
|
||||
it will use the <a href="http://www.sane-project.org/">SANE</a> library (or
|
||||
directly use TWAIN on Windows if SANE is not available).
|
||||
|
||||
@see KSaneWidget
|
||||
|
||||
*/
|
||||
|
||||
// vim:ft=doxygen
|
3
libksane/libksane/Messages.sh
Executable file
3
libksane/libksane/Messages.sh
Executable file
|
@ -0,0 +1,3 @@
|
|||
#! /bin/sh
|
||||
$XGETTEXT `find . -name \*.cpp` ../ksanetwain/*.cpp -o $podir/libksane.pot
|
||||
|
33
libksane/libksane/dummy-hplip.cpp
Normal file
33
libksane/libksane/dummy-hplip.cpp
Normal file
|
@ -0,0 +1,33 @@
|
|||
// krazy:skip
|
||||
//begin strings from hplip-3.9.2/scan/sane/common.h to make them translatable
|
||||
I18N_NOOP("None");
|
||||
I18N_NOOP("MH");
|
||||
I18N_NOOP("MR");
|
||||
I18N_NOOP("MMR");
|
||||
I18N_NOOP("JPEG");
|
||||
I18N_NOOP("Auto");
|
||||
I18N_NOOP("Flatbed");
|
||||
I18N_NOOP("ADF");
|
||||
I18N_NOOP("Advanced");
|
||||
I18N_NOOP("Compression");
|
||||
I18N_NOOP("Selects the scanner compression "\
|
||||
"method for faster scans, possibly at the expense of image quality.");
|
||||
I18N_NOOP("JPEG compression factor");
|
||||
I18N_NOOP("Sets the scanner JPEG compression "\
|
||||
"factor. Larger numbers mean better compression, " \
|
||||
"and smaller numbers mean better image quality.");
|
||||
I18N_NOOP("Batch scan");
|
||||
I18N_NOOP("Enables continuous scanning with automatic document feeder (ADF).");
|
||||
I18N_NOOP("Duplex");
|
||||
I18N_NOOP("Enables scanning on both sides of the page.");
|
||||
I18N_NOOP("Geometry");
|
||||
I18N_NOOP("Length measurement");
|
||||
I18N_NOOP("Selects how the scanned image "\
|
||||
"length is measured and reported, which is impossible to know in advance for scrollfed scans.");
|
||||
I18N_NOOP("Unknown");
|
||||
I18N_NOOP("Unlimited");
|
||||
I18N_NOOP("Approximate");
|
||||
I18N_NOOP("Padded");
|
||||
I18N_NOOP("Exact");
|
||||
I18N_NOOP("???");
|
||||
//end strings from hplip-3.9.2/scan/sane/common.h to make them translatable
|
BIN
libksane/libksane/hi16-action-black-white.png
Normal file
BIN
libksane/libksane/hi16-action-black-white.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 129 B |
BIN
libksane/libksane/hi16-action-color.png
Normal file
BIN
libksane/libksane/hi16-action-color.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 803 B |
BIN
libksane/libksane/hi16-action-gray-scale.png
Normal file
BIN
libksane/libksane/hi16-action-gray-scale.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 182 B |
307
libksane/libksane/ksane.h
Normal file
307
libksane/libksane/ksane.h
Normal file
|
@ -0,0 +1,307 @@
|
|||
/* ============================================================
|
||||
*
|
||||
* This file is part of the KDE project
|
||||
*
|
||||
* Date : 2007-09-13
|
||||
* Description : Sane interface for KDE
|
||||
*
|
||||
* Copyright (C) 2007-2010 by Kare Sars <kare dot sars at iki dot fi>
|
||||
* Copyright (C) 2007 by Gilles Caulier <caulier dot gilles at gmail dot com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) version 3, or any
|
||||
* later version accepted by the membership of KDE e.V. (or its
|
||||
* successor approved by the membership of KDE e.V.), which shall
|
||||
* act as a proxy defined in Section 6 of version 3 of the license.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* ============================================================ */
|
||||
|
||||
#ifndef KSANE_H
|
||||
#define KSANE_H
|
||||
|
||||
// Qt includes
|
||||
#include <QtGui/QWidget>
|
||||
|
||||
// Local includes
|
||||
#include "libksane_export.h"
|
||||
|
||||
/** This namespace collects all methods and classes in LibKSane. */
|
||||
namespace KSaneIface
|
||||
{
|
||||
|
||||
class KSaneWidgetPrivate;
|
||||
|
||||
/**
|
||||
* This class provides the widget containing the scan options and the preview.
|
||||
* @author Kare Sars <kare.sars@iki.fi>
|
||||
*/
|
||||
class LIBKSANE_EXPORT KSaneWidget : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
friend class KSaneWidgetPrivate;
|
||||
|
||||
public:
|
||||
/** This enumeration describes the type of the returned data.
|
||||
* The number of formats might grow, so it is wise to be prepared fro more.*/
|
||||
typedef enum
|
||||
{
|
||||
FormatBlackWhite, /**< One bit per pixel 1 = black 0 = white */
|
||||
FormatGrayScale8, /**< Grayscale with one byte per pixel 0 = black 255 = white */
|
||||
FormatGrayScale16, /**< Grayscale withtTwo bytes per pixel.
|
||||
* The byte order is the one provided by libsane. */
|
||||
FormatRGB_8_C, /**< Every pixel consists of three colors in the order Read,
|
||||
* Grean and Blue, with one byte per color (no alpha channel). */
|
||||
FormatRGB_16_C, /**< Every pixel consists of three colors in the order Read,
|
||||
* Grean and Blue, with two bytes per color(no alpha channel).
|
||||
* The byte order is the one provided by libsane. */
|
||||
FormatBMP, /**< The image data is returned as a BMP. */
|
||||
FormatNone = 0xFFFF /**< This enumeration value should never be returned to the user */
|
||||
} ImageFormat;
|
||||
|
||||
/** @note There might come more enumerations in the future. */
|
||||
typedef enum
|
||||
{
|
||||
NoError, /**< The scanning was finished successfully.*/
|
||||
ErrorCannotSegment, /**< If this error status is returned libksane can not segment the
|
||||
* returned data. Scanning without segmentation should work.
|
||||
* @note segmentation is not implemented yet.*/
|
||||
ErrorGeneral, /**< The error string should contain an error message. */
|
||||
Information /**< There is some information to the user. */
|
||||
} ScanStatus;
|
||||
|
||||
struct DeviceInfo
|
||||
{
|
||||
QString name; /* unique device name */
|
||||
QString vendor; /* device vendor string */
|
||||
QString model; /* device model name */
|
||||
QString type; /* device type (e.g., "flatbed scanner") */
|
||||
};
|
||||
|
||||
/** This constructor initializes the private class variables, but the widget is left empty.
|
||||
* The options and the preview are added with the call to openDevice(). */
|
||||
KSaneWidget(QWidget* parent=0);
|
||||
|
||||
/** Standard destructor */
|
||||
~KSaneWidget();
|
||||
|
||||
/** This helper method displays a dialog for selecting a scanner. The libsane
|
||||
* device name of the selected scanner device is returned. */
|
||||
QString selectDevice(QWidget* parent=0);
|
||||
|
||||
/**
|
||||
* Get the list of available scanning devices. Connect to availableDevices()
|
||||
* which is fired once these devices are known.
|
||||
*/
|
||||
void initGetDeviceList() const;
|
||||
|
||||
/** This method opens the specified scanner device and adds the scan options to the
|
||||
* KSane widget.
|
||||
* @param device_name is the libsane device name for the scanner to open.
|
||||
* @return 'true' if all goes well and 'false' if the specified scanner can not be opened. */
|
||||
bool openDevice(const QString &device_name);
|
||||
|
||||
/** This method closes the currently open scanner device.
|
||||
* @return 'true' if all goes well and 'false' if no device is open. */
|
||||
bool closeDevice();
|
||||
|
||||
KDE_DEPRECATED bool makeQImage(const QByteArray &, int, int, int, ImageFormat, QImage &);
|
||||
|
||||
/**
|
||||
* This is a convenience method that can be used to create a QImage from the image data
|
||||
* returned by the imageReady(...) signal.
|
||||
* @note: If the image data has 16 bits/color the * data is truncated to 8 bits/color
|
||||
* since QImage does not support 16 bits/color. A warning message will be shown.
|
||||
*
|
||||
* @param data is the byte data containing the image.
|
||||
* @param width is the width of the image in pixels.
|
||||
* @param height is the height of the image in pixels.
|
||||
* @param bytes_per_line is the number of bytes used per line. This might include padding
|
||||
* and is probably only relevant for 'FormatBlackWhite'.
|
||||
* @param format is the KSane image format of the data.
|
||||
* @return This function returns the provided image data as a QImage. */
|
||||
QImage toQImage(const QByteArray &data,
|
||||
int width,
|
||||
int height,
|
||||
int bytes_per_line,
|
||||
ImageFormat format);
|
||||
|
||||
/**
|
||||
* This is a convenience method that can be used to create a QImage from the image data
|
||||
* returned by the imageReady(...) signal.
|
||||
* @note: If the image data has 16 bits/color the * data is truncated to 8 bits/color, but
|
||||
* unlike toQImage() this function will not give a warning.
|
||||
*
|
||||
* @param data is the byte data containing the image.
|
||||
* @param width is the width of the image in pixels.
|
||||
* @param height is the height of the image in pixels.
|
||||
* @param bytes_per_line is the number of bytes used per line. This might include padding
|
||||
* and is probably only relevant for 'FormatBlackWhite'.
|
||||
* @param format is the KSane image format of the data.
|
||||
* @return This function returns the provided image data as a QImage. */
|
||||
QImage toQImageSilent(const QByteArray &data,
|
||||
int width,
|
||||
int height,
|
||||
int bytes_per_line,
|
||||
ImageFormat format);
|
||||
|
||||
/** This method returns the vendor name of the scanner (Same as make). */
|
||||
QString vendor() const;
|
||||
/** This method returns the make name of the scanner. */
|
||||
QString make() const;
|
||||
/** This methos returns the model of the scanner. */
|
||||
QString model() const;
|
||||
|
||||
/** This method returns the current resolution of the acquired image,
|
||||
* in dots per inch.
|
||||
* @note This function should be called from the slot connected
|
||||
* to the imageReady signal. The connection should not be queued.
|
||||
* @return the resolution used for scanning or 0.0 on failure. */
|
||||
float currentDPI();
|
||||
|
||||
/** This method returns the scan area's width in mm
|
||||
* @return Width of the scannable area in mm */
|
||||
float scanAreaWidth();
|
||||
|
||||
/** This method returns the scan area's height in mm
|
||||
* @return Height of the scannable area in mm */
|
||||
float scanAreaHeight();
|
||||
|
||||
/** This method sets the selection according to the given points
|
||||
* @note The points are defined with respect to the scan areas top-left corner in mm
|
||||
* @param topLeft Upper left corner of the selection (in mm)
|
||||
* @param bottomRight Lower right corner of the selection (in mm) */
|
||||
void setSelection(QPointF topLeft, QPointF bottomRight);
|
||||
|
||||
/** This function is used to set the preferred resolution for scanning the preview.
|
||||
* @param dpi is the wanted scan resolution for the preview
|
||||
* @note if the set value is not supported, the cloasest one is used
|
||||
* @note setting the value 0 means that the default calculated value should be used */
|
||||
void setPreviewResolution(float dpi);
|
||||
|
||||
/** This method reads the available parameters and their values and
|
||||
* returns them in a QMap (Name, value)
|
||||
* @param opts is a QMap with the parameter names and values. */
|
||||
void getOptVals(QMap <QString, QString> &opts);
|
||||
|
||||
/** This method can be used to write many parameter values at once.
|
||||
* @param opts is a QMap with the parameter names and values.
|
||||
* @return This function returns the number of successful writes. */
|
||||
int setOptVals(const QMap <QString, QString> &opts);
|
||||
|
||||
/** This function reads one parameter value into a string.
|
||||
* @param optname is the name of the parameter to read.
|
||||
* @param value is the string representation of the value.
|
||||
* @return this function returns true if the read was successful. */
|
||||
bool getOptVal(const QString &optname, QString &value);
|
||||
|
||||
/** This function writes one parameter value into a string.
|
||||
* @param optname is the name of the parameter to write.
|
||||
* @param value is the string representation of the value.
|
||||
* @return this function returns true if the write was successful. */
|
||||
bool setOptVal(const QString &optname, const QString &value);
|
||||
|
||||
/** This function sets the label on the final scan button
|
||||
* @param scanLabel is the new label for the button. */
|
||||
void setScanButtonText(const QString &scanLabel);
|
||||
|
||||
/** This function sets the label on the preview button
|
||||
* @param previewLabel is the new label for the button. */
|
||||
void setPreviewButtonText(const QString &previewLabel);
|
||||
|
||||
/** This function can be used to enable/disable automatic selections on previews.
|
||||
* The default state is enabled.
|
||||
* @param enable specifies if the auto selection should be turned on or off. */
|
||||
void enableAutoSelect(bool enable);
|
||||
|
||||
/** This function is used to programatically collapse/restore the options.
|
||||
* @param collapse defines the state to set. */
|
||||
void setOptionsCollapsed(bool collapse);
|
||||
|
||||
/** This function is used hide/show the final scan button.
|
||||
* @param hidden defines the state to set. */
|
||||
void setScanButtonHidden(bool hidden);
|
||||
|
||||
public Q_SLOTS:
|
||||
/** This method can be used to cancel a scan or prevent an automatic new scan. */
|
||||
void scanCancel();
|
||||
|
||||
/** This method can be used to start a scan (if no GUI is needed).
|
||||
* @note libksane may return one or more images as a result of one invocation of this slot.
|
||||
* If no more images are wanted scanCancel should be called in the slot handling the
|
||||
* imageReady signal. */
|
||||
void scanFinal();
|
||||
|
||||
Q_SIGNALS:
|
||||
/**
|
||||
* This Signal is emitted when a final scan is ready.
|
||||
* @param data is the byte data containing the image.
|
||||
* @param width is the width of the image in pixels.
|
||||
* @param height is the height of the image in pixels.
|
||||
* @param bytes_per_line is the number of bytes used per line. This might include padding
|
||||
* and is probably only relevant for 'FormatBlackWhite'.
|
||||
* @param format is the KSane image format of the data. */
|
||||
void imageReady(QByteArray &data, int width, int height,
|
||||
int bytes_per_line, int format);
|
||||
|
||||
/**
|
||||
* This signal is emitted when the scanning has ended.
|
||||
* @param status contains a ScanStatus status code.
|
||||
* @param strStatus If an error has occurred this string will contain an error message.
|
||||
* otherwise the string is empty. */
|
||||
void scanDone(int status, const QString &strStatus);
|
||||
|
||||
/**
|
||||
* This signal is emitted when the user is to be notified about something.
|
||||
* @note If no slot is connected to this signal the message will be displayed in a KMessageBox.
|
||||
* @param type contains a ScanStatus code to identify the type of message (error/info/...).
|
||||
* @param msg is the message to the user.
|
||||
* otherwise the string is empty. */
|
||||
void userMessage(int type, const QString &strStatus);
|
||||
|
||||
/**
|
||||
* This Signal is emitted for progress information during a scan.
|
||||
* The GUI already has a progress bar, but if the GUI is hidden,
|
||||
* this can be used to display a progress bar.
|
||||
* @param percent is the percentage of the scan progress (0-100). */
|
||||
void scanProgress(int percent);
|
||||
|
||||
/**
|
||||
* This signal is emitted every time the device list is updated or
|
||||
* after initGetDeviceList() is called.
|
||||
* @param deviceList is a QList of KSaneWidget::DeviceInfo that contain the
|
||||
* device name, model, vendor and type of the attached scanners.
|
||||
* @note The list is only a snapshot of the current available devices. Devices
|
||||
* might be added or removed/opened after the signal is emitted.
|
||||
*/
|
||||
void availableDevices(const QList<KSaneWidget::DeviceInfo> &deviceList);
|
||||
|
||||
/**
|
||||
* This Signal is emitted when a hardware button is pressed.
|
||||
* @param optionName is the untranslated technical name of the sane-option.
|
||||
* @param optionLabel is the translated user visible label of the sane-option.
|
||||
* @param pressed indicates if the value is true or false.
|
||||
* @note The SANE standard does not specify hardware buttons and their behaviors,
|
||||
* so this signal is emitted for sane-options that behave like hardware buttons.
|
||||
* That is the sane-options are read-only and type boolean. The naming of hardware
|
||||
* buttons also differ from backend to backend.
|
||||
*/
|
||||
void buttonPressed(const QString &optionName, const QString &optionLabel, bool pressed);
|
||||
|
||||
private:
|
||||
|
||||
KSaneWidgetPrivate * const d;
|
||||
};
|
||||
|
||||
} // NameSpace KSaneIface
|
||||
|
||||
#endif // SANE_WIDGET_H
|
136
libksane/libksane/ksane_auth.cpp
Normal file
136
libksane/libksane/ksane_auth.cpp
Normal file
|
@ -0,0 +1,136 @@
|
|||
/* ============================================================
|
||||
*
|
||||
* This file is part of the KDE project
|
||||
*
|
||||
* Date : 2010
|
||||
* Description : Sane authentication helpers.
|
||||
*
|
||||
* Copyright (C) 2010 by Kare Sars <kare dot sars at iki dot fi>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) version 3, or any
|
||||
* later version accepted by the membership of KDE e.V. (or its
|
||||
* successor approved by the membership of KDE e.V.), which shall
|
||||
* act as a proxy defined in Section 6 of version 3 of the license.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* ============================================================ */
|
||||
|
||||
#include "ksane_auth.h"
|
||||
|
||||
// Qt includes
|
||||
#include <QMutex>
|
||||
#include <QList>
|
||||
|
||||
// KDE includes
|
||||
#include <KDebug>
|
||||
|
||||
namespace KSaneIface
|
||||
{
|
||||
|
||||
static KSaneAuth *s_instance = 0;
|
||||
static QMutex s_mutex;
|
||||
|
||||
struct KSaneAuth::Private
|
||||
{
|
||||
struct AuthStruct
|
||||
{
|
||||
QString resource;
|
||||
QString username;
|
||||
QString password;
|
||||
};
|
||||
|
||||
QList<AuthStruct> authList;
|
||||
};
|
||||
|
||||
KSaneAuth *KSaneAuth::getInstance()
|
||||
{
|
||||
s_mutex.lock();
|
||||
|
||||
if (s_instance == 0) {
|
||||
s_instance = new KSaneAuth();
|
||||
}
|
||||
s_mutex.unlock();
|
||||
|
||||
return s_instance;
|
||||
}
|
||||
|
||||
KSaneAuth::KSaneAuth() : d(new Private) {}
|
||||
|
||||
KSaneAuth::~KSaneAuth()
|
||||
{
|
||||
d->authList.clear();
|
||||
delete d;
|
||||
}
|
||||
|
||||
void KSaneAuth::setDeviceAuth(const QString &resource, const QString &username, const QString &password)
|
||||
{
|
||||
// This is a short list so we do not need a QMap...
|
||||
int i;
|
||||
for (i=0; i<d->authList.size(); i++) {
|
||||
if (resource == d->authList.at(i).resource) {
|
||||
// update the existing node
|
||||
d->authList[i].username = username;
|
||||
d->authList[i].password = password;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (i==d->authList.size()) {
|
||||
// Add a new list node
|
||||
Private::AuthStruct tmp;
|
||||
tmp.resource = resource;
|
||||
tmp.username = username;
|
||||
tmp.password = password;
|
||||
d->authList << tmp;
|
||||
}
|
||||
}
|
||||
|
||||
void KSaneAuth::clearDeviceAuth(const QString &resource)
|
||||
{
|
||||
// This is a short list so we do not need a QMap...
|
||||
for (int i=0; i<d->authList.size(); i++) {
|
||||
if (resource == d->authList.at(i).resource) {
|
||||
d->authList.removeAt(i);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** static function called by sane_open to get authorization from user */
|
||||
void KSaneAuth::authorization(SANE_String_Const resource, SANE_Char *username, SANE_Char *password)
|
||||
{
|
||||
kDebug() << resource;
|
||||
// This is vague in the standard... what can I find in the resource string?
|
||||
// I have found that "resource contains the backend name + "$MD5$....."
|
||||
// it does not contain unique identifiers like ":libusb:001:004"
|
||||
// -> remove $MD5 and later before comparison...
|
||||
QString res(resource);
|
||||
int end = res.indexOf("$MD5$");
|
||||
res = res.left(end);
|
||||
kDebug() << res;
|
||||
|
||||
QList<Private::AuthStruct> list = getInstance()->d->authList;
|
||||
for (int i=0; i<list.size(); i++) {
|
||||
kDebug() << res << list.at(i).resource;
|
||||
if (list.at(i).resource.contains(res)) {
|
||||
qstrncpy(username, list.at(i).username.toLocal8Bit(), SANE_MAX_USERNAME_LEN);
|
||||
qstrncpy(password, list.at(i).password.toLocal8Bit(), SANE_MAX_PASSWORD_LEN);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
63
libksane/libksane/ksane_auth.h
Normal file
63
libksane/libksane/ksane_auth.h
Normal file
|
@ -0,0 +1,63 @@
|
|||
/* ============================================================
|
||||
*
|
||||
* This file is part of the KDE project
|
||||
*
|
||||
* Date : 2010
|
||||
* Description : Sane authentication helpers.
|
||||
*
|
||||
* Copyright (C) 2010 by Kare Sars <kare dot sars at iki dot fi>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) version 3, or any
|
||||
* later version accepted by the membership of KDE e.V. (or its
|
||||
* successor approved by the membership of KDE e.V.), which shall
|
||||
* act as a proxy defined in Section 6 of version 3 of the license.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* ============================================================ */
|
||||
|
||||
#ifndef KSANE_AUTH_H
|
||||
#define KSANE_AUTH_H
|
||||
|
||||
// Qt includes
|
||||
#include <QString>
|
||||
|
||||
// Sane includes
|
||||
extern "C"
|
||||
{
|
||||
#include <sane/saneopts.h>
|
||||
#include <sane/sane.h>
|
||||
}
|
||||
|
||||
namespace KSaneIface
|
||||
{
|
||||
|
||||
class KSaneAuth
|
||||
{
|
||||
public:
|
||||
static KSaneAuth *getInstance();
|
||||
~KSaneAuth();
|
||||
|
||||
void setDeviceAuth(const QString &resource, const QString &username, const QString &password);
|
||||
void clearDeviceAuth(const QString &resource);
|
||||
static void authorization(SANE_String_Const resource, SANE_Char *username, SANE_Char *password);
|
||||
|
||||
private:
|
||||
KSaneAuth();
|
||||
struct Private;
|
||||
Private * const d;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
|
||||
#endif
|
189
libksane/libksane/ksane_device_dialog.cpp
Normal file
189
libksane/libksane/ksane_device_dialog.cpp
Normal file
|
@ -0,0 +1,189 @@
|
|||
/* ============================================================
|
||||
*
|
||||
* This file is part of the KDE project
|
||||
*
|
||||
* Date : 2007-09-13
|
||||
* Description : Sane interface for KDE
|
||||
*
|
||||
* Copyright (C) 2007-2008 by Kare Sars <kare dot sars at iki dot fi>
|
||||
* Copyright (C) 2009 by Grzegorz Kurtyka <grzegorz dot kurtyka at gmail dot com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) version 3, or any
|
||||
* later version accepted by the membership of KDE e.V. (or its
|
||||
* successor approved by the membership of KDE e.V.), which shall
|
||||
* act as a proxy defined in Section 6 of version 3 of the license.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* ============================================================ */
|
||||
|
||||
// Local includes
|
||||
#include "ksane_device_dialog.h"
|
||||
#include "ksane_device_dialog.moc"
|
||||
|
||||
|
||||
// Sane includes
|
||||
extern "C"
|
||||
{
|
||||
#include <sane/saneopts.h>
|
||||
#include <sane/sane.h>
|
||||
}
|
||||
|
||||
|
||||
// KDE includes
|
||||
#include <KDebug>
|
||||
#include <KPushButton>
|
||||
|
||||
#include <QScrollArea>
|
||||
#include <QLabel>
|
||||
|
||||
namespace KSaneIface
|
||||
{
|
||||
|
||||
KSaneDeviceDialog::KSaneDeviceDialog(QWidget *parent)
|
||||
: KDialog(parent)
|
||||
{
|
||||
|
||||
setButtons(KDialog::User1 | KDialog::Ok | KDialog::Cancel);
|
||||
setButtonText(User1, i18n("Reload devices list"));
|
||||
|
||||
m_btnGroup = new QButtonGroup(this);
|
||||
|
||||
m_btnBox = new QGroupBox;
|
||||
QVBoxLayout *layout = new QVBoxLayout;
|
||||
m_btnContainer = new QWidget;
|
||||
m_btnLayout = new QVBoxLayout(m_btnContainer);
|
||||
QScrollArea *area = new QScrollArea;
|
||||
|
||||
m_btnBox->setLayout(layout);
|
||||
|
||||
QLabel *explanation =
|
||||
new QLabel(i18n("<html>The SANE (Scanner Access Now Easy) system could not find any device.<br>"
|
||||
"Check that the scanner is plugged in and turned on<br>"
|
||||
"or check your systems scanner setup.<br>"
|
||||
"For details about SANE see the "
|
||||
"<a href='http://www.sane-project.org/'>SANE homepage</a>.</html>"));
|
||||
explanation->setOpenExternalLinks(true);
|
||||
int l,t,r,b;
|
||||
layout->getContentsMargins(&l, &t, &r, &b);
|
||||
explanation->setContentsMargins(l, t, r, b);
|
||||
|
||||
layout->addWidget(explanation);
|
||||
m_btnBox->adjustSize(); // make sure to see the complete explanation text
|
||||
layout->addWidget(area);
|
||||
layout->setContentsMargins(0,0,0,0);
|
||||
|
||||
area->setWidgetResizable(true);
|
||||
area->setFrameShape(QFrame::NoFrame);
|
||||
area->setWidget(m_btnContainer);
|
||||
|
||||
setMainWidget(m_btnBox);
|
||||
setMinimumHeight(200);
|
||||
m_findDevThread = FindSaneDevicesThread::getInstance();
|
||||
|
||||
connect(m_findDevThread, SIGNAL(finished()), this, SLOT(updateDevicesList()));
|
||||
connect(this, SIGNAL(user1Clicked()), this, SLOT(reloadDevicesList()));
|
||||
|
||||
reloadDevicesList();
|
||||
}
|
||||
|
||||
KSaneDeviceDialog::~KSaneDeviceDialog() {
|
||||
///@todo wait for thread to finish if its running
|
||||
}
|
||||
|
||||
void KSaneDeviceDialog::reloadDevicesList()
|
||||
{
|
||||
setAvailable(false);
|
||||
while (!m_btnGroup->buttons().isEmpty()) {
|
||||
delete m_btnGroup->buttons().takeFirst();
|
||||
}
|
||||
m_btnBox->setTitle(i18n("Looking for devices. Please wait."));
|
||||
m_btnBox->layout()->itemAt(0)->widget()->hide(); // explanation
|
||||
enableButton(KDialog::User1, false);
|
||||
|
||||
if(!m_findDevThread->isRunning()) {
|
||||
m_findDevThread->start();
|
||||
}
|
||||
}
|
||||
|
||||
void KSaneDeviceDialog::setAvailable(bool avail)
|
||||
{
|
||||
enableButtonOk(avail);
|
||||
if(avail) {
|
||||
m_selectedDevice = getSelectedName();
|
||||
setButtonFocus(KDialog::Ok);
|
||||
}
|
||||
}
|
||||
|
||||
void KSaneDeviceDialog::setDefault(QString defaultBackend)
|
||||
{
|
||||
m_selectedDevice = defaultBackend;
|
||||
}
|
||||
|
||||
QString KSaneDeviceDialog::getSelectedName() {
|
||||
QAbstractButton *selectedButton = m_btnGroup->checkedButton();
|
||||
if(selectedButton) {
|
||||
return selectedButton->objectName();
|
||||
}
|
||||
return QString();
|
||||
}
|
||||
|
||||
void KSaneDeviceDialog::updateDevicesList()
|
||||
{
|
||||
while (!m_btnGroup->buttons().isEmpty()) {
|
||||
delete m_btnGroup->buttons().takeFirst();
|
||||
}
|
||||
|
||||
const QList<KSaneWidget::DeviceInfo> list = m_findDevThread->devicesList();
|
||||
if (list.isEmpty()) {
|
||||
m_btnBox->setTitle(i18n("Sorry. No devices found."));
|
||||
m_btnBox->layout()->itemAt(0)->widget()->show(); // explanation
|
||||
m_btnBox->layout()->itemAt(1)->widget()->hide(); // scroll area
|
||||
enableButton(KDialog::User1, true);
|
||||
return;
|
||||
}
|
||||
|
||||
delete m_btnLayout;
|
||||
m_btnLayout = new QVBoxLayout;
|
||||
m_btnContainer->setLayout(m_btnLayout);
|
||||
m_btnBox->setTitle(i18n("Found devices:"));
|
||||
m_btnBox->layout()->itemAt(0)->widget()->hide(); // explanation
|
||||
m_btnBox->layout()->itemAt(1)->widget()->show(); // scroll area
|
||||
|
||||
for (int i=0; i< list.size(); i++) {
|
||||
QRadioButton *b = new QRadioButton(this);
|
||||
b->setObjectName(list[i].name);
|
||||
b->setToolTip(list[i].name);
|
||||
b->setText(QString("%1 : %2\n%3")
|
||||
.arg(list[i].vendor)
|
||||
.arg(list[i].model)
|
||||
.arg(list[i].name));
|
||||
|
||||
m_btnLayout->addWidget(b);
|
||||
m_btnGroup->addButton(b);
|
||||
connect(b, SIGNAL(clicked(bool)), this, SLOT(setAvailable(bool)));
|
||||
if((i==0) || (list[i].name == m_selectedDevice)) {
|
||||
b->setChecked(true);
|
||||
setAvailable(true);
|
||||
}
|
||||
}
|
||||
|
||||
m_btnLayout->addStretch();
|
||||
|
||||
if(list.size() == 1) {
|
||||
button(KDialog::Ok)->animateClick();
|
||||
}
|
||||
|
||||
enableButton(KDialog::User1, true);
|
||||
}
|
||||
|
||||
} // NameSpace KSaneIface
|
83
libksane/libksane/ksane_device_dialog.h
Normal file
83
libksane/libksane/ksane_device_dialog.h
Normal file
|
@ -0,0 +1,83 @@
|
|||
/* ============================================================
|
||||
*
|
||||
* This file is part of the KDE project
|
||||
*
|
||||
* Date : 2007-09-13
|
||||
* Description : Sane interface for KDE
|
||||
*
|
||||
* Copyright (C) 2007-2010 by Kare Sars <kare dot sars at iki dot fi>
|
||||
* Copyright (C) 2009 by Grzegorz Kurtyka <grzegorz dot kurtyka at gmail dot com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) version 3, or any
|
||||
* later version accepted by the membership of KDE e.V. (or its
|
||||
* successor approved by the membership of KDE e.V.), which shall
|
||||
* act as a proxy defined in Section 6 of version 3 of the license.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* ============================================================ */
|
||||
|
||||
#ifndef KSANE_DEVICE_DIALOG_H
|
||||
#define KSANE_DEVICE_DIALOG_H
|
||||
|
||||
#include "ksane_find_devices_thread.h"
|
||||
|
||||
// Qt includes
|
||||
#include <QGroupBox>
|
||||
#include <QStringList>
|
||||
#include <QButtonGroup>
|
||||
#include <QToolTip>
|
||||
#include <QRadioButton>
|
||||
#include <QCheckBox>
|
||||
#include <QPushButton>
|
||||
#include <QBoxLayout>
|
||||
|
||||
|
||||
// KDE includes
|
||||
#include <KDialog>
|
||||
#include <klocale.h>
|
||||
|
||||
namespace KSaneIface
|
||||
{
|
||||
|
||||
class KSaneDeviceDialog : public KDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
|
||||
KSaneDeviceDialog(QWidget *parent=0);
|
||||
~KSaneDeviceDialog();
|
||||
|
||||
QString getSelectedName();
|
||||
void setDefault(QString);
|
||||
|
||||
public Q_SLOTS:
|
||||
void reloadDevicesList();
|
||||
|
||||
private Q_SLOTS:
|
||||
void setAvailable(bool avail);
|
||||
void updateDevicesList();
|
||||
|
||||
private:
|
||||
QWidget *m_btnContainer;
|
||||
QGroupBox *m_btnBox;
|
||||
QButtonGroup *m_btnGroup;
|
||||
QVBoxLayout *m_btnLayout;
|
||||
QString m_defaultBackend;
|
||||
QString m_selectedDevice;
|
||||
FindSaneDevicesThread *m_findDevThread;
|
||||
};
|
||||
|
||||
} // NameSpace KSaneIface
|
||||
|
||||
#endif
|
107
libksane/libksane/ksane_find_devices_thread.cpp
Normal file
107
libksane/libksane/ksane_find_devices_thread.cpp
Normal file
|
@ -0,0 +1,107 @@
|
|||
/* ============================================================
|
||||
*
|
||||
* This file is part of the KDE project
|
||||
*
|
||||
* Date : 2007-09-13
|
||||
* Description : Sane interface for KDE
|
||||
*
|
||||
* Copyright (C) 2009 by Grzegorz Kurtyka <grzegorz dot kurtyka at gmail dot com>
|
||||
* Copyright (C) 2010 by Kare Sars <kare dot sars at iki dot fi>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) version 3, or any
|
||||
* later version accepted by the membership of KDE e.V. (or its
|
||||
* successor approved by the membership of KDE e.V.), which shall
|
||||
* act as a proxy defined in Section 6 of version 3 of the license.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* ============================================================ */
|
||||
|
||||
#include "ksane_find_devices_thread.h"
|
||||
#include "ksane_find_devices_thread.moc"
|
||||
|
||||
#include "ksane_widget_private.h"
|
||||
|
||||
// Sane includes
|
||||
extern "C"
|
||||
{
|
||||
#include <sane/saneopts.h>
|
||||
#include <sane/sane.h>
|
||||
}
|
||||
|
||||
// KDE includes
|
||||
#include <KDebug>
|
||||
|
||||
// Qt includes
|
||||
#include <QMutex>
|
||||
|
||||
namespace KSaneIface
|
||||
{
|
||||
static FindSaneDevicesThread *s_instancesane = 0;
|
||||
static QMutex s_mutexsane;
|
||||
|
||||
FindSaneDevicesThread *FindSaneDevicesThread::getInstance()
|
||||
{
|
||||
s_mutexsane.lock();
|
||||
|
||||
if (s_instancesane == 0) {
|
||||
s_instancesane = new FindSaneDevicesThread();
|
||||
}
|
||||
s_mutexsane.unlock();
|
||||
|
||||
return s_instancesane;
|
||||
}
|
||||
|
||||
FindSaneDevicesThread::FindSaneDevicesThread() : QThread(0)
|
||||
{
|
||||
}
|
||||
|
||||
FindSaneDevicesThread::~FindSaneDevicesThread()
|
||||
{
|
||||
s_mutexsane.lock();
|
||||
wait();
|
||||
s_mutexsane.unlock();
|
||||
}
|
||||
|
||||
|
||||
void FindSaneDevicesThread::run()
|
||||
{
|
||||
SANE_Device const **devList;
|
||||
//SANE_Int version;
|
||||
SANE_Status status;
|
||||
|
||||
// This is unfortunately not very reliable as many back-ends do not refresh
|
||||
// the device list after the sane_init() call...
|
||||
status = sane_get_devices(&devList, SANE_FALSE);
|
||||
|
||||
m_deviceList.clear();
|
||||
if (status == SANE_STATUS_GOOD) {
|
||||
int i = 0;
|
||||
KSaneWidget::DeviceInfo tmp;
|
||||
|
||||
while(devList[i] != 0) {
|
||||
tmp.name = devList[i]->name;
|
||||
tmp.vendor = devList[i]->vendor;
|
||||
tmp.model = devList[i]->model;
|
||||
tmp.type = devList[i]->type;
|
||||
m_deviceList << tmp;
|
||||
i++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const QList<KSaneWidget::DeviceInfo> FindSaneDevicesThread::devicesList() const
|
||||
{
|
||||
return m_deviceList;
|
||||
}
|
||||
|
||||
}
|
57
libksane/libksane/ksane_find_devices_thread.h
Normal file
57
libksane/libksane/ksane_find_devices_thread.h
Normal file
|
@ -0,0 +1,57 @@
|
|||
/* ============================================================
|
||||
*
|
||||
* This file is part of the KDE project
|
||||
*
|
||||
* Date : 2007-09-13
|
||||
* Description : Sane interface for KDE
|
||||
*
|
||||
* Copyright (C) 2007-2008 by Kare Sars <kare dot sars at iki dot fi>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) version 3, or any
|
||||
* later version accepted by the membership of KDE e.V. (or its
|
||||
* successor approved by the membership of KDE e.V.), which shall
|
||||
* act as a proxy defined in Section 6 of version 3 of the license.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* ============================================================ */
|
||||
|
||||
#ifndef KSANE_FIND_DEVICES_THREAD_H
|
||||
#define KSANE_FIND_DEVICES_THREAD_H
|
||||
|
||||
#include "ksane.h"
|
||||
|
||||
#include <QThread>
|
||||
#include <QList>
|
||||
|
||||
namespace KSaneIface
|
||||
{
|
||||
|
||||
class FindSaneDevicesThread : public QThread {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
static FindSaneDevicesThread *getInstance();
|
||||
~FindSaneDevicesThread();
|
||||
void run();
|
||||
|
||||
const QList<KSaneWidget::DeviceInfo> devicesList() const;
|
||||
|
||||
private:
|
||||
FindSaneDevicesThread();
|
||||
|
||||
QList<KSaneWidget::DeviceInfo> m_deviceList;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
472
libksane/libksane/ksane_preview_thread.cpp
Normal file
472
libksane/libksane/ksane_preview_thread.cpp
Normal file
|
@ -0,0 +1,472 @@
|
|||
/* ============================================================
|
||||
*
|
||||
* This file is part of the KDE project
|
||||
*
|
||||
* Date : 2009-11-13
|
||||
* Description : Sane interface for KDE
|
||||
*
|
||||
* Copyright (C) 2009 by Kare Sars <kare dot sars at iki dot fi>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) version 3, or any
|
||||
* later version accepted by the membership of KDE e.V. (or its
|
||||
* successor approved by the membership of KDE e.V.), which shall
|
||||
* act as a proxy defined in Section 6 of version 3 of the license.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* ============================================================ */
|
||||
|
||||
// Local includes
|
||||
#include "ksane_preview_thread.moc"
|
||||
|
||||
#include <KDebug>
|
||||
#include <QMutexLocker>
|
||||
|
||||
|
||||
namespace KSaneIface
|
||||
{
|
||||
KSanePreviewThread::KSanePreviewThread(SANE_Handle handle, QImage *img):
|
||||
QThread(),
|
||||
status(SANE_STATUS_GOOD),
|
||||
m_frameSize(0),
|
||||
m_frameRead(0),
|
||||
m_dataSize(0),
|
||||
m_frame_t_count(0),
|
||||
m_pixel_x(0),
|
||||
m_pixel_y(0),
|
||||
m_px_c_index(0),
|
||||
m_img(img),
|
||||
m_saneHandle(handle),
|
||||
m_invertColors(false),
|
||||
m_readStatus(READ_READY),
|
||||
// m_scanProgress(0),
|
||||
m_saneStartDone(false),
|
||||
m_imageResized(false)
|
||||
{
|
||||
m_px_colors[0] = 0;
|
||||
m_px_colors[1] = 0;
|
||||
m_px_colors[2] = 0;
|
||||
}
|
||||
|
||||
void KSanePreviewThread::setPreviewInverted(bool inverted)
|
||||
{
|
||||
m_invertColors = inverted;
|
||||
}
|
||||
|
||||
void KSanePreviewThread::cancelScan()
|
||||
{
|
||||
m_readStatus = READ_CANCEL;
|
||||
}
|
||||
|
||||
void KSanePreviewThread::run()
|
||||
{
|
||||
m_dataSize = 0;
|
||||
m_readStatus = READ_ON_GOING;
|
||||
m_saneStartDone = false;
|
||||
|
||||
// Start the scanning with sane_start
|
||||
status = sane_start(m_saneHandle);
|
||||
|
||||
if (status != SANE_STATUS_GOOD) {
|
||||
kDebug() << "sane_start=" << sane_strstatus(status);
|
||||
sane_cancel(m_saneHandle);
|
||||
m_readStatus = READ_ERROR;
|
||||
return;
|
||||
}
|
||||
|
||||
// Read image parameters
|
||||
status = sane_get_parameters(m_saneHandle, &m_params);
|
||||
if (status != SANE_STATUS_GOOD) {
|
||||
kDebug() << "sane_get_parameters=" << sane_strstatus(status);
|
||||
sane_cancel(m_saneHandle);
|
||||
m_readStatus = READ_ERROR;
|
||||
return;
|
||||
}
|
||||
|
||||
// calculate data size
|
||||
m_frameSize = m_params.lines * m_params.bytes_per_line;
|
||||
if ((m_params.format == SANE_FRAME_RED) ||
|
||||
(m_params.format == SANE_FRAME_GREEN) ||
|
||||
(m_params.format == SANE_FRAME_BLUE))
|
||||
{
|
||||
// this is unfortunately calculated again for every frame....
|
||||
m_dataSize = m_frameSize*3;
|
||||
}
|
||||
else {
|
||||
m_dataSize = m_frameSize;
|
||||
}
|
||||
|
||||
// create a new image if necessary
|
||||
if ((m_img->height() != m_params.lines) ||
|
||||
(m_img->width() != m_params.pixels_per_line))
|
||||
{
|
||||
// just hope that the frame size is not changed between different frames of the same image.
|
||||
if (m_params.lines > 0) {
|
||||
*m_img = QImage(m_params.pixels_per_line, m_params.lines, QImage::Format_RGB32);
|
||||
}
|
||||
else {
|
||||
// handscanners have the number of lines -1 -> make room for something
|
||||
*m_img = QImage(m_params.pixels_per_line, m_params.pixels_per_line, QImage::Format_RGB32);
|
||||
}
|
||||
m_img->fill(0xFFFFFFFF);
|
||||
}
|
||||
m_imageResized = false;
|
||||
m_pixel_x = 0;
|
||||
m_pixel_y = 0;
|
||||
m_frameRead = 0;
|
||||
m_px_c_index = 0;
|
||||
m_frame_t_count = 0;
|
||||
|
||||
// set the m_saneStartDone here so the new QImage gets allocated before updating the preview.
|
||||
m_saneStartDone = true;
|
||||
|
||||
|
||||
while (m_readStatus == READ_ON_GOING) {
|
||||
readData();
|
||||
}
|
||||
}
|
||||
|
||||
int KSanePreviewThread::scanProgress()
|
||||
{
|
||||
// handscanners have negative data size
|
||||
if (m_dataSize <= 0) return 0;
|
||||
|
||||
int bytesRead;
|
||||
|
||||
if (m_frameSize < m_dataSize) {
|
||||
bytesRead = m_frameRead + (m_frameSize * m_frame_t_count);
|
||||
}
|
||||
else {
|
||||
bytesRead = m_frameRead;
|
||||
}
|
||||
|
||||
return (int)(((float)bytesRead * 100.0)/m_dataSize);
|
||||
}
|
||||
|
||||
void KSanePreviewThread::readData()
|
||||
{
|
||||
SANE_Int readBytes;
|
||||
status = sane_read(m_saneHandle, m_readData, PREVIEW_READ_CHUNK_SIZE, &readBytes);
|
||||
|
||||
switch (status)
|
||||
{
|
||||
case SANE_STATUS_GOOD:
|
||||
// continue to parsing the data
|
||||
break;
|
||||
|
||||
case SANE_STATUS_EOF:
|
||||
// (handscanners have negative frame size)
|
||||
if (m_frameRead < m_frameSize) {
|
||||
kDebug() << "frameRead =" << m_frameRead << ", frameSize =" << m_frameSize;
|
||||
m_readStatus = READ_ERROR;
|
||||
return;
|
||||
}
|
||||
if (m_params.last_frame == SANE_TRUE) {
|
||||
// this is where it all ends well :)
|
||||
m_readStatus = READ_READY;
|
||||
return;
|
||||
}
|
||||
else {
|
||||
// start reading next frame
|
||||
SANE_Status status = sane_start(m_saneHandle);
|
||||
if (status != SANE_STATUS_GOOD) {
|
||||
kDebug() << "sane_start =" << sane_strstatus(status);
|
||||
m_readStatus = READ_ERROR;
|
||||
return;
|
||||
}
|
||||
status = sane_get_parameters(m_saneHandle, &m_params);
|
||||
if (status != SANE_STATUS_GOOD) {
|
||||
kDebug() << "sane_get_parameters =" << sane_strstatus(status);
|
||||
m_readStatus = READ_ERROR;
|
||||
sane_cancel(m_saneHandle);
|
||||
return;
|
||||
}
|
||||
//kDebug() << "New Frame";
|
||||
m_frameRead = 0;
|
||||
m_pixel_x = 0;
|
||||
m_pixel_y = 0;
|
||||
m_px_c_index = 0;
|
||||
m_frame_t_count++;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
kDebug() << "sane_read=" << status << "=" << sane_strstatus(status);
|
||||
m_readStatus = READ_ERROR;
|
||||
sane_cancel(m_saneHandle);
|
||||
return;
|
||||
}
|
||||
|
||||
copyToPreviewImg(readBytes);
|
||||
}
|
||||
|
||||
#define inc_pixel(x,y,ppl) { x++; if (x>=ppl) { y++; x=0;} }
|
||||
#define inc_color_index(index) { index++; if (index==3) index=0;}
|
||||
|
||||
#define index_red8_to_argb8(i) (i*4 + 2)
|
||||
#define index_red16_to_argb8(i) (i*2 + 2)
|
||||
|
||||
#define index_green8_to_argb8(i) (i*4 + 1)
|
||||
#define index_green16_to_argb8(i) (i*2 + 1)
|
||||
|
||||
#define index_blue8_to_argb8(i) (i*4)
|
||||
#define index_blue16_to_argb8(i) (i*2)
|
||||
|
||||
void KSanePreviewThread::copyToPreviewImg(int read_bytes)
|
||||
{
|
||||
QMutexLocker locker(&imgMutex);
|
||||
int index;
|
||||
uchar *imgBits = m_img->bits();
|
||||
if (m_invertColors) {
|
||||
if (m_params.depth >= 8) {
|
||||
for(int i=0; i<read_bytes; i++) {
|
||||
m_readData[i] = 255 - m_readData[i];
|
||||
}
|
||||
}
|
||||
if (m_params.depth == 1) {
|
||||
for(int i=0; i<read_bytes; i++) {
|
||||
m_readData[i] = ~m_readData[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
switch (m_params.format)
|
||||
{
|
||||
case SANE_FRAME_GRAY:
|
||||
if (m_params.depth == 1) {
|
||||
int i, j;
|
||||
for (i=0; i<read_bytes; i++) {
|
||||
if (m_pixel_y >= m_img->height()) {
|
||||
// resize the image
|
||||
*m_img = m_img->copy(0, 0, m_img->width(), m_img->height() + m_img->width());
|
||||
m_imageResized = true;
|
||||
}
|
||||
for (j=7; j>=0; --j) {
|
||||
if ((m_readData[i] & (1<<j)) == 0) {
|
||||
m_img->setPixel(m_pixel_x,
|
||||
m_pixel_y,
|
||||
qRgb(255,255,255));
|
||||
}
|
||||
else {
|
||||
m_img->setPixel(m_pixel_x,
|
||||
m_pixel_y,
|
||||
qRgb(0,0,0));
|
||||
}
|
||||
m_pixel_x++;
|
||||
if(m_pixel_x >= m_params.pixels_per_line) {
|
||||
m_pixel_x = 0;
|
||||
m_pixel_y++;
|
||||
break;
|
||||
}
|
||||
if (m_pixel_y >= m_params.lines) break;
|
||||
}
|
||||
m_frameRead++;
|
||||
}
|
||||
return;
|
||||
}
|
||||
else if (m_params.depth == 8) {
|
||||
for (int i=0; i<read_bytes; i++) {
|
||||
index = m_frameRead * 4;
|
||||
if ((index + 2) >m_img->numBytes()) {
|
||||
// resize the image
|
||||
*m_img = m_img->copy(0, 0, m_img->width(), m_img->height() + m_img->width());
|
||||
imgBits = m_img->bits();
|
||||
m_imageResized = true;
|
||||
}
|
||||
imgBits[index ] = m_readData[i];
|
||||
imgBits[index + 1] = m_readData[i];
|
||||
imgBits[index + 2] = m_readData[i];
|
||||
m_frameRead++;
|
||||
}
|
||||
return;
|
||||
}
|
||||
else if (m_params.depth == 16) {
|
||||
for (int i=0; i<read_bytes; i++) {
|
||||
if (m_frameRead%2 == 0) {
|
||||
index = m_frameRead * 2;
|
||||
if ((index + 2) > m_img->numBytes()) {
|
||||
// resize the image
|
||||
*m_img = m_img->copy(0, 0, m_img->width(), m_img->height() + m_img->width());
|
||||
imgBits = m_img->bits();
|
||||
m_imageResized = true;
|
||||
}
|
||||
imgBits[index ] = m_readData[i+1];
|
||||
imgBits[index + 1] = m_readData[i+1];
|
||||
imgBits[index + 2] = m_readData[i+1];
|
||||
}
|
||||
m_frameRead++;
|
||||
}
|
||||
return;
|
||||
}
|
||||
break;
|
||||
|
||||
case SANE_FRAME_RGB:
|
||||
if (m_params.depth == 8) {
|
||||
for (int i=0; i<read_bytes; i++) {
|
||||
m_px_colors[m_px_c_index] = m_readData[i];
|
||||
inc_color_index(m_px_c_index);
|
||||
m_frameRead++;
|
||||
if (m_px_c_index == 0) {
|
||||
if (m_pixel_y >= m_img->height()) {
|
||||
// resize the image
|
||||
*m_img = m_img->copy(0, 0, m_img->width(), m_img->height() + m_img->width());
|
||||
m_imageResized = true;
|
||||
}
|
||||
m_img->setPixel(m_pixel_x,
|
||||
m_pixel_y,
|
||||
qRgb(m_px_colors[0],
|
||||
m_px_colors[1],
|
||||
m_px_colors[2]));
|
||||
inc_pixel(m_pixel_x, m_pixel_y, m_params.pixels_per_line);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
else if (m_params.depth == 16) {
|
||||
for (int i=0; i<read_bytes; i++) {
|
||||
m_frameRead++;
|
||||
if (m_frameRead%2==0) {
|
||||
m_px_colors[m_px_c_index] = m_readData[i];
|
||||
inc_color_index(m_px_c_index);
|
||||
if (m_px_c_index == 0) {
|
||||
if (m_pixel_y >= m_img->height()) {
|
||||
// resize the image
|
||||
*m_img = m_img->copy(0, 0, m_img->width(), m_img->height() + m_img->width());
|
||||
m_imageResized = true;
|
||||
}
|
||||
m_img->setPixel(m_pixel_x,
|
||||
m_pixel_y,
|
||||
qRgb(m_px_colors[0],
|
||||
m_px_colors[1],
|
||||
m_px_colors[2]));
|
||||
inc_pixel(m_pixel_x, m_pixel_y, m_params.pixels_per_line);
|
||||
}
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
break;
|
||||
|
||||
case SANE_FRAME_RED:
|
||||
if (m_params.depth == 8) {
|
||||
for (int i=0; i<read_bytes; i++) {
|
||||
if (index_red8_to_argb8(m_frameRead) > m_img->numBytes()) {
|
||||
// resize the image
|
||||
*m_img = m_img->copy(0, 0, m_img->width(), m_img->height() + m_img->width());
|
||||
imgBits = m_img->bits();
|
||||
m_imageResized = true;
|
||||
}
|
||||
imgBits[index_red8_to_argb8(m_frameRead)] = m_readData[i];
|
||||
m_frameRead++;
|
||||
}
|
||||
return;
|
||||
}
|
||||
else if (m_params.depth == 16) {
|
||||
for (int i=0; i<read_bytes; i++) {
|
||||
if (m_frameRead%2 == 0) {
|
||||
if (index_red16_to_argb8(m_frameRead) > m_img->numBytes()) {
|
||||
// resize the image
|
||||
*m_img = m_img->copy(0, 0, m_img->width(), m_img->height() + m_img->width());
|
||||
imgBits = m_img->bits();
|
||||
m_imageResized = true;
|
||||
}
|
||||
imgBits[index_red16_to_argb8(m_frameRead)] = m_readData[i+1];
|
||||
}
|
||||
m_frameRead++;
|
||||
}
|
||||
return;
|
||||
}
|
||||
break;
|
||||
|
||||
case SANE_FRAME_GREEN:
|
||||
if (m_params.depth == 8) {
|
||||
for (int i=0; i<read_bytes; i++) {
|
||||
if (index_green8_to_argb8(m_frameRead) > m_img->numBytes()) {
|
||||
// resize the image
|
||||
*m_img = m_img->copy(0, 0, m_img->width(), m_img->height() + m_img->width());
|
||||
imgBits = m_img->bits();
|
||||
m_imageResized = true;
|
||||
}
|
||||
imgBits[index_green8_to_argb8(m_frameRead)] = m_readData[i];
|
||||
m_frameRead++;
|
||||
}
|
||||
return;
|
||||
}
|
||||
else if (m_params.depth == 16) {
|
||||
for (int i=0; i<read_bytes; i++) {
|
||||
if (m_frameRead%2 == 0) {
|
||||
if (index_green16_to_argb8(m_frameRead) > m_img->numBytes()) {
|
||||
// resize the image
|
||||
*m_img = m_img->copy(0, 0, m_img->width(), m_img->height() + m_img->width());
|
||||
imgBits = m_img->bits();
|
||||
m_imageResized = true;
|
||||
}
|
||||
imgBits[index_green16_to_argb8(m_frameRead)] = m_readData[i+1];
|
||||
}
|
||||
m_frameRead++;
|
||||
}
|
||||
return;
|
||||
}
|
||||
break;
|
||||
|
||||
case SANE_FRAME_BLUE:
|
||||
if (m_params.depth == 8) {
|
||||
for (int i=0; i<read_bytes; i++) {
|
||||
if (index_blue8_to_argb8(m_frameRead) > m_img->numBytes()) {
|
||||
// resize the image
|
||||
*m_img = m_img->copy(0, 0, m_img->width(), m_img->height() + m_img->width());
|
||||
imgBits = m_img->bits();
|
||||
m_imageResized = true;
|
||||
}
|
||||
imgBits[index_blue8_to_argb8(m_frameRead)] = m_readData[i];
|
||||
m_frameRead++;
|
||||
}
|
||||
return;
|
||||
}
|
||||
else if (m_params.depth == 16) {
|
||||
for (int i=0; i<read_bytes; i++) {
|
||||
if (m_frameRead%2 == 0) {
|
||||
if (index_blue16_to_argb8(m_frameRead) > m_img->numBytes()) {
|
||||
// resize the image
|
||||
*m_img = m_img->copy(0, 0, m_img->width(), m_img->height() + m_img->width());
|
||||
imgBits = m_img->bits();
|
||||
m_imageResized = true;
|
||||
}
|
||||
imgBits[index_blue16_to_argb8(m_frameRead)] = m_readData[i+1];
|
||||
}
|
||||
m_frameRead++;
|
||||
}
|
||||
return;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
kWarning() << "Format" << m_params.format
|
||||
<< "and depth" << m_params.format
|
||||
<< "is not yet suppoeted by libksane!";
|
||||
m_readStatus = READ_ERROR;
|
||||
return;
|
||||
}
|
||||
|
||||
bool KSanePreviewThread::saneStartDone()
|
||||
{
|
||||
return m_saneStartDone;
|
||||
}
|
||||
|
||||
bool KSanePreviewThread::imageResized()
|
||||
{
|
||||
if (m_imageResized) {
|
||||
m_imageResized = false;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
} // NameSpace KSaneIface
|
94
libksane/libksane/ksane_preview_thread.h
Normal file
94
libksane/libksane/ksane_preview_thread.h
Normal file
|
@ -0,0 +1,94 @@
|
|||
/* ============================================================
|
||||
*
|
||||
* This file is part of the KDE project
|
||||
*
|
||||
* Date : 2009-11-13
|
||||
* Description : Sane interface for KDE
|
||||
*
|
||||
* Copyright (C) 2009 by Kare Sars <kare dot sars at iki dot fi>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) version 3, or any
|
||||
* later version accepted by the membership of KDE e.V. (or its
|
||||
* successor approved by the membership of KDE e.V.), which shall
|
||||
* act as a proxy defined in Section 6 of version 3 of the license.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* ============================================================ */
|
||||
|
||||
#ifndef KSANE_PREVIEW_THREAD_H
|
||||
#define KSANE_PREVIEW_THREAD_H
|
||||
|
||||
// Sane includes
|
||||
extern "C"
|
||||
{
|
||||
#include <sane/saneopts.h>
|
||||
#include <sane/sane.h>
|
||||
}
|
||||
|
||||
#include <QThread>
|
||||
#include <QMutex>
|
||||
#include <QImage>
|
||||
|
||||
#define PREVIEW_READ_CHUNK_SIZE 100000
|
||||
|
||||
namespace KSaneIface
|
||||
{
|
||||
class KSanePreviewThread: public QThread
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
typedef enum
|
||||
{
|
||||
READ_ON_GOING,
|
||||
READ_ERROR,
|
||||
READ_CANCEL,
|
||||
READ_READY
|
||||
} ReadStatus;
|
||||
|
||||
KSanePreviewThread(SANE_Handle handle, QImage *img);
|
||||
void run();
|
||||
void setPreviewInverted(bool);
|
||||
void cancelScan();
|
||||
int scanProgress();
|
||||
bool saneStartDone();
|
||||
bool imageResized();
|
||||
|
||||
SANE_Status status;
|
||||
QMutex imgMutex;
|
||||
|
||||
private:
|
||||
void readData();
|
||||
void copyToPreviewImg(int readBytes);
|
||||
|
||||
SANE_Byte m_readData[PREVIEW_READ_CHUNK_SIZE];
|
||||
int m_frameSize;
|
||||
int m_frameRead;
|
||||
int m_dataSize;
|
||||
int m_frame_t_count;
|
||||
int m_pixel_x;
|
||||
int m_pixel_y;
|
||||
int m_px_colors[3];
|
||||
int m_px_c_index;
|
||||
SANE_Parameters m_params;
|
||||
QImage *m_img;
|
||||
SANE_Handle m_saneHandle;
|
||||
bool m_invertColors;
|
||||
ReadStatus m_readStatus;
|
||||
// int m_scanProgress;
|
||||
bool m_saneStartDone;
|
||||
bool m_imageResized;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
#endif
|
311
libksane/libksane/ksane_scan_thread.cpp
Normal file
311
libksane/libksane/ksane_scan_thread.cpp
Normal file
|
@ -0,0 +1,311 @@
|
|||
/* ============================================================
|
||||
*
|
||||
* This file is part of the KDE project
|
||||
*
|
||||
* Date : 2009-11-13
|
||||
* Description : Sane interface for KDE
|
||||
*
|
||||
* Copyright (C) 2009 by Kare Sars <kare dot sars at iki dot fi>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) version 3, or any
|
||||
* later version accepted by the membership of KDE e.V. (or its
|
||||
* successor approved by the membership of KDE e.V.), which shall
|
||||
* act as a proxy defined in Section 6 of version 3 of the license.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* ============================================================ */
|
||||
|
||||
// Local includes
|
||||
#include "ksane_scan_thread.moc"
|
||||
|
||||
#include <KDebug>
|
||||
|
||||
namespace KSaneIface
|
||||
{
|
||||
|
||||
|
||||
KSaneScanThread::KSaneScanThread(SANE_Handle handle, QByteArray *data):
|
||||
QThread(),
|
||||
m_data(data),
|
||||
m_saneHandle(handle),
|
||||
m_frameSize(0),
|
||||
m_frameRead(0),
|
||||
m_frame_t_count(0),
|
||||
m_dataSize(0),
|
||||
m_saneStatus(SANE_STATUS_GOOD),
|
||||
m_readStatus(READ_READY),
|
||||
m_invertColors(false),
|
||||
m_saneStartDone(false)
|
||||
{}
|
||||
|
||||
void KSaneScanThread::setImageInverted(bool inverted)
|
||||
{
|
||||
m_invertColors = inverted;
|
||||
}
|
||||
|
||||
SANE_Status KSaneScanThread::saneStatus()
|
||||
{
|
||||
return m_saneStatus;
|
||||
}
|
||||
|
||||
KSaneScanThread::ReadStatus KSaneScanThread::frameStatus()
|
||||
{
|
||||
return m_readStatus;
|
||||
}
|
||||
|
||||
void KSaneScanThread::cancelScan()
|
||||
{
|
||||
m_readStatus = READ_CANCEL;
|
||||
}
|
||||
|
||||
int KSaneScanThread::scanProgress()
|
||||
{
|
||||
if (m_dataSize == 0) return 0;
|
||||
|
||||
int bytesRead;
|
||||
|
||||
if (m_frameSize < m_dataSize) {
|
||||
bytesRead = m_frameRead + (m_frameSize * m_frame_t_count);
|
||||
}
|
||||
else {
|
||||
bytesRead = m_frameRead;
|
||||
}
|
||||
return (int)(((float)bytesRead * 100.0)/m_dataSize);
|
||||
}
|
||||
|
||||
SANE_Parameters KSaneScanThread::saneParameters()
|
||||
{
|
||||
return m_params;
|
||||
}
|
||||
|
||||
void KSaneScanThread::run()
|
||||
{
|
||||
m_dataSize = 0;
|
||||
m_readStatus = READ_ON_GOING;
|
||||
m_saneStartDone = false;
|
||||
|
||||
// Start the scanning with sane_start
|
||||
m_saneStatus = sane_start(m_saneHandle);
|
||||
|
||||
m_saneStartDone = true;
|
||||
|
||||
if (m_readStatus == READ_CANCEL) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_saneStatus != SANE_STATUS_GOOD) {
|
||||
kDebug() << "sane_start=" << sane_strstatus(m_saneStatus);
|
||||
m_readStatus = READ_ERROR;
|
||||
// oneFinalScanDone() does the sane_cancel()
|
||||
return;
|
||||
}
|
||||
|
||||
// Read image parameters
|
||||
m_saneStatus = sane_get_parameters(m_saneHandle, &m_params);
|
||||
if (m_saneStatus != SANE_STATUS_GOOD) {
|
||||
kDebug() << "sane_get_parameters=" << sane_strstatus(m_saneStatus);
|
||||
m_readStatus = READ_ERROR;
|
||||
// oneFinalScanDone() does the sane_cancel()
|
||||
return;
|
||||
}
|
||||
|
||||
// calculate data size
|
||||
m_frameSize = m_params.lines * m_params.bytes_per_line;
|
||||
if ((m_params.format == SANE_FRAME_RED) ||
|
||||
(m_params.format == SANE_FRAME_GREEN) ||
|
||||
(m_params.format == SANE_FRAME_BLUE))
|
||||
{
|
||||
m_dataSize = m_frameSize*3;
|
||||
}
|
||||
else {
|
||||
m_dataSize = m_frameSize;
|
||||
}
|
||||
|
||||
m_data->clear();
|
||||
if (m_dataSize > 0) {
|
||||
m_data->reserve(m_dataSize);
|
||||
}
|
||||
|
||||
m_frameRead = 0;
|
||||
m_frame_t_count = 0;
|
||||
m_readStatus = READ_ON_GOING;
|
||||
while (m_readStatus == READ_ON_GOING) {
|
||||
readData();
|
||||
}
|
||||
}
|
||||
|
||||
void KSaneScanThread::readData()
|
||||
{
|
||||
SANE_Int readBytes = 0;
|
||||
m_saneStatus = sane_read(m_saneHandle, m_readData, SCAN_READ_CHUNK_SIZE, &readBytes);
|
||||
|
||||
switch (m_saneStatus)
|
||||
{
|
||||
case SANE_STATUS_GOOD:
|
||||
// continue to parsing the data
|
||||
break;
|
||||
|
||||
case SANE_STATUS_EOF:
|
||||
if (m_frameRead < m_frameSize) {
|
||||
kDebug() << "frameRead =" << m_frameRead << ", frameSize =" << m_frameSize << "readBytes =" << readBytes;
|
||||
if ((readBytes > 0) && ((m_frameRead + readBytes) <= m_frameSize)) {
|
||||
kDebug() << "This is not a standard compliant backend";
|
||||
copyToScanData(readBytes);
|
||||
}
|
||||
m_readStatus = READ_READY; // It is better to return a broken image than nothing
|
||||
return;
|
||||
}
|
||||
if (m_params.last_frame == SANE_TRUE) {
|
||||
// this is where it all ends well :)
|
||||
m_readStatus = READ_READY;
|
||||
return;
|
||||
}
|
||||
else {
|
||||
// start reading next frame
|
||||
m_saneStatus = sane_start(m_saneHandle);
|
||||
if (m_saneStatus != SANE_STATUS_GOOD) {
|
||||
kDebug() << "sane_start =" << sane_strstatus(m_saneStatus);
|
||||
m_readStatus = READ_ERROR;
|
||||
return;
|
||||
}
|
||||
m_saneStatus = sane_get_parameters(m_saneHandle, &m_params);
|
||||
if (m_saneStatus != SANE_STATUS_GOOD) {
|
||||
kDebug() << "sane_get_parameters =" << sane_strstatus(m_saneStatus);
|
||||
m_readStatus = READ_ERROR;
|
||||
sane_cancel(m_saneHandle);
|
||||
return;
|
||||
}
|
||||
//kDebug() << "New Frame";
|
||||
m_frameRead = 0;
|
||||
m_frame_t_count++;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
kDebug() << "sane_read=" << m_saneStatus << "=" << sane_strstatus(m_saneStatus);
|
||||
m_readStatus = READ_ERROR;
|
||||
sane_cancel(m_saneHandle);
|
||||
return;
|
||||
}
|
||||
|
||||
copyToScanData(readBytes);
|
||||
}
|
||||
|
||||
#define index_red8_to_rgb8(i) (i*3)
|
||||
#define index_red16_to_rgb16(i) ((i/2)*6 + i%2)
|
||||
|
||||
#define index_green8_to_rgb8(i) (i*3 + 1)
|
||||
#define index_green16_to_rgb16(i) ((i/2)*6 + i%2 + 2)
|
||||
|
||||
#define index_blue8_to_rgb8(i) (i*3 + 2)
|
||||
#define index_blue16_to_rgb16(i) ((i/2)*6 + i%2 + 4)
|
||||
|
||||
void KSaneScanThread::copyToScanData(int readBytes)
|
||||
{
|
||||
if (m_invertColors) {
|
||||
if (m_params.depth == 16) {
|
||||
//if (readBytes%2) qDebug() << "readBytes=" << readBytes;
|
||||
quint16 *u16ptr = reinterpret_cast<quint16*>(m_readData);
|
||||
for(int i=0; i<readBytes/2; i++) {
|
||||
u16ptr[i] = 0xFFFF - u16ptr[i];
|
||||
}
|
||||
}
|
||||
else if (m_params.depth == 8) {
|
||||
for(int i=0; i<readBytes; i++) {
|
||||
m_readData[i] = 0xFF - m_readData[i];
|
||||
}
|
||||
}
|
||||
else if (m_params.depth == 1) {
|
||||
for(int i=0; i<readBytes; i++) {
|
||||
m_readData[i] = ~m_readData[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
switch (m_params.format)
|
||||
{
|
||||
case SANE_FRAME_GRAY:
|
||||
m_data->append((const char*)m_readData, readBytes);
|
||||
m_frameRead += readBytes;
|
||||
return;
|
||||
case SANE_FRAME_RGB:
|
||||
if (m_params.depth == 1) {
|
||||
break;
|
||||
}
|
||||
m_data->append((const char*)m_readData, readBytes);
|
||||
m_frameRead += readBytes;
|
||||
return;
|
||||
|
||||
case SANE_FRAME_RED:
|
||||
if (m_params.depth == 8) {
|
||||
for (int i=0; i<readBytes; i++) {
|
||||
(*m_data)[index_red8_to_rgb8(m_frameRead)] = m_readData[i];
|
||||
m_frameRead++;
|
||||
}
|
||||
return;
|
||||
}
|
||||
else if (m_params.depth == 16) {
|
||||
for (int i=0; i<readBytes; i++) {
|
||||
(*m_data)[index_red16_to_rgb16(m_frameRead)] = m_readData[i];
|
||||
m_frameRead++;
|
||||
}
|
||||
return;
|
||||
}
|
||||
break;
|
||||
|
||||
case SANE_FRAME_GREEN:
|
||||
if (m_params.depth == 8) {
|
||||
for (int i=0; i<readBytes; i++) {
|
||||
(*m_data)[index_green8_to_rgb8(m_frameRead)] = m_readData[i];
|
||||
m_frameRead++;
|
||||
}
|
||||
return;
|
||||
}
|
||||
else if (m_params.depth == 16) {
|
||||
for (int i=0; i<readBytes; i++) {
|
||||
(*m_data)[index_green16_to_rgb16(m_frameRead)] = m_readData[i];
|
||||
m_frameRead++;
|
||||
}
|
||||
return;
|
||||
}
|
||||
break;
|
||||
|
||||
case SANE_FRAME_BLUE:
|
||||
if (m_params.depth == 8) {
|
||||
for (int i=0; i<readBytes; i++) {
|
||||
(*m_data)[index_blue8_to_rgb8(m_frameRead)] = m_readData[i];
|
||||
m_frameRead++;
|
||||
}
|
||||
return;
|
||||
}
|
||||
else if (m_params.depth == 16) {
|
||||
for (int i=0; i<readBytes; i++) {
|
||||
(*m_data)[index_blue16_to_rgb16(m_frameRead)] = m_readData[i];
|
||||
m_frameRead++;
|
||||
}
|
||||
return;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
kDebug() << "Format" << m_params.format
|
||||
<< "and depth" << m_params.format
|
||||
<< "is not yet suppoeted by libksane!";
|
||||
m_readStatus = READ_ERROR;
|
||||
return;
|
||||
}
|
||||
|
||||
bool KSaneScanThread::saneStartDone()
|
||||
{
|
||||
return m_saneStartDone;
|
||||
}
|
||||
|
||||
} // NameSpace KSaneIface
|
88
libksane/libksane/ksane_scan_thread.h
Normal file
88
libksane/libksane/ksane_scan_thread.h
Normal file
|
@ -0,0 +1,88 @@
|
|||
/* ============================================================
|
||||
*
|
||||
* This file is part of the KDE project
|
||||
*
|
||||
* Date : 2009-11-13
|
||||
* Description : Sane interface for KDE
|
||||
*
|
||||
* Copyright (C) 2009 by Kare Sars <kare dot sars at iki dot fi>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) version 3, or any
|
||||
* later version accepted by the membership of KDE e.V. (or its
|
||||
* successor approved by the membership of KDE e.V.), which shall
|
||||
* act as a proxy defined in Section 6 of version 3 of the license.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* ============================================================ */
|
||||
|
||||
#ifndef KSANE_SCAN_THREAD_H
|
||||
#define KSANE_SCAN_THREAD_H
|
||||
|
||||
// Sane includes
|
||||
extern "C"
|
||||
{
|
||||
#include <sane/saneopts.h>
|
||||
#include <sane/sane.h>
|
||||
}
|
||||
|
||||
#include <QThread>
|
||||
#include <QByteArray>
|
||||
|
||||
#define SCAN_READ_CHUNK_SIZE 100000
|
||||
|
||||
namespace KSaneIface
|
||||
{
|
||||
class KSaneScanThread: public QThread
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
typedef enum
|
||||
{
|
||||
READ_ON_GOING,
|
||||
READ_ERROR,
|
||||
READ_CANCEL,
|
||||
READ_READY
|
||||
} ReadStatus;
|
||||
|
||||
KSaneScanThread(SANE_Handle handle, QByteArray *data);
|
||||
void run();
|
||||
void setImageInverted(bool);
|
||||
void cancelScan();
|
||||
int scanProgress();
|
||||
bool saneStartDone();
|
||||
|
||||
ReadStatus frameStatus();
|
||||
SANE_Status saneStatus();
|
||||
SANE_Parameters saneParameters();
|
||||
|
||||
private:
|
||||
void readData();
|
||||
void copyToScanData(int readBytes);
|
||||
|
||||
SANE_Byte m_readData[SCAN_READ_CHUNK_SIZE];
|
||||
QByteArray *m_data;
|
||||
SANE_Handle m_saneHandle;
|
||||
SANE_Parameters m_params;
|
||||
int m_frameSize;
|
||||
int m_frameRead;
|
||||
int m_frame_t_count;
|
||||
int m_dataSize;
|
||||
SANE_Status m_saneStatus;
|
||||
ReadStatus m_readStatus;
|
||||
bool m_invertColors;
|
||||
bool m_saneStartDone;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
#endif
|
1102
libksane/libksane/ksane_viewer.cpp
Normal file
1102
libksane/libksane/ksane_viewer.cpp
Normal file
File diff suppressed because it is too large
Load diff
128
libksane/libksane/ksane_viewer.h
Normal file
128
libksane/libksane/ksane_viewer.h
Normal file
|
@ -0,0 +1,128 @@
|
|||
/* ============================================================
|
||||
*
|
||||
* This file is part of the KDE project
|
||||
*
|
||||
* Date : 2008-11-15
|
||||
* Description : Preview image viewer that can handle a selection.
|
||||
*
|
||||
* Copyright (C) 2008 by Kare Sars <kare dot sars at iki dot fi>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) version 3, or any
|
||||
* later version accepted by the membership of KDE e.V. (or its
|
||||
* successor approved by the membership of KDE e.V.), which shall
|
||||
* act as a proxy defined in Section 6 of version 3 of the license.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* ============================================================ */
|
||||
|
||||
#ifndef KSANE_VIEWER_H
|
||||
#define KSANE_VIEWER_H
|
||||
|
||||
#include <QGraphicsView>
|
||||
#include <QWheelEvent>
|
||||
|
||||
namespace KSaneIface
|
||||
{
|
||||
|
||||
class KSaneViewer : public QGraphicsView
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit KSaneViewer(QImage *img, QWidget *parent = 0);
|
||||
~KSaneViewer();
|
||||
|
||||
void setQImage(QImage *img);
|
||||
void updateImage();
|
||||
/** Find selections in the picture
|
||||
* \param area this parameter determine the area of the reduced sized image. */
|
||||
void findSelections(float area = 10000.0);
|
||||
|
||||
virtual QSize sizeHint() const;
|
||||
|
||||
public Q_SLOTS:
|
||||
|
||||
void setTLX(float ratio);
|
||||
void setTLY(float ratio);
|
||||
void setBRX(float ratio);
|
||||
void setBRY(float ratio);
|
||||
|
||||
/** This function is used to set a selection without the user setting it.
|
||||
* \note all parameters must be in the range 0.0 -> 1.0.
|
||||
* \param tl_x is the x coordinate of the top left corner 0=0 1=image with.
|
||||
* \param tl_y is the y coordinate of the top left corner 0=0 1=image height.
|
||||
* \param br_x is the x coordinate of the bottom right corner 0=0 1=image with.
|
||||
* \param br_y is the y coordinate of the bottom right corner 0=0 1=image height. */
|
||||
void setSelection(float tl_x, float tl_y, float br_x, float br_y);
|
||||
void clearActiveSelection();
|
||||
void clearSavedSelections();
|
||||
void clearSelections();
|
||||
|
||||
/** This function is used to darken everything except what is inside the given area.
|
||||
* \note all parameters must be in the range 0.0 -> 1.0.
|
||||
* \param tl_x is the x coordinate of the top left corner 0=0 1=image with.
|
||||
* \param tl_y is the y coordinate of the top left corner 0=0 1=image height.
|
||||
* \param br_x is the x coordinate of the bottom right corner 0=0 1=image with.
|
||||
* \param br_y is the y coordinate of the bottom right corner 0=0 1=image height. */
|
||||
void setHighlightArea(float tl_x, float tl_y, float br_x, float br_y);
|
||||
|
||||
/** This function sets the percentage of the highlighted area that is visible. The rest is hidden.
|
||||
* \param percentage is the percentage of the highlighted area that is shown.
|
||||
* \param hideColor is the color to use to hide the highlighted area of the image.*/
|
||||
void setHighlightShown(int percentage, QColor hideColor = Qt::white);
|
||||
|
||||
/** This function removes the highlight area. */
|
||||
void clearHighlight();
|
||||
|
||||
void zoomIn();
|
||||
void zoomOut();
|
||||
void zoomSel();
|
||||
void zoom2Fit();
|
||||
|
||||
int selListSize();
|
||||
/* This function returns the active visible selection in index 0 and after that the "saved" ones */
|
||||
bool selectionAt(int index, float &tl_x, float &tl_y, float &br_x, float &br_y);
|
||||
|
||||
Q_SIGNALS:
|
||||
void newSelection(float tl_x, float tl_y, float br_x, float br_y);
|
||||
|
||||
protected:
|
||||
void wheelEvent(QWheelEvent *e);
|
||||
void mousePressEvent(QMouseEvent *e);
|
||||
void mouseReleaseEvent(QMouseEvent *e);
|
||||
void mouseMoveEvent(QMouseEvent *e);
|
||||
void drawBackground(QPainter *painter, const QRectF &rect);
|
||||
|
||||
private:
|
||||
void updateSelVisibility();
|
||||
void updateHighlight();
|
||||
bool activeSelection(float &tl_x, float &tl_y, float &br_x, float &br_y);
|
||||
void refineSelections(int pixelMargin);
|
||||
|
||||
// fromRow is the row to start the iterations from. fromRow can be grater than toRow.
|
||||
// rowStart is the x1 coordinate of the row
|
||||
// all parameters are corrected to be valid pixel indexes,
|
||||
// but start must be < end
|
||||
int refineRow(int fromRow, int toRow, int rowStart, int rowEnd);
|
||||
int refineColumn(int fromCol, int toCol, int colStart, int colEnd);
|
||||
|
||||
struct Private;
|
||||
Private * const d;
|
||||
|
||||
};
|
||||
|
||||
} // NameSpace KSaneIface
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
52
libksane/libksane/ksane_viewer_test.cpp
Normal file
52
libksane/libksane/ksane_viewer_test.cpp
Normal file
|
@ -0,0 +1,52 @@
|
|||
/* ============================================================
|
||||
*
|
||||
* This file is part of the KDE project
|
||||
*
|
||||
* Date : 2010-03-17
|
||||
* Description : Preview image viewer that can handle a selection.
|
||||
*
|
||||
* Copyright (C) 2010 by Kare Sars <kare dot sars at iki dot fi>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) version 3, or any
|
||||
* later version accepted by the membership of KDE e.V. (or its
|
||||
* successor approved by the membership of KDE e.V.), which shall
|
||||
* act as a proxy defined in Section 6 of version 3 of the license.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* ============================================================ */
|
||||
|
||||
#include "ksane_viewer.h"
|
||||
|
||||
#include <KDebug>
|
||||
#include <QApplication>
|
||||
|
||||
int main (int argc, char *argv[])
|
||||
{
|
||||
QApplication app(argc, argv);
|
||||
|
||||
if (argc != 2) {
|
||||
kDebug() << "An image filename is needed.";
|
||||
return 1;
|
||||
}
|
||||
QImage img(argv[1]);
|
||||
|
||||
KSaneIface::KSaneViewer viewer(&img);
|
||||
|
||||
viewer.findSelections();
|
||||
|
||||
viewer.show();
|
||||
|
||||
viewer.zoom2Fit();
|
||||
|
||||
return app.exec();
|
||||
}
|
931
libksane/libksane/ksane_widget.cpp
Normal file
931
libksane/libksane/ksane_widget.cpp
Normal file
|
@ -0,0 +1,931 @@
|
|||
/* ============================================================
|
||||
*
|
||||
* This file is part of the KDE project
|
||||
*
|
||||
* Date : 2009-01-24
|
||||
* Description : Sane interface for KDE
|
||||
*
|
||||
* Copyright (C) 2007-2010 by Kare Sars <kare dot sars at iki dot fi>
|
||||
* Copyright (C) 2009 by Matthias Nagl <matthias at nagl dot info>
|
||||
* Copyright (C) 2009 by Grzegorz Kurtyka <grzegorz dot kurtyka at gmail dot com>
|
||||
* Copyright (C) 2007-2008 by Gilles Caulier <caulier dot gilles at gmail dot com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) version 3, or any
|
||||
* later version accepted by the membership of KDE e.V. (or its
|
||||
* successor approved by the membership of KDE e.V.), which shall
|
||||
* act as a proxy defined in Section 6 of version 3 of the license.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* ============================================================ */
|
||||
|
||||
#include "ksane.h"
|
||||
#include "ksane.moc"
|
||||
|
||||
#include <unistd.h>
|
||||
|
||||
// Qt includes
|
||||
#include <QApplication>
|
||||
#include <QVarLengthArray>
|
||||
#include <QLabel>
|
||||
#include <QSplitter>
|
||||
#include <QMutex>
|
||||
#include <QPointer>
|
||||
|
||||
// KDE includes
|
||||
#include <kpassworddialog.h>
|
||||
#include <kwallet.h>
|
||||
#include <kpushbutton.h>
|
||||
|
||||
// Local includes
|
||||
#include "ksane_widget_private.h"
|
||||
#include "ksane_option.h"
|
||||
#include "ksane_opt_button.h"
|
||||
#include "ksane_opt_checkbox.h"
|
||||
#include "ksane_opt_combo.h"
|
||||
#include "ksane_opt_entry.h"
|
||||
#include "ksane_opt_fslider.h"
|
||||
#include "ksane_opt_gamma.h"
|
||||
#include "ksane_opt_slider.h"
|
||||
#include "ksane_device_dialog.h"
|
||||
#include "labeled_gamma.h"
|
||||
|
||||
namespace KSaneIface
|
||||
{
|
||||
static int s_objectCount = 0;
|
||||
static QMutex s_objectMutex;
|
||||
|
||||
static const QString InvetColorsOption = QString("KSane::InvertColors");
|
||||
|
||||
KSaneWidget::KSaneWidget(QWidget* parent)
|
||||
: QWidget(parent), d(new KSaneWidgetPrivate(this))
|
||||
{
|
||||
SANE_Int version;
|
||||
SANE_Status status;
|
||||
|
||||
//kDebug() << "The language is:" << KGlobal::locale()->language();
|
||||
//kDebug() << "Languagelist" << KGlobal::locale()->languageList();
|
||||
KGlobal::locale()->insertCatalog("libksane");
|
||||
KGlobal::locale()->insertCatalog("sane-backends");
|
||||
|
||||
s_objectMutex.lock();
|
||||
s_objectCount++;
|
||||
|
||||
if (s_objectCount == 1) {
|
||||
// only call sane init for the first instance
|
||||
status = sane_init(&version, &KSaneAuth::authorization);
|
||||
if (status != SANE_STATUS_GOOD) {
|
||||
kDebug() << "libksane: sane_init() failed("
|
||||
<< sane_strstatus(status) << ")";
|
||||
}
|
||||
else {
|
||||
//kDebug() << "Sane Version = "
|
||||
// << SANE_VERSION_MAJOR(version) << "."
|
||||
// << SANE_VERSION_MINORparent(version) << "."
|
||||
// << SANE_VERSION_BUILD(version);
|
||||
}
|
||||
}
|
||||
s_objectMutex.unlock();
|
||||
|
||||
// read the device list to get a list of vendor and model info
|
||||
d->m_findDevThread->start();
|
||||
|
||||
d->m_readValsTmr.setSingleShot(true);
|
||||
connect(&d->m_readValsTmr, SIGNAL(timeout()), d, SLOT(valReload()));
|
||||
|
||||
d->m_updProgressTmr.setSingleShot(false);
|
||||
d->m_updProgressTmr.setInterval(300);
|
||||
connect(&d->m_updProgressTmr, SIGNAL(timeout()), d, SLOT(updateProgress()));
|
||||
|
||||
// Create the static UI
|
||||
// create the preview
|
||||
d->m_previewViewer = new KSaneViewer(&(d->m_previewImg), this);
|
||||
connect(d->m_previewViewer, SIGNAL(newSelection(float,float,float,float)),
|
||||
d, SLOT(handleSelection(float,float,float,float)));
|
||||
|
||||
|
||||
d->m_warmingUp = new QLabel;
|
||||
d->m_warmingUp->setText(i18n("Waiting for the scan to start."));
|
||||
d->m_warmingUp->setAlignment(Qt::AlignCenter);
|
||||
d->m_warmingUp->setAutoFillBackground(true);
|
||||
d->m_warmingUp->setBackgroundRole(QPalette::Highlight);
|
||||
//d->m_warmingUp->setForegroundRole(QPalette::HighlightedText);
|
||||
d->m_warmingUp->hide();
|
||||
|
||||
d->m_progressBar = new QProgressBar;
|
||||
d->m_progressBar->setMaximum(100);
|
||||
|
||||
d->m_cancelBtn = new KPushButton;
|
||||
d->m_cancelBtn->setIcon(KIcon("process-stop"));
|
||||
d->m_cancelBtn->setToolTip(i18n("Cancel current scan operation"));
|
||||
connect(d->m_cancelBtn, SIGNAL(clicked()), this, SLOT(scanCancel()));
|
||||
|
||||
d->m_activityFrame = new QWidget;
|
||||
QHBoxLayout *progress_lay = new QHBoxLayout(d->m_activityFrame);
|
||||
progress_lay->setContentsMargins(0,0,0,0);
|
||||
progress_lay->addWidget(d->m_progressBar, 100);
|
||||
progress_lay->addWidget(d->m_cancelBtn, 0);
|
||||
d->m_activityFrame->hide();
|
||||
|
||||
d->m_zInBtn = new QToolButton(this);
|
||||
d->m_zInBtn->setAutoRaise(true);
|
||||
d->m_zInBtn->setIcon(KIcon("zoom-in"));
|
||||
d->m_zInBtn->setToolTip(i18n("Zoom In"));
|
||||
connect(d->m_zInBtn, SIGNAL(clicked()), d->m_previewViewer, SLOT(zoomIn()));
|
||||
|
||||
d->m_zOutBtn = new QToolButton(this);
|
||||
d->m_zOutBtn->setAutoRaise(true);
|
||||
d->m_zOutBtn->setIcon(KIcon("zoom-out"));
|
||||
d->m_zOutBtn->setToolTip(i18n("Zoom Out"));
|
||||
connect(d->m_zOutBtn, SIGNAL(clicked()), d->m_previewViewer, SLOT(zoomOut()));
|
||||
|
||||
d->m_zSelBtn = new QToolButton(this);
|
||||
d->m_zSelBtn->setAutoRaise(true);
|
||||
d->m_zSelBtn->setIcon(KIcon("zoom-fit-best"));
|
||||
d->m_zSelBtn->setToolTip(i18n("Zoom to Selection"));
|
||||
connect(d->m_zSelBtn, SIGNAL(clicked()), d->m_previewViewer, SLOT(zoomSel()));
|
||||
|
||||
d->m_zFitBtn = new QToolButton(this);
|
||||
d->m_zFitBtn->setAutoRaise(true);
|
||||
d->m_zFitBtn->setIcon(KIcon("document-preview"));
|
||||
d->m_zFitBtn->setToolTip(i18n("Zoom to Fit"));
|
||||
connect(d->m_zFitBtn, SIGNAL(clicked()), d->m_previewViewer, SLOT(zoom2Fit()));
|
||||
|
||||
d->m_clearSelBtn = new QToolButton(this);
|
||||
d->m_clearSelBtn->setAutoRaise(true);
|
||||
d->m_clearSelBtn->setIcon(KIcon("edit-clear"));
|
||||
d->m_clearSelBtn->setToolTip(i18n("Clear Selections"));
|
||||
connect(d->m_clearSelBtn, SIGNAL(clicked()), d->m_previewViewer, SLOT(clearSelections()));
|
||||
|
||||
d->m_prevBtn = new KPushButton(this);
|
||||
d->m_prevBtn->setIcon(KIcon("document-import"));
|
||||
d->m_prevBtn->setToolTip(i18n("Scan Preview Image"));
|
||||
d->m_prevBtn->setText(i18nc("Preview button text", "Preview"));
|
||||
connect(d->m_prevBtn, SIGNAL(clicked()), d, SLOT(startPreviewScan()));
|
||||
|
||||
d->m_scanBtn = new KPushButton(this);
|
||||
d->m_scanBtn->setIcon(KIcon("document-save"));
|
||||
d->m_scanBtn->setToolTip(i18n("Scan Final Image"));
|
||||
d->m_scanBtn->setText(i18nc("Final scan button text", "Scan"));
|
||||
d->m_scanBtn->setFocus(Qt::OtherFocusReason);
|
||||
connect(d->m_scanBtn, SIGNAL(clicked()), d, SLOT(startFinalScan()));
|
||||
|
||||
d->m_btnFrame = new QWidget;
|
||||
QHBoxLayout *btn_lay = new QHBoxLayout(d->m_btnFrame);
|
||||
btn_lay->setContentsMargins(0,0,0,0);
|
||||
btn_lay->addWidget(d->m_zInBtn);
|
||||
btn_lay->addWidget(d->m_zOutBtn);
|
||||
btn_lay->addWidget(d->m_zSelBtn);
|
||||
btn_lay->addWidget(d->m_zFitBtn);
|
||||
btn_lay->addWidget(d->m_clearSelBtn);
|
||||
btn_lay->addStretch(100);
|
||||
btn_lay->addWidget(d->m_prevBtn);
|
||||
btn_lay->addWidget(d->m_scanBtn);
|
||||
|
||||
// calculate the height of the waiting/scanning/buttons frames to avoid jumpiness.
|
||||
int minHeight = d->m_btnFrame->sizeHint().height();
|
||||
if (d->m_activityFrame->sizeHint().height() > minHeight) minHeight = d->m_activityFrame->sizeHint().height();
|
||||
if (d->m_warmingUp->sizeHint().height() > minHeight) minHeight = d->m_warmingUp->sizeHint().height();
|
||||
d->m_btnFrame->setMinimumHeight(minHeight);
|
||||
d->m_activityFrame->setMinimumHeight(minHeight);
|
||||
d->m_warmingUp->setMinimumHeight(minHeight);
|
||||
|
||||
d->m_previewFrame = new QWidget;
|
||||
QVBoxLayout *preview_layout = new QVBoxLayout(d->m_previewFrame);
|
||||
preview_layout->setContentsMargins(0,0,0,0);
|
||||
preview_layout->addWidget(d->m_previewViewer, 100);
|
||||
preview_layout->addWidget(d->m_warmingUp, 0);
|
||||
preview_layout->addWidget(d->m_activityFrame, 0);
|
||||
preview_layout->addWidget(d->m_btnFrame, 0);
|
||||
|
||||
// Create Options Widget
|
||||
d->m_optsTabWidget = new KTabWidget;
|
||||
|
||||
// Add the basic options tab
|
||||
d->m_basicScrollA = new QScrollArea;
|
||||
d->m_basicScrollA->setWidgetResizable(true);
|
||||
d->m_basicScrollA->setFrameShape(QFrame::NoFrame);
|
||||
d->m_optsTabWidget->addTab(d->m_basicScrollA, i18n("Basic Options"));
|
||||
|
||||
// Add the other options tab
|
||||
d->m_otherScrollA = new QScrollArea;
|
||||
d->m_otherScrollA->setWidgetResizable(true);
|
||||
d->m_otherScrollA->setFrameShape(QFrame::NoFrame);
|
||||
d->m_optsTabWidget->addTab(d->m_otherScrollA, i18n("Scanner Specific Options"));
|
||||
|
||||
|
||||
d->m_splitter = new QSplitter(this);
|
||||
d->m_splitter->addWidget(d->m_optsTabWidget);
|
||||
d->m_splitter->setStretchFactor(0,0);
|
||||
d->m_splitter->addWidget(d->m_previewFrame);
|
||||
d->m_splitter->setStretchFactor(1,100);
|
||||
|
||||
d->m_optionsCollapser = new SplitterCollapser(d->m_splitter, d->m_optsTabWidget);
|
||||
|
||||
QHBoxLayout *base_layout = new QHBoxLayout(this);
|
||||
base_layout->addWidget(d->m_splitter);
|
||||
base_layout->setContentsMargins(0,0,0,0);
|
||||
|
||||
// disable the interface in case no device is opened.
|
||||
d->m_optsTabWidget->setDisabled(true);
|
||||
d->m_previewViewer->setDisabled(true);
|
||||
d->m_btnFrame->setDisabled(true);
|
||||
|
||||
}
|
||||
|
||||
KSaneWidget::~KSaneWidget()
|
||||
{
|
||||
while (!closeDevice()) usleep(1000);
|
||||
// wait for any thread to exit
|
||||
|
||||
s_objectMutex.lock();
|
||||
s_objectCount--;
|
||||
if (s_objectCount <= 0) {
|
||||
// only delete the find-devices and authorization singletons and call sane_exit
|
||||
// if this is the last instance
|
||||
delete d->m_findDevThread;
|
||||
delete d->m_auth;
|
||||
sane_exit();
|
||||
}
|
||||
s_objectMutex.unlock();
|
||||
delete d;
|
||||
}
|
||||
|
||||
QString KSaneWidget::vendor() const
|
||||
{
|
||||
d->m_findDevThread->wait();
|
||||
d->devListUpdated(); // this is just a wrapped if (m_vendor.isEmpty()) statement if the vendor is known
|
||||
// devListUpdated here is to ensure that we do not come in between finished and the devListUpdated slot
|
||||
|
||||
return d->m_vendor;
|
||||
}
|
||||
QString KSaneWidget::make() const
|
||||
{
|
||||
return vendor();
|
||||
}
|
||||
QString KSaneWidget::model() const
|
||||
{
|
||||
d->m_findDevThread->wait();
|
||||
d->devListUpdated(); // this is just a wrapped if (m_vendor.isEmpty()) statement if the vendor is known
|
||||
// devListUpdated here is to ensure that we do not come in between finished and the devListUpdated slot
|
||||
|
||||
return d->m_model;
|
||||
}
|
||||
|
||||
QString KSaneWidget::selectDevice(QWidget* parent)
|
||||
{
|
||||
QString selected_name;
|
||||
QPointer<KSaneDeviceDialog> sel = new KSaneDeviceDialog(parent);
|
||||
|
||||
// sel.setDefault(prev_backend); // set default scanner - perhaps application using libksane should remember that
|
||||
if(sel->exec() == KDialog::Accepted) {
|
||||
selected_name = sel->getSelectedName();
|
||||
}
|
||||
delete sel;
|
||||
return selected_name;
|
||||
}
|
||||
|
||||
void KSaneWidget::initGetDeviceList() const
|
||||
{
|
||||
// update the device list if needed to get the vendor and model info
|
||||
if (d->m_findDevThread->devicesList().size() == 0) {
|
||||
//kDebug() << "initGetDeviceList() starting thread...";
|
||||
d->m_findDevThread->start();
|
||||
}
|
||||
else {
|
||||
//kDebug() << "initGetDeviceList() have existing data...";
|
||||
d->signalDevListUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
bool KSaneWidget::openDevice(const QString &deviceName)
|
||||
{
|
||||
int i=0;
|
||||
const SANE_Option_Descriptor *optDesc;
|
||||
SANE_Status status;
|
||||
SANE_Word numSaneOptions;
|
||||
SANE_Int res;
|
||||
KPasswordDialog *dlg;
|
||||
KWallet::Wallet *saneWallet;
|
||||
QString myFolderName("ksane");
|
||||
QMap<QString, QString> wallet_entry;
|
||||
|
||||
if (d->m_saneHandle != 0) {
|
||||
// this KSaneWidget already has an open device
|
||||
return false;
|
||||
}
|
||||
|
||||
// don't bother trying to open if the device string is empty
|
||||
if (deviceName.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
// save the device name
|
||||
d->m_devName = deviceName;
|
||||
|
||||
// Try to open the device
|
||||
status = sane_open(deviceName.toLatin1(), &d->m_saneHandle);
|
||||
|
||||
bool password_dialog_ok = true;
|
||||
|
||||
// prepare wallet for authentication and create password dialog
|
||||
if(status == SANE_STATUS_ACCESS_DENIED) {
|
||||
saneWallet = KWallet::Wallet::openWallet(KWallet::Wallet::LocalWallet(), winId() );
|
||||
|
||||
if(saneWallet) {
|
||||
dlg = new KPasswordDialog(this, KPasswordDialog::ShowUsernameLine | KPasswordDialog::ShowKeepPassword);
|
||||
if(!saneWallet->hasFolder(myFolderName)) {
|
||||
saneWallet->createFolder(myFolderName);
|
||||
}
|
||||
saneWallet->setFolder(myFolderName);
|
||||
saneWallet->readMap(deviceName.toLatin1(), wallet_entry);
|
||||
if(!wallet_entry.empty() || true) {
|
||||
dlg->setUsername( wallet_entry["username"] );
|
||||
dlg->setPassword( wallet_entry["password"] );
|
||||
dlg->setKeepPassword( true );
|
||||
}
|
||||
} else {
|
||||
dlg = new KPasswordDialog(this, KPasswordDialog::ShowUsernameLine);
|
||||
}
|
||||
dlg->setPrompt(i18n("Authentication required for resource: %1", deviceName ) );
|
||||
|
||||
}
|
||||
|
||||
// sane_open failed due to insufficient authorization
|
||||
// retry opening device with user provided data assisted with kwallet records
|
||||
while (status == SANE_STATUS_ACCESS_DENIED) {
|
||||
|
||||
password_dialog_ok = dlg->exec();
|
||||
if(!password_dialog_ok) {
|
||||
delete dlg;
|
||||
d->m_devName.clear();
|
||||
return false; //the user canceled
|
||||
}
|
||||
|
||||
// add/update the device user-name and password for authentication
|
||||
d->m_auth->setDeviceAuth(d->m_devName, dlg->username(), dlg->password());
|
||||
|
||||
status = sane_open(deviceName.toLatin1(), &d->m_saneHandle);
|
||||
|
||||
// store password in wallet on successful authentication
|
||||
if(dlg->keepPassword() && status != SANE_STATUS_ACCESS_DENIED) {
|
||||
QMap<QString, QString> entry;
|
||||
entry["username"] = dlg->username().toUtf8();
|
||||
entry["password"] = dlg->password().toUtf8();
|
||||
if(saneWallet) {
|
||||
saneWallet->writeMap(deviceName.toLatin1(), entry);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (status != SANE_STATUS_GOOD) {
|
||||
kDebug() << "sane_open(\"" << deviceName << "\", &handle) failed! status = " << sane_strstatus(status);
|
||||
d->m_auth->clearDeviceAuth(d->m_devName);
|
||||
d->m_devName.clear();
|
||||
return false;
|
||||
}
|
||||
|
||||
// update the device list if needed to get the vendor and model info
|
||||
if (d->m_findDevThread->devicesList().size() == 0) {
|
||||
d->m_findDevThread->start();
|
||||
}
|
||||
else {
|
||||
// use the "old" existing list
|
||||
d->devListUpdated();
|
||||
// if m_vendor is not updated it means that the list needs to be updated.
|
||||
if (d->m_vendor.isEmpty()) {
|
||||
d->m_findDevThread->start();
|
||||
}
|
||||
}
|
||||
|
||||
// Read the options (start with option 0 the number of parameters)
|
||||
optDesc = sane_get_option_descriptor(d->m_saneHandle, 0);
|
||||
if (optDesc == 0) {
|
||||
d->m_auth->clearDeviceAuth(d->m_devName);
|
||||
d->m_devName.clear();
|
||||
return false;
|
||||
}
|
||||
QVarLengthArray<char> data(optDesc->size);
|
||||
status = sane_control_option(d->m_saneHandle, 0, SANE_ACTION_GET_VALUE, data.data(), &res);
|
||||
if (status != SANE_STATUS_GOOD) {
|
||||
d->m_auth->clearDeviceAuth(d->m_devName);
|
||||
d->m_devName.clear();
|
||||
return false;
|
||||
}
|
||||
numSaneOptions = *reinterpret_cast<SANE_Word*>(data.data());
|
||||
|
||||
// read the rest of the options
|
||||
for (i=1; i<numSaneOptions; ++i) {
|
||||
switch (KSaneOption::optionType(sane_get_option_descriptor(d->m_saneHandle, i))) {
|
||||
case KSaneOption::TYPE_DETECT_FAIL:
|
||||
d->m_optList.append(new KSaneOption(d->m_saneHandle, i));
|
||||
break;
|
||||
case KSaneOption::TYPE_CHECKBOX:
|
||||
d->m_optList.append(new KSaneOptCheckBox(d->m_saneHandle, i));
|
||||
break;
|
||||
case KSaneOption::TYPE_SLIDER:
|
||||
d->m_optList.append(new KSaneOptSlider(d->m_saneHandle, i));
|
||||
break;
|
||||
case KSaneOption::TYPE_F_SLIDER:
|
||||
d->m_optList.append(new KSaneOptFSlider(d->m_saneHandle, i));
|
||||
break;
|
||||
case KSaneOption::TYPE_COMBO:
|
||||
d->m_optList.append(new KSaneOptCombo(d->m_saneHandle, i));
|
||||
break;
|
||||
case KSaneOption::TYPE_ENTRY:
|
||||
d->m_optList.append(new KSaneOptEntry(d->m_saneHandle, i));
|
||||
break;
|
||||
case KSaneOption::TYPE_GAMMA:
|
||||
d->m_optList.append(new KSaneOptGamma(d->m_saneHandle, i));
|
||||
break;
|
||||
case KSaneOption::TYPE_BUTTON:
|
||||
d->m_optList.append(new KSaneOptButton(d->m_saneHandle, i));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// do the connections of the option parameters
|
||||
for (i=1; i<d->m_optList.size(); ++i) {
|
||||
//kDebug() << d->m_optList.at(i)->name();
|
||||
connect (d->m_optList.at(i), SIGNAL(optsNeedReload()), d, SLOT(optReload()));
|
||||
connect (d->m_optList.at(i), SIGNAL(valsNeedReload()), d, SLOT(scheduleValReload()));
|
||||
|
||||
if (d->m_optList.at(i)->needsPolling()) {
|
||||
//kDebug() << d->m_optList.at(i)->name() << " needs polling";
|
||||
d->m_pollList.append(d->m_optList.at(i));
|
||||
KSaneOptCheckBox *buttonOption = qobject_cast<KSaneOptCheckBox *>(d->m_optList.at(i));
|
||||
if (buttonOption) {
|
||||
connect(buttonOption, SIGNAL(buttonPressed(QString,QString,bool)),
|
||||
this, SIGNAL(buttonPressed(QString,QString,bool)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// start polling the poll options
|
||||
if (d->m_pollList.size() > 0) {
|
||||
d->m_optionPollTmr.start();
|
||||
}
|
||||
|
||||
// Create the preview thread
|
||||
d->m_previewThread = new KSanePreviewThread(d->m_saneHandle, &d->m_previewImg);
|
||||
connect(d->m_previewThread, SIGNAL(finished()), d, SLOT(previewScanDone()));
|
||||
|
||||
// Create the read thread
|
||||
d->m_scanThread = new KSaneScanThread(d->m_saneHandle, &d->m_scanData);
|
||||
connect(d->m_scanThread, SIGNAL(finished()), d, SLOT(oneFinalScanDone()));
|
||||
|
||||
// Create the options interface
|
||||
d->createOptInterface();
|
||||
|
||||
// try to set KSaneWidget default values
|
||||
d->setDefaultValues();
|
||||
|
||||
// Enable the interface
|
||||
d->m_optsTabWidget->setDisabled(false);
|
||||
d->m_previewViewer->setDisabled(false);
|
||||
d->m_btnFrame->setDisabled(false);
|
||||
|
||||
// estimate the preview size and create an empty image
|
||||
// this is done so that you can select scan area without
|
||||
// having to scan a preview.
|
||||
d->updatePreviewSize();
|
||||
QTimer::singleShot(1000, d->m_previewViewer, SLOT(zoom2Fit()));
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool KSaneWidget::closeDevice()
|
||||
{
|
||||
if (!d->m_saneHandle) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (d->m_scanThread->isRunning()) {
|
||||
d->m_scanThread->cancelScan();
|
||||
d->m_closeDevicePending = true;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (d->m_previewThread->isRunning()) {
|
||||
d->m_previewThread->cancelScan();
|
||||
d->m_closeDevicePending = true;
|
||||
return false;
|
||||
}
|
||||
|
||||
d->m_auth->clearDeviceAuth(d->m_devName);
|
||||
// else
|
||||
sane_close(d->m_saneHandle);
|
||||
d->m_saneHandle = 0;
|
||||
d->clearDeviceOptions();
|
||||
|
||||
// disable the interface until a new device is opened.
|
||||
d->m_optsTabWidget->setDisabled(true);
|
||||
d->m_previewViewer->setDisabled(true);
|
||||
d->m_btnFrame->setDisabled(true);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
#define inc_pixel(x,y,ppl) { x++; if (x>=ppl) { y++; x=0;} }
|
||||
|
||||
QImage KSaneWidget::toQImageSilent(const QByteArray &data,
|
||||
int width,
|
||||
int height,
|
||||
int bytes_per_line,
|
||||
ImageFormat format)
|
||||
{
|
||||
QImage img;
|
||||
int j=0;
|
||||
QVector<QRgb> table;
|
||||
QRgb *imgLine;
|
||||
|
||||
switch (format)
|
||||
{
|
||||
case FormatBlackWhite:
|
||||
img = QImage((uchar*)data.data(),
|
||||
width,
|
||||
height,
|
||||
bytes_per_line,
|
||||
QImage::Format_Mono);
|
||||
// The color table must be set
|
||||
table.append(0xFFFFFFFF);
|
||||
table.append(0xFF000000);
|
||||
img.setColorTable(table);
|
||||
break;
|
||||
|
||||
case FormatGrayScale8:
|
||||
{
|
||||
img = QImage(width, height, QImage::Format_RGB32);
|
||||
int dI = 0;
|
||||
for (int i=0; (i<img.height() && dI<data.size()); i++) {
|
||||
imgLine = reinterpret_cast<QRgb*>(img.scanLine(i));
|
||||
for (j=0; (j<img.width() && dI<data.size()); j++) {
|
||||
imgLine[j] = qRgb(data[dI], data[dI], data[dI]);
|
||||
dI++;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case FormatGrayScale16:
|
||||
{
|
||||
img = QImage(width, height, QImage::Format_RGB32);
|
||||
int dI = 1;
|
||||
for (int i=0; (i<img.height() && dI<data.size()); i++) {
|
||||
imgLine = reinterpret_cast<QRgb*>(img.scanLine(i));
|
||||
for (j=0; (j<img.width() && dI<data.size()); j++) {
|
||||
imgLine[j] = qRgb(data[dI], data[dI], data[dI]);
|
||||
dI+=2;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case FormatRGB_8_C:
|
||||
{
|
||||
img = QImage(width, height, QImage::Format_RGB32);
|
||||
int dI = 0;
|
||||
for (int i=0; (i<img.height() && dI<data.size()); i++) {
|
||||
imgLine = reinterpret_cast<QRgb*>(img.scanLine(i));
|
||||
for (j=0; (j<img.width() && dI<data.size()); j++) {
|
||||
imgLine[j] = qRgb(data[dI], data[dI+1], data[dI+2]);
|
||||
dI+=3;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case FormatRGB_16_C:
|
||||
{
|
||||
img = QImage(width, height, QImage::Format_RGB32);
|
||||
int dI = 1;
|
||||
for (int i=0; (i<img.height() && dI<data.size()); i++) {
|
||||
imgLine = reinterpret_cast<QRgb*>(img.scanLine(i));
|
||||
for (j=0; (j<img.width() && dI<data.size()); j++) {
|
||||
imgLine[j] = qRgb(data[dI], data[dI+2], data[dI+4]);
|
||||
dI+=6;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case FormatNone:
|
||||
default:
|
||||
kDebug() << "Unsupported conversion";
|
||||
break;
|
||||
}
|
||||
float dpm = currentDPI() * (1000.0 / 25.4);
|
||||
img.setDotsPerMeterX(dpm);
|
||||
img.setDotsPerMeterY(dpm);
|
||||
return img;
|
||||
}
|
||||
|
||||
QImage KSaneWidget::toQImage(const QByteArray &data,
|
||||
int width,
|
||||
int height,
|
||||
int bytes_per_line,
|
||||
ImageFormat format)
|
||||
{
|
||||
|
||||
if ((format == FormatRGB_16_C) || (format == FormatGrayScale16)) {
|
||||
d->alertUser(KSaneWidget::ErrorGeneral, i18n("The image data contained 16 bits per color, "
|
||||
"but the color depth has been truncated to 8 bits per color."));
|
||||
}
|
||||
return toQImageSilent(data, width, height, bytes_per_line, format);
|
||||
}
|
||||
|
||||
void KSaneWidget::scanFinal()
|
||||
{
|
||||
if (d->m_btnFrame->isEnabled()) {
|
||||
d->startFinalScan();
|
||||
}
|
||||
else {
|
||||
// if the button frame is disabled, there is no open device to scan from
|
||||
emit scanDone(KSaneWidget::ErrorGeneral, "");
|
||||
}
|
||||
}
|
||||
|
||||
void KSaneWidget::scanCancel()
|
||||
{
|
||||
if (d->m_scanThread->isRunning()) {
|
||||
d->m_scanThread->cancelScan();
|
||||
}
|
||||
|
||||
if (d->m_previewThread->isRunning()) {
|
||||
d->m_previewThread->cancelScan();
|
||||
}
|
||||
}
|
||||
|
||||
void KSaneWidget::setPreviewResolution(float dpi)
|
||||
{
|
||||
d->m_previewDPI = dpi;
|
||||
}
|
||||
|
||||
void KSaneWidget::getOptVals(QMap <QString, QString> &opts)
|
||||
{
|
||||
KSaneOption *option;
|
||||
opts.clear();
|
||||
QString tmp;
|
||||
|
||||
for (int i=1; i<d->m_optList.size(); i++) {
|
||||
option = d->m_optList.at(i);
|
||||
if (option->getValue(tmp)) {
|
||||
opts[option->name()] = tmp;
|
||||
}
|
||||
}
|
||||
// Special handling for non sane option
|
||||
opts[InvetColorsOption] = d->m_invertColors->isChecked() ? "true" : "false";
|
||||
}
|
||||
|
||||
bool KSaneWidget::getOptVal(const QString &optname, QString &value)
|
||||
{
|
||||
KSaneOption *option;
|
||||
|
||||
if ((option = d->getOption(optname)) != 0) {
|
||||
return option->getValue(value);
|
||||
}
|
||||
// Special handling for non sane option
|
||||
if (optname == InvetColorsOption) {
|
||||
value = d->m_invertColors->isChecked() ? "true" : "false";
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
int KSaneWidget::setOptVals(const QMap <QString, QString> &opts)
|
||||
{
|
||||
QString tmp;
|
||||
int i;
|
||||
int ret=0;
|
||||
|
||||
for (i=0; i<d->m_optList.size(); i++) {
|
||||
if (opts.contains(d->m_optList.at(i)->name())) {
|
||||
tmp = opts[d->m_optList.at(i)->name()];
|
||||
if (d->m_optList.at(i)->setValue(tmp) == false) {
|
||||
ret++;
|
||||
}
|
||||
}
|
||||
}
|
||||
if ((d->m_splitGamChB) &&
|
||||
(d->m_optGamR) &&
|
||||
(d->m_optGamG) &&
|
||||
(d->m_optGamB))
|
||||
{
|
||||
// check if the current gamma values are identical. if they are identical,
|
||||
// uncheck the "Separate color intensity tables" checkbox
|
||||
QString redGamma;
|
||||
QString greenGamma;
|
||||
QString blueGamma;
|
||||
d->m_optGamR->getValue(redGamma);
|
||||
d->m_optGamG->getValue(greenGamma);
|
||||
d->m_optGamB->getValue(blueGamma);
|
||||
if ((redGamma == greenGamma) && (greenGamma == blueGamma)) {
|
||||
d->m_splitGamChB->setChecked(false);
|
||||
// set the values to the common gamma widget
|
||||
d->m_commonGamma->setValues(redGamma);
|
||||
}
|
||||
else {
|
||||
d->m_splitGamChB->setChecked(true);
|
||||
}
|
||||
}
|
||||
|
||||
// special handling for non-sane option
|
||||
if (opts.contains(InvetColorsOption)) {
|
||||
tmp = opts[InvetColorsOption];
|
||||
if ((tmp.compare("true", Qt::CaseInsensitive) == 0) ||
|
||||
(tmp.compare("1") == 0))
|
||||
{
|
||||
d->m_invertColors->setChecked(true);
|
||||
}
|
||||
else {
|
||||
d->m_invertColors->setChecked(false);
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool KSaneWidget::setOptVal(const QString &option, const QString &value)
|
||||
{
|
||||
KSaneOption *opt;
|
||||
|
||||
if ((opt = d->getOption(option)) != 0) {
|
||||
if (opt->setValue(value)) {
|
||||
if ((d->m_splitGamChB) &&
|
||||
(d->m_optGamR) &&
|
||||
(d->m_optGamG) &&
|
||||
(d->m_optGamB) &&
|
||||
((opt == d->m_optGamR) ||
|
||||
(opt == d->m_optGamG) ||
|
||||
(opt == d->m_optGamB)))
|
||||
{
|
||||
// check if the current gamma values are identical. if they are identical,
|
||||
// uncheck the "Separate color intensity tables" checkbox
|
||||
QString redGamma;
|
||||
QString greenGamma;
|
||||
QString blueGamma;
|
||||
d->m_optGamR->getValue(redGamma);
|
||||
d->m_optGamG->getValue(greenGamma);
|
||||
d->m_optGamB->getValue(blueGamma);
|
||||
if ((redGamma == greenGamma) && (greenGamma == blueGamma)) {
|
||||
d->m_splitGamChB->setChecked(false);
|
||||
// set the values to the common gamma widget
|
||||
d->m_commonGamma->setValues(redGamma);
|
||||
}
|
||||
else {
|
||||
d->m_splitGamChB->setChecked(true);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// special handling for non-sane option
|
||||
if (option == InvetColorsOption) {
|
||||
if ((value.compare("true", Qt::CaseInsensitive) == 0) ||
|
||||
(value.compare("1") == 0))
|
||||
{
|
||||
d->m_invertColors->setChecked(true);
|
||||
}
|
||||
else {
|
||||
d->m_invertColors->setChecked(false);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void KSaneWidget::setScanButtonText(const QString &scanLabel)
|
||||
{
|
||||
if (d->m_scanBtn == 0) {
|
||||
kError() << "setScanButtonText was called before KSaneWidget was initialized";
|
||||
return;
|
||||
}
|
||||
d->m_scanBtn->setText(scanLabel);
|
||||
}
|
||||
|
||||
void KSaneWidget::setPreviewButtonText(const QString &previewLabel)
|
||||
{
|
||||
if (d->m_scanBtn == 0) {
|
||||
kError() << "setPreviewButtonText was called before KSaneWidget was initialized";
|
||||
return;
|
||||
}
|
||||
d->m_prevBtn->setText(previewLabel);
|
||||
}
|
||||
|
||||
void KSaneWidget::enableAutoSelect(bool enable)
|
||||
{
|
||||
d->m_autoSelect = enable;
|
||||
}
|
||||
|
||||
float KSaneWidget::currentDPI()
|
||||
{
|
||||
if (d->m_optRes) {
|
||||
float value;
|
||||
if (d->m_optRes->getValue(value)) {
|
||||
return value;
|
||||
}
|
||||
}
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
float KSaneWidget::scanAreaWidth()
|
||||
{
|
||||
float result = 0.0;
|
||||
if (d->m_optBrX) {
|
||||
if (d->m_optBrX->getUnit() == SANE_UNIT_PIXEL) {
|
||||
d->m_optBrX->getMaxValue(result);
|
||||
result = result / currentDPI() / 25.4;
|
||||
}
|
||||
else if (d->m_optBrX->getUnit() == SANE_UNIT_MM) {
|
||||
d->m_optBrX->getMaxValue(result);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
float KSaneWidget::scanAreaHeight()
|
||||
{
|
||||
float result = 0.0;
|
||||
if (d->m_optBrY) {
|
||||
if (d->m_optBrY->getUnit() == SANE_UNIT_PIXEL) {
|
||||
d->m_optBrY->getMaxValue(result);
|
||||
result = result / currentDPI() / 25.4;
|
||||
}
|
||||
else if (d->m_optBrY->getUnit() == SANE_UNIT_MM) {
|
||||
d->m_optBrY->getMaxValue(result);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void KSaneWidget::setSelection(QPointF topLeft, QPointF bottomRight)
|
||||
{
|
||||
if (!d->m_optBrX || !d->m_optBrY || !d->m_optTlX || !d->m_optTlY) {
|
||||
return;
|
||||
}
|
||||
float xmax, ymax;
|
||||
d->m_optBrX->getMaxValue(xmax);
|
||||
d->m_optBrY->getMaxValue(ymax);
|
||||
if (topLeft.x() < 0.0 || topLeft.y() < 0.0 || bottomRight.x() < 0.0 || bottomRight.y() < 0.0) {
|
||||
d->m_previewViewer->clearActiveSelection();
|
||||
d->m_optTlX->setValue(0.0);
|
||||
d->m_optTlY->setValue(0.0);
|
||||
d->m_optBrX->setValue(xmax);
|
||||
d->m_optBrY->setValue(ymax);
|
||||
}
|
||||
|
||||
if (d->m_optBrY->getUnit() == SANE_UNIT_MM) {
|
||||
// clear selection if values are out of bounds
|
||||
if (topLeft.x() > xmax || topLeft.y() > ymax || bottomRight.x() > xmax || bottomRight.y() > ymax) {
|
||||
d->m_previewViewer->clearActiveSelection();
|
||||
d->m_optTlX->setValue(0.0);
|
||||
d->m_optTlY->setValue(0.0);
|
||||
d->m_optBrX->setValue(xmax);
|
||||
d->m_optBrY->setValue(ymax);
|
||||
}
|
||||
d->m_previewViewer->setSelection(topLeft.x(), topLeft.y(), bottomRight.x(), bottomRight.y());
|
||||
d->m_optTlX->setValue(topLeft.x());
|
||||
d->m_optTlY->setValue(topLeft.y());
|
||||
d->m_optBrX->setValue(bottomRight.x());
|
||||
d->m_optBrY->setValue(bottomRight.y());
|
||||
}
|
||||
else if (d->m_optBrY->getUnit() == SANE_UNIT_PIXEL) {
|
||||
const float mmperinch = 25.4;
|
||||
const float dpi = currentDPI();
|
||||
const float m = dpi / mmperinch;
|
||||
if (m*topLeft.x() > xmax || m*topLeft.y() > ymax || m*bottomRight.x() > xmax || m*bottomRight.y() > ymax) {
|
||||
d->m_previewViewer->clearActiveSelection();
|
||||
d->m_optTlX->setValue(0.0);
|
||||
d->m_optTlY->setValue(0.0);
|
||||
d->m_optBrX->setValue(xmax);
|
||||
d->m_optBrY->setValue(ymax);
|
||||
}
|
||||
d->m_previewViewer->setSelection(m*topLeft.x(), m*topLeft.y(), m*bottomRight.x(), m*bottomRight.y());
|
||||
d->m_optTlX->setValue(m*topLeft.x());
|
||||
d->m_optTlY->setValue(m*topLeft.y());
|
||||
d->m_optBrX->setValue(m*bottomRight.x());
|
||||
d->m_optBrY->setValue(m*bottomRight.y());
|
||||
}
|
||||
}
|
||||
|
||||
void KSaneWidget::setOptionsCollapsed(bool collapse)
|
||||
{
|
||||
if (collapse) {
|
||||
QTimer::singleShot(0, d->m_optionsCollapser, SLOT(slotCollapse()));
|
||||
}
|
||||
else {
|
||||
QTimer::singleShot(0, d->m_optionsCollapser, SLOT(slotRestore()));
|
||||
}
|
||||
}
|
||||
|
||||
void KSaneWidget::setScanButtonHidden(bool hidden)
|
||||
{
|
||||
d->m_scanBtn->setHidden(hidden);
|
||||
}
|
||||
|
||||
} // NameSpace KSaneIface
|
1134
libksane/libksane/ksane_widget_private.cpp
Normal file
1134
libksane/libksane/ksane_widget_private.cpp
Normal file
File diff suppressed because it is too large
Load diff
204
libksane/libksane/ksane_widget_private.h
Normal file
204
libksane/libksane/ksane_widget_private.h
Normal file
|
@ -0,0 +1,204 @@
|
|||
/* ============================================================
|
||||
*
|
||||
* This file is part of the KDE project
|
||||
*
|
||||
* Date : 2009-01-21
|
||||
* Description : Sane interface for KDE
|
||||
*
|
||||
* Copyright (C) 2009 by Kare Sars <kare dot sars at iki dot fi>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) version 3, or any
|
||||
* later version accepted by the membership of KDE e.V. (or its
|
||||
* successor approved by the membership of KDE e.V.), which shall
|
||||
* act as a proxy defined in Section 6 of version 3 of the license.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* ============================================================ */
|
||||
|
||||
#ifndef KSANE_WIDGET_PRIVATE_H
|
||||
#define KSANE_WIDGET_PRIVATE_H
|
||||
|
||||
// Sane includes
|
||||
extern "C"
|
||||
{
|
||||
#include <sane/saneopts.h>
|
||||
#include <sane/sane.h>
|
||||
}
|
||||
|
||||
// Qt includes
|
||||
#include <QtGui/QWidget>
|
||||
#include <QCheckBox>
|
||||
#include <QTimer>
|
||||
#include <QTime>
|
||||
#include <QProgressBar>
|
||||
|
||||
// KDE includes
|
||||
#include <KTabWidget>
|
||||
#include <KLocale>
|
||||
#include <KDebug>
|
||||
#include <KMessageBox>
|
||||
#include <KPushButton>
|
||||
#include <KToolBar>
|
||||
|
||||
// Local includes
|
||||
#include "ksane.h"
|
||||
#include "ksane_option.h"
|
||||
#include "ksane_viewer.h"
|
||||
#include "labeled_gamma.h"
|
||||
#include "labeled_checkbox.h"
|
||||
#include "splittercollapser.h"
|
||||
#include "ksane_scan_thread.h"
|
||||
#include "ksane_preview_thread.h"
|
||||
#include "ksane_find_devices_thread.h"
|
||||
#include "ksane_auth.h"
|
||||
|
||||
#define IMG_DATA_R_SIZE 100000
|
||||
|
||||
/** This namespace collects all methods and classes in LibKSane. */
|
||||
namespace KSaneIface
|
||||
{
|
||||
class KSaneWidgetPrivate: public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
KSaneWidgetPrivate(KSaneWidget *);
|
||||
void clearDeviceOptions();
|
||||
void createOptInterface();
|
||||
void updatePreviewSize();
|
||||
void setDefaultValues();
|
||||
void setBusy(bool busy);
|
||||
KSaneOption *getOption(const QString &name);
|
||||
KSaneWidget::ImageFormat getImgFormat(SANE_Parameters ¶ms);
|
||||
int getBytesPerLines(SANE_Parameters ¶ms);
|
||||
|
||||
public Q_SLOTS:
|
||||
void devListUpdated();
|
||||
void signalDevListUpdate();
|
||||
void startFinalScan();
|
||||
void previewScanDone();
|
||||
void oneFinalScanDone();
|
||||
void updateProgress();
|
||||
|
||||
private Q_SLOTS:
|
||||
void scheduleValReload();
|
||||
void optReload();
|
||||
void valReload();
|
||||
void handleSelection(float tl_x, float tl_y, float br_x, float br_y);
|
||||
void setTLX(float x);
|
||||
void setTLY(float y);
|
||||
void setBRX(float x);
|
||||
void setBRY(float y);
|
||||
|
||||
void startPreviewScan();
|
||||
|
||||
void checkInvert();
|
||||
void invertPreview();
|
||||
void pollPollOptions();
|
||||
|
||||
public:
|
||||
void alertUser(int type, const QString &strStatus);
|
||||
|
||||
public:
|
||||
// backend independent
|
||||
KTabWidget *m_optsTabWidget;
|
||||
QScrollArea *m_basicScrollA;
|
||||
QWidget *m_basicOptsTab;
|
||||
QWidget *m_colorOpts;
|
||||
QScrollArea *m_otherScrollA;
|
||||
QWidget *m_otherOptsTab;
|
||||
LabeledCheckbox *m_invertColors;
|
||||
|
||||
QSplitter *m_splitter;
|
||||
SplitterCollapser *m_optionsCollapser;
|
||||
|
||||
QWidget *m_previewFrame;
|
||||
KSaneViewer *m_previewViewer;
|
||||
QWidget *m_btnFrame;
|
||||
QToolButton *m_zInBtn;
|
||||
QToolButton *m_zOutBtn;
|
||||
QToolButton *m_zSelBtn;
|
||||
QToolButton *m_zFitBtn;
|
||||
QToolButton *m_clearSelBtn;
|
||||
KPushButton *m_scanBtn;
|
||||
KPushButton *m_prevBtn;
|
||||
|
||||
QWidget *m_activityFrame;
|
||||
QLabel *m_warmingUp;
|
||||
QProgressBar *m_progressBar;
|
||||
KPushButton *m_cancelBtn;
|
||||
|
||||
// device info
|
||||
SANE_Handle m_saneHandle;
|
||||
QString m_devName;
|
||||
QString m_vendor;
|
||||
QString m_model;
|
||||
|
||||
// Option variables
|
||||
QList<KSaneOption*> m_optList;
|
||||
QList<KSaneOption*> m_pollList;
|
||||
KSaneOption *m_optSource;
|
||||
KSaneOption *m_optNegative;
|
||||
KSaneOption *m_optFilmType;
|
||||
KSaneOption *m_optMode;
|
||||
KSaneOption *m_optDepth;
|
||||
KSaneOption *m_optRes;
|
||||
KSaneOption *m_optResX;
|
||||
KSaneOption *m_optResY;
|
||||
KSaneOption *m_optTlX;
|
||||
KSaneOption *m_optTlY;
|
||||
KSaneOption *m_optBrX;
|
||||
KSaneOption *m_optBrY;
|
||||
KSaneOption *m_optPreview;
|
||||
KSaneOption *m_optGamR;
|
||||
KSaneOption *m_optGamG;
|
||||
KSaneOption *m_optGamB;
|
||||
LabeledCheckbox *m_splitGamChB;
|
||||
LabeledGamma *m_commonGamma;
|
||||
KSaneOption *m_optWaitForBtn;
|
||||
|
||||
// preview variables
|
||||
float m_previewWidth;
|
||||
float m_previewHeight;
|
||||
float m_previewDPI;
|
||||
QImage m_previewImg;
|
||||
bool m_isPreview;
|
||||
bool m_autoSelect;
|
||||
|
||||
int m_selIndex;
|
||||
|
||||
bool m_scanOngoing;
|
||||
bool m_closeDevicePending;
|
||||
|
||||
// final image data
|
||||
QByteArray m_scanData;
|
||||
|
||||
// option handling
|
||||
QTimer m_readValsTmr;
|
||||
QTimer m_updProgressTmr;
|
||||
QTimer m_optionPollTmr;
|
||||
KSaneScanThread *m_scanThread;
|
||||
KSanePreviewThread *m_previewThread;
|
||||
|
||||
QString m_saneUserName;
|
||||
QString m_sanePassword;
|
||||
|
||||
FindSaneDevicesThread *m_findDevThread;
|
||||
KSaneAuth *m_auth;
|
||||
KSaneWidget *q;
|
||||
};
|
||||
|
||||
|
||||
} // NameSpace KSaneIface
|
||||
|
||||
#endif // SANE_WIDGET_H
|
40
libksane/libksane/libksane_export.h
Normal file
40
libksane/libksane/libksane_export.h
Normal file
|
@ -0,0 +1,40 @@
|
|||
/* This file is part of the KDE project
|
||||
Copyright (C) 2007 David Faure <faure@kde.org>
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public License
|
||||
along with this library; see the file COPYING.LIB. If not, write to
|
||||
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#ifndef LIBKSANE_EXPORT_H
|
||||
#define LIBKSANE_EXPORT_H
|
||||
|
||||
/* needed for KDE_EXPORT and KDE_IMPORT macros */
|
||||
#include <kdemacros.h>
|
||||
|
||||
#ifndef LIBKSANE_EXPORT
|
||||
# if defined(MAKE_KSANE_LIB)
|
||||
/* We are building this library */
|
||||
# define LIBKSANE_EXPORT KDE_EXPORT
|
||||
# else
|
||||
/* We are using this library */
|
||||
# define LIBKSANE_EXPORT KDE_IMPORT
|
||||
# endif
|
||||
#endif
|
||||
|
||||
# ifndef LIBKSANE_EXPORT_DEPRECATED
|
||||
# define LIBKSANE_EXPORT_DEPRECATED KDE_DEPRECATED LIBKSANE_EXPORT
|
||||
# endif
|
||||
|
||||
#endif
|
71
libksane/libksane/options/ksane_opt_button.cpp
Normal file
71
libksane/libksane/options/ksane_opt_button.cpp
Normal file
|
@ -0,0 +1,71 @@
|
|||
/* ============================================================
|
||||
*
|
||||
* This file is part of the KDE project
|
||||
*
|
||||
* Date : 2009-01-21
|
||||
* Description : Sane interface for KDE
|
||||
*
|
||||
* Copyright (C) 2009 by Kare Sars <kare dot sars at iki dot fi>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) version 3, or any
|
||||
* later version accepted by the membership of KDE e.V. (or its
|
||||
* successor approved by the membership of KDE e.V.), which shall
|
||||
* act as a proxy defined in Section 6 of version 3 of the license.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* ============================================================ */
|
||||
// Local includes
|
||||
#include "ksane_opt_button.h"
|
||||
#include "ksane_opt_button.moc"
|
||||
|
||||
#include "ksane_button.h"
|
||||
|
||||
// KDE includes
|
||||
#include <KDebug>
|
||||
#include <KLocale>
|
||||
|
||||
namespace KSaneIface
|
||||
{
|
||||
|
||||
KSaneOptButton::KSaneOptButton(const SANE_Handle handle, const int index)
|
||||
: KSaneOption(handle, index), m_button(0)
|
||||
{
|
||||
}
|
||||
|
||||
void KSaneOptButton::createWidget(QWidget *parent)
|
||||
{
|
||||
if (m_widget) return;
|
||||
|
||||
readOption();
|
||||
|
||||
if (!m_optDesc) {
|
||||
kDebug() << "This is a bug";
|
||||
m_widget = new KSaneOptionWidget(parent, "");
|
||||
return;
|
||||
}
|
||||
|
||||
m_widget = m_button = new KSaneButton(parent, i18n(m_optDesc->title));
|
||||
m_widget->setToolTip(i18n(m_optDesc->desc));
|
||||
connect(m_button, SIGNAL(clicked()), this, SLOT(buttonClicked()));
|
||||
|
||||
updateVisibility();
|
||||
readValue();
|
||||
}
|
||||
|
||||
void KSaneOptButton::buttonClicked()
|
||||
{
|
||||
unsigned char data[4];
|
||||
writeData(data);
|
||||
}
|
||||
|
||||
} // NameSpace KSaneIface
|
58
libksane/libksane/options/ksane_opt_button.h
Normal file
58
libksane/libksane/options/ksane_opt_button.h
Normal file
|
@ -0,0 +1,58 @@
|
|||
/* ============================================================
|
||||
*
|
||||
* This file is part of the KDE project
|
||||
*
|
||||
* Date : 2009-01-21
|
||||
* Description : Sane interface for KDE
|
||||
*
|
||||
* Copyright (C) 2009 by Kare Sars <kare dot sars at iki dot fi>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) version 3, or any
|
||||
* later version accepted by the membership of KDE e.V. (or its
|
||||
* successor approved by the membership of KDE e.V.), which shall
|
||||
* act as a proxy defined in Section 6 of version 3 of the license.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* ============================================================ */
|
||||
|
||||
#ifndef KSANE_OPT_BUTTON_H
|
||||
#define KSANE_OPT_BUTTON_H
|
||||
|
||||
#include "ksane_option.h"
|
||||
|
||||
namespace KSaneIface
|
||||
{
|
||||
|
||||
class KSaneButton;
|
||||
|
||||
class KSaneOptButton : public KSaneOption
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
KSaneOptButton(const SANE_Handle handle, const int index);
|
||||
|
||||
void createWidget(QWidget *parent);
|
||||
|
||||
bool hasGui() {return true;}
|
||||
|
||||
private Q_SLOTS:
|
||||
void buttonClicked();
|
||||
|
||||
private:
|
||||
KSaneButton *m_button;
|
||||
};
|
||||
|
||||
} // NameSpace KSaneIface
|
||||
|
||||
#endif // KSANE_BUTTON_OPT_H
|
138
libksane/libksane/options/ksane_opt_checkbox.cpp
Normal file
138
libksane/libksane/options/ksane_opt_checkbox.cpp
Normal file
|
@ -0,0 +1,138 @@
|
|||
/* ============================================================
|
||||
*
|
||||
* This file is part of the KDE project
|
||||
*
|
||||
* Date : 2009-01-21
|
||||
* Description : Sane interface for KDE
|
||||
*
|
||||
* Copyright (C) 2009 by Kare Sars <kare dot sars at iki dot fi>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) version 3, or any
|
||||
* later version accepted by the membership of KDE e.V. (or its
|
||||
* successor approved by the membership of KDE e.V.), which shall
|
||||
* act as a proxy defined in Section 6 of version 3 of the license.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* ============================================================ */
|
||||
// Local includes
|
||||
#include "ksane_opt_checkbox.h"
|
||||
#include "ksane_opt_checkbox.moc"
|
||||
|
||||
#include "labeled_checkbox.h"
|
||||
|
||||
// Qt includes
|
||||
#include <QtCore/QVarLengthArray>
|
||||
|
||||
// KDE includes
|
||||
#include <KDebug>
|
||||
#include <KLocale>
|
||||
|
||||
namespace KSaneIface
|
||||
{
|
||||
|
||||
KSaneOptCheckBox::KSaneOptCheckBox(const SANE_Handle handle, const int index)
|
||||
: KSaneOption(handle, index), m_checkbox(0), m_checked(false)
|
||||
{
|
||||
}
|
||||
|
||||
void KSaneOptCheckBox::createWidget(QWidget *parent)
|
||||
{
|
||||
if (m_widget) return;
|
||||
|
||||
readOption();
|
||||
|
||||
if (!m_optDesc) {
|
||||
kDebug() << "This is a bug";
|
||||
m_widget = new KSaneOptionWidget(parent, "");
|
||||
return;
|
||||
}
|
||||
|
||||
m_widget = m_checkbox = new LabeledCheckbox(parent, i18n(m_optDesc->title));
|
||||
m_widget->setToolTip(i18n(m_optDesc->desc));
|
||||
|
||||
connect(m_checkbox, SIGNAL(toggled(bool)), this, SLOT(checkboxChanged(bool)));
|
||||
|
||||
updateVisibility();
|
||||
readValue();
|
||||
}
|
||||
|
||||
void KSaneOptCheckBox::checkboxChanged(bool toggled)
|
||||
{
|
||||
unsigned char data[4];
|
||||
|
||||
m_checked = toggled;
|
||||
fromSANE_Word(data, (toggled) ? 1:0);
|
||||
writeData(data);
|
||||
}
|
||||
|
||||
void KSaneOptCheckBox::readValue()
|
||||
{
|
||||
if (state() == STATE_HIDDEN) return;
|
||||
|
||||
// read the current value
|
||||
QVarLengthArray<unsigned char> data(m_optDesc->size);
|
||||
SANE_Status status;
|
||||
SANE_Int res;
|
||||
status = sane_control_option (m_handle, m_index, SANE_ACTION_GET_VALUE, data.data(), &res);
|
||||
if (status != SANE_STATUS_GOOD) {
|
||||
return;
|
||||
}
|
||||
bool old = m_checked;
|
||||
m_checked = (toSANE_Word(data.data()) != 0) ? true:false;
|
||||
if (m_checkbox) {
|
||||
m_checkbox->setChecked(m_checked);
|
||||
}
|
||||
if ((old != m_checked) && ((m_optDesc->cap & SANE_CAP_SOFT_SELECT) == 0)) {
|
||||
emit buttonPressed(name(), i18n(m_optDesc->title), m_checked);
|
||||
}
|
||||
}
|
||||
|
||||
bool KSaneOptCheckBox::getValue(float &val)
|
||||
{
|
||||
if (state() == STATE_HIDDEN) return false;
|
||||
val = m_checked ? 1.0 : 0.0;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool KSaneOptCheckBox::setValue(float val)
|
||||
{
|
||||
if (state() == STATE_HIDDEN) return false;
|
||||
checkboxChanged(val == 0);
|
||||
readValue();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool KSaneOptCheckBox::getValue(QString &val)
|
||||
{
|
||||
if (state() == STATE_HIDDEN) return false;
|
||||
val = m_checked ? "true" : "false";
|
||||
return true;
|
||||
}
|
||||
|
||||
bool KSaneOptCheckBox::setValue(const QString &val)
|
||||
{
|
||||
if (state() == STATE_HIDDEN) return false;
|
||||
if ((val.compare("true", Qt::CaseInsensitive) == 0) ||
|
||||
(val.compare("1") == 0))
|
||||
{
|
||||
checkboxChanged(true);
|
||||
}
|
||||
else {
|
||||
checkboxChanged(false);
|
||||
}
|
||||
readValue();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
} // NameSpace KSaneIface
|
68
libksane/libksane/options/ksane_opt_checkbox.h
Normal file
68
libksane/libksane/options/ksane_opt_checkbox.h
Normal file
|
@ -0,0 +1,68 @@
|
|||
/* ============================================================
|
||||
*
|
||||
* This file is part of the KDE project
|
||||
*
|
||||
* Date : 2009-01-21
|
||||
* Description : Sane interface for KDE
|
||||
*
|
||||
* Copyright (C) 2009 by Kare Sars <kare dot sars at iki dot fi>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) version 3, or any
|
||||
* later version accepted by the membership of KDE e.V. (or its
|
||||
* successor approved by the membership of KDE e.V.), which shall
|
||||
* act as a proxy defined in Section 6 of version 3 of the license.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* ============================================================ */
|
||||
|
||||
#ifndef KSANE_OPT_CHECKBOX_H
|
||||
#define KSANE_OPT_CHECKBOX_H
|
||||
|
||||
#include "ksane_option.h"
|
||||
|
||||
namespace KSaneIface
|
||||
{
|
||||
|
||||
class LabeledCheckbox;
|
||||
|
||||
class KSaneOptCheckBox : public KSaneOption
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
KSaneOptCheckBox(const SANE_Handle handle, const int index);
|
||||
|
||||
void createWidget(QWidget *parent);
|
||||
|
||||
void readValue();
|
||||
|
||||
bool getValue(float &val);
|
||||
bool setValue(float val);
|
||||
bool getValue(QString &val);
|
||||
bool setValue(const QString &val);
|
||||
bool hasGui() {return true;}
|
||||
|
||||
private Q_SLOTS:
|
||||
void checkboxChanged(bool toggled);
|
||||
|
||||
Q_SIGNALS:
|
||||
void buttonPressed(const QString &optionName, const QString &optionLabel, bool pressed);
|
||||
|
||||
private:
|
||||
LabeledCheckbox *m_checkbox;
|
||||
bool m_checked;
|
||||
};
|
||||
|
||||
} // NameSpace KSaneIface
|
||||
|
||||
#endif
|
380
libksane/libksane/options/ksane_opt_combo.cpp
Normal file
380
libksane/libksane/options/ksane_opt_combo.cpp
Normal file
|
@ -0,0 +1,380 @@
|
|||
/* ============================================================
|
||||
*
|
||||
* This file is part of the KDE project
|
||||
*
|
||||
* Date : 2009-01-21
|
||||
* Description : Sane interface for KDE
|
||||
*
|
||||
* Copyright (C) 2009 by Kare Sars <kare dot sars at iki dot fi>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) version 3, or any
|
||||
* later version accepted by the membership of KDE e.V. (or its
|
||||
* successor approved by the membership of KDE e.V.), which shall
|
||||
* act as a proxy defined in Section 6 of version 3 of the license.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* ============================================================ */
|
||||
// Local includes
|
||||
#include "ksane_opt_combo.h"
|
||||
#include "ksane_opt_combo.moc"
|
||||
|
||||
#include "labeled_combo.h"
|
||||
|
||||
// Qt includes
|
||||
#include <QtCore/QVarLengthArray>
|
||||
|
||||
// KDE includes
|
||||
#include <kicon.h>
|
||||
#include <KDebug>
|
||||
#include <KLocale>
|
||||
|
||||
namespace KSaneIface
|
||||
{
|
||||
static const char tmp_binary[] = "Binary";
|
||||
|
||||
KSaneOptCombo::KSaneOptCombo(const SANE_Handle handle, const int index)
|
||||
: KSaneOption(handle, index), m_combo(0)
|
||||
{
|
||||
}
|
||||
|
||||
void KSaneOptCombo::createWidget(QWidget *parent)
|
||||
{
|
||||
if (m_widget) return;
|
||||
|
||||
m_widget = m_combo = new LabeledCombo(parent, "", QStringList());
|
||||
readOption();
|
||||
m_widget->setToolTip(i18n(m_optDesc->desc));
|
||||
connect(m_combo, SIGNAL(activated(int)), this, SLOT(comboboxChangedIndex(int)));
|
||||
readValue();
|
||||
}
|
||||
|
||||
void KSaneOptCombo::readValue()
|
||||
{
|
||||
if (state() == STATE_HIDDEN) return;
|
||||
|
||||
// read that current value
|
||||
QVarLengthArray<unsigned char> data(m_optDesc->size);
|
||||
SANE_Status status;
|
||||
SANE_Int res;
|
||||
status = sane_control_option (m_handle, m_index, SANE_ACTION_GET_VALUE, data.data(), &res);
|
||||
if (status != SANE_STATUS_GOOD) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
m_currentText = getSaneComboString(data.data());
|
||||
if (m_combo != 0) {
|
||||
if (m_combo->currentText() != m_currentText) {
|
||||
m_combo->setCurrentText(m_currentText);
|
||||
emit valueChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void KSaneOptCombo::readOption()
|
||||
{
|
||||
KSaneOption::readOption();
|
||||
|
||||
if (!m_combo) return;
|
||||
|
||||
QString saved = m_combo->currentText();
|
||||
|
||||
m_strList = genComboStringList();
|
||||
m_combo->clear();
|
||||
m_combo->setLabelText(i18n(m_optDesc->title));
|
||||
m_combo->addItems(m_strList);
|
||||
m_combo->setIcon(KIcon("color"), getSaneComboString((unsigned char*)SANE_VALUE_SCAN_MODE_COLOR));
|
||||
m_combo->setIcon(KIcon("gray-scale"),
|
||||
getSaneComboString((unsigned char*)SANE_VALUE_SCAN_MODE_GRAY));
|
||||
m_combo->setIcon(KIcon("black-white"),
|
||||
getSaneComboString((unsigned char*)SANE_VALUE_SCAN_MODE_LINEART));
|
||||
// The epkowa/epson backend uses "Binary" which is the same as "Lineart"
|
||||
m_combo->setIcon(KIcon("black-white"), i18n(tmp_binary));
|
||||
|
||||
// set the previous value
|
||||
m_combo->setCurrentText(saved);
|
||||
}
|
||||
|
||||
|
||||
QStringList &KSaneOptCombo::genComboStringList()
|
||||
{
|
||||
int i;
|
||||
m_strList.clear();
|
||||
|
||||
switch (m_optDesc->type)
|
||||
{
|
||||
case SANE_TYPE_INT:
|
||||
for (i=1; i<=m_optDesc->constraint.word_list[0]; ++i) {
|
||||
m_strList += getSaneComboString((int)m_optDesc->constraint.word_list[i]);
|
||||
}
|
||||
break;
|
||||
case SANE_TYPE_FIXED:
|
||||
for (i=1; i<=m_optDesc->constraint.word_list[0]; ++i) {
|
||||
m_strList += getSaneComboString((float)SANE_UNFIX(m_optDesc->constraint.word_list[i]));
|
||||
}
|
||||
break;
|
||||
case SANE_TYPE_STRING:
|
||||
i=0;
|
||||
while (m_optDesc->constraint.string_list[i] != 0) {
|
||||
m_strList += getSaneComboString((unsigned char *)m_optDesc->constraint.string_list[i]);
|
||||
i++;
|
||||
}
|
||||
break;
|
||||
default :
|
||||
m_strList += "NOT HANDELED";
|
||||
break;
|
||||
}
|
||||
return m_strList;
|
||||
}
|
||||
|
||||
QString KSaneOptCombo::getSaneComboString(int ival)
|
||||
{
|
||||
switch(m_optDesc->unit)
|
||||
{
|
||||
case SANE_UNIT_NONE: break;
|
||||
case SANE_UNIT_PIXEL: return i18np("%1 Pixel","%1 Pixels", ival);
|
||||
case SANE_UNIT_BIT: return i18np("%1 Bit","%1 Bits", ival);
|
||||
case SANE_UNIT_MM: return i18np("%1 mm","%1 mm", ival);
|
||||
case SANE_UNIT_DPI: return i18np("%1 DPI","%1 DPI", ival);
|
||||
case SANE_UNIT_PERCENT: return i18np("%1 %","%1 %", ival);
|
||||
case SANE_UNIT_MICROSECOND: return i18np("%1 µs","%1 µs", ival);
|
||||
}
|
||||
return QString::number(ival);
|
||||
}
|
||||
|
||||
QString KSaneOptCombo::getSaneComboString(float fval)
|
||||
{
|
||||
switch(m_optDesc->unit)
|
||||
{
|
||||
case SANE_UNIT_NONE: break;
|
||||
case SANE_UNIT_PIXEL: return i18ncp("Parameter and Unit","%1 Pixel", "%1 Pixels", fval);
|
||||
case SANE_UNIT_BIT: return i18ncp("Parameter and Unit","%1 Bit","%1 Bits", fval);
|
||||
case SANE_UNIT_MM: return i18nc("Parameter and Unit (Millimeter)","%1 mm", fval);
|
||||
case SANE_UNIT_DPI: return i18nc("Parameter and Unit (Dots Per Inch)","%1 DPI", fval);
|
||||
case SANE_UNIT_PERCENT: return i18nc("Parameter and Unit (Percentage)","%1 %", fval);
|
||||
case SANE_UNIT_MICROSECOND: return i18nc("Parameter and Unit (Microseconds)","%1 µs", fval);
|
||||
}
|
||||
return QString::number(fval, 'F', 4);
|
||||
}
|
||||
|
||||
QString KSaneOptCombo::getSaneComboString(unsigned char *data)
|
||||
{
|
||||
QString tmp;
|
||||
if (data == 0) return QString();
|
||||
|
||||
switch (m_optDesc->type)
|
||||
{
|
||||
case SANE_TYPE_INT:
|
||||
return getSaneComboString((int)toSANE_Word(data));
|
||||
case SANE_TYPE_FIXED:
|
||||
return getSaneComboString((float)SANE_UNFIX(toSANE_Word(data)));
|
||||
case SANE_TYPE_STRING:
|
||||
tmp = i18n(reinterpret_cast<char*>(data));
|
||||
tmp = tmp.simplified();
|
||||
return tmp;
|
||||
default :
|
||||
break;
|
||||
}
|
||||
return QString();
|
||||
}
|
||||
|
||||
|
||||
|
||||
void KSaneOptCombo::comboboxChangedIndex(int i)
|
||||
{
|
||||
if (m_combo && (m_combo->currentText() == m_currentText)) {
|
||||
return;
|
||||
}
|
||||
|
||||
unsigned char data[4];
|
||||
void *dataPtr;
|
||||
|
||||
switch (m_optDesc->type)
|
||||
{
|
||||
case SANE_TYPE_INT:
|
||||
case SANE_TYPE_FIXED:
|
||||
fromSANE_Word(data, m_optDesc->constraint.word_list[i+1]);
|
||||
dataPtr = data;
|
||||
break;
|
||||
case SANE_TYPE_STRING:
|
||||
dataPtr = (void *)m_optDesc->constraint.string_list[i];
|
||||
break;
|
||||
default:
|
||||
kDebug() << "can not handle type:" << m_optDesc->type;
|
||||
return;
|
||||
}
|
||||
writeData(dataPtr);
|
||||
readValue();
|
||||
emit valueChanged();
|
||||
}
|
||||
|
||||
bool KSaneOptCombo::getMinValue(float &val)
|
||||
{
|
||||
if (state() == STATE_HIDDEN) return false;
|
||||
switch (m_optDesc->type)
|
||||
{
|
||||
case SANE_TYPE_INT:
|
||||
val = (float)m_optDesc->constraint.word_list[1];
|
||||
for (int i=2; i<=m_optDesc->constraint.word_list[0]; i++) {
|
||||
val = qMin((float)m_optDesc->constraint.word_list[i], val);
|
||||
}
|
||||
break;
|
||||
case SANE_TYPE_FIXED:
|
||||
val = (float)SANE_UNFIX(m_optDesc->constraint.word_list[1]);
|
||||
for (int i=2; i<=m_optDesc->constraint.word_list[0]; i++) {
|
||||
val = qMin((float)SANE_UNFIX(m_optDesc->constraint.word_list[i]), val);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
kDebug() << "can not handle type:" << m_optDesc->type;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool KSaneOptCombo::getValue(float &val)
|
||||
{
|
||||
if (state() == STATE_HIDDEN) return false;
|
||||
|
||||
// read that current value
|
||||
QVarLengthArray<unsigned char> data(m_optDesc->size);
|
||||
SANE_Status status;
|
||||
SANE_Int res;
|
||||
status = sane_control_option (m_handle, m_index, SANE_ACTION_GET_VALUE, data.data(), &res);
|
||||
if (status != SANE_STATUS_GOOD) {
|
||||
kDebug() << m_optDesc->name << "sane_control_option returned" << status;
|
||||
return false;
|
||||
}
|
||||
|
||||
switch (m_optDesc->type)
|
||||
{
|
||||
case SANE_TYPE_INT:
|
||||
val = (float)toSANE_Word(data.data());
|
||||
return true;
|
||||
case SANE_TYPE_FIXED:
|
||||
val = SANE_UNFIX(toSANE_Word(data.data()));
|
||||
return true;
|
||||
default:
|
||||
kDebug() << "Type" << m_optDesc->type << "not supported!";
|
||||
break;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool KSaneOptCombo::setValue(float value)
|
||||
{
|
||||
unsigned char data[4];
|
||||
float tmp;
|
||||
float minDiff;
|
||||
int i;
|
||||
int minIndex = 1;
|
||||
|
||||
switch (m_optDesc->type)
|
||||
{
|
||||
case SANE_TYPE_INT:
|
||||
tmp = (float)m_optDesc->constraint.word_list[minIndex];
|
||||
minDiff = qAbs(value - tmp);
|
||||
for (i=2; i<=m_optDesc->constraint.word_list[0]; ++i) {
|
||||
tmp = (float)m_optDesc->constraint.word_list[i];
|
||||
if (qAbs(value - tmp) < minDiff) {
|
||||
minDiff = qAbs(value - tmp);
|
||||
minIndex = i;
|
||||
}
|
||||
}
|
||||
fromSANE_Word(data, m_optDesc->constraint.word_list[minIndex]);
|
||||
writeData(data);
|
||||
readValue();
|
||||
return (minDiff < 1.0);
|
||||
case SANE_TYPE_FIXED:
|
||||
tmp = (float)SANE_UNFIX(m_optDesc->constraint.word_list[minIndex]);
|
||||
minDiff = qAbs(value - tmp);
|
||||
for (i=2; i<=m_optDesc->constraint.word_list[0]; ++i) {
|
||||
tmp = (float)SANE_UNFIX(m_optDesc->constraint.word_list[i]);
|
||||
if (qAbs(value - tmp) < minDiff) {
|
||||
minDiff = qAbs(value - tmp);
|
||||
minIndex = i;
|
||||
}
|
||||
}
|
||||
fromSANE_Word(data, m_optDesc->constraint.word_list[minIndex]);
|
||||
writeData(data);
|
||||
readValue();
|
||||
return (minDiff < 1.0);
|
||||
default:
|
||||
kDebug() << "can not handle type:" << m_optDesc->type;
|
||||
break;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool KSaneOptCombo::getValue(QString &val)
|
||||
{
|
||||
if (state() == STATE_HIDDEN) return false;
|
||||
val = m_currentText;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool KSaneOptCombo::setValue(const QString &val)
|
||||
{
|
||||
if (state() == STATE_HIDDEN) return false;
|
||||
if (val == m_currentText) return true;
|
||||
|
||||
unsigned char data[4];
|
||||
void *data_ptr;
|
||||
SANE_Word fixed;
|
||||
int i;
|
||||
float f;
|
||||
bool ok;
|
||||
QString tmp;
|
||||
|
||||
switch (m_optDesc->type)
|
||||
{
|
||||
case SANE_TYPE_INT:
|
||||
tmp = val.left(val.indexOf(' ')); // strip the unit
|
||||
// accept float formating of the string
|
||||
i = (int)(tmp.toFloat(&ok));
|
||||
if (ok == false) return false;
|
||||
fromSANE_Word(data, i);
|
||||
data_ptr = data;
|
||||
break;
|
||||
case SANE_TYPE_FIXED:
|
||||
tmp = val.left(val.indexOf(' ')); // strip the unit
|
||||
f = tmp.toFloat(&ok);
|
||||
if (ok == false) return false;
|
||||
fixed = SANE_FIX(f);
|
||||
fromSANE_Word(data, fixed);
|
||||
data_ptr = data;
|
||||
break;
|
||||
case SANE_TYPE_STRING:
|
||||
i = 0;
|
||||
while (m_optDesc->constraint.string_list[i] != 0) {
|
||||
tmp = getSaneComboString((unsigned char *)m_optDesc->constraint.string_list[i]);
|
||||
if (val == tmp) {
|
||||
data_ptr = (void *)m_optDesc->constraint.string_list[i];
|
||||
break;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
if (m_optDesc->constraint.string_list[i] == 0) return false;
|
||||
break;
|
||||
default:
|
||||
kDebug() << "can only handle SANE_TYPE: INT, FIXED and STRING";
|
||||
return false;
|
||||
}
|
||||
writeData(data_ptr);
|
||||
|
||||
readValue();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
} // NameSpace KSaneIface
|
76
libksane/libksane/options/ksane_opt_combo.h
Normal file
76
libksane/libksane/options/ksane_opt_combo.h
Normal file
|
@ -0,0 +1,76 @@
|
|||
/* ============================================================
|
||||
*
|
||||
* This file is part of the KDE project
|
||||
*
|
||||
* Date : 2009-01-21
|
||||
* Description : Sane interface for KDE
|
||||
*
|
||||
* Copyright (C) 2009 by Kare Sars <kare dot sars at iki dot fi>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) version 3, or any
|
||||
* later version accepted by the membership of KDE e.V. (or its
|
||||
* successor approved by the membership of KDE e.V.), which shall
|
||||
* act as a proxy defined in Section 6 of version 3 of the license.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* ============================================================ */
|
||||
|
||||
#ifndef KSANE_OPT_COMBO_H
|
||||
#define KSANE_OPT_COMBO_H
|
||||
|
||||
#include "ksane_option.h"
|
||||
|
||||
namespace KSaneIface
|
||||
{
|
||||
|
||||
class LabeledCombo;
|
||||
|
||||
class KSaneOptCombo : public KSaneOption
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
KSaneOptCombo(const SANE_Handle handle, const int index);
|
||||
|
||||
void createWidget(QWidget *parent);
|
||||
|
||||
void readValue();
|
||||
void readOption();
|
||||
|
||||
bool getMinValue(float &max);
|
||||
bool getValue(float &val);
|
||||
bool setValue(float val);
|
||||
bool getValue(QString &val);
|
||||
bool setValue(const QString &val);
|
||||
bool hasGui() {return true;}
|
||||
|
||||
private Q_SLOTS:
|
||||
void comboboxChangedIndex(int val);
|
||||
|
||||
Q_SIGNALS:
|
||||
void valueChanged();
|
||||
|
||||
private:
|
||||
QStringList &genComboStringList();
|
||||
QString getSaneComboString(int ival);
|
||||
QString getSaneComboString(float fval);
|
||||
QString getSaneComboString(unsigned char *data);
|
||||
|
||||
LabeledCombo *m_combo;
|
||||
QString m_currentText;
|
||||
QStringList m_strList;
|
||||
};
|
||||
|
||||
} // NameSpace KSaneIface
|
||||
|
||||
#endif
|
114
libksane/libksane/options/ksane_opt_entry.cpp
Normal file
114
libksane/libksane/options/ksane_opt_entry.cpp
Normal file
|
@ -0,0 +1,114 @@
|
|||
/* ============================================================
|
||||
*
|
||||
* This file is part of the KDE project
|
||||
*
|
||||
* Date : 2009-01-21
|
||||
* Description : Sane interface for KDE
|
||||
*
|
||||
* Copyright (C) 2009 by Kare Sars <kare dot sars at iki dot fi>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) version 3, or any
|
||||
* later version accepted by the membership of KDE e.V. (or its
|
||||
* successor approved by the membership of KDE e.V.), which shall
|
||||
* act as a proxy defined in Section 6 of version 3 of the license.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* ============================================================ */
|
||||
// Local includes
|
||||
#include "ksane_opt_entry.h"
|
||||
#include "ksane_opt_entry.moc"
|
||||
|
||||
#include "labeled_entry.h"
|
||||
|
||||
// Qt includes
|
||||
#include <QtCore/QVarLengthArray>
|
||||
|
||||
// KDE includes
|
||||
#include <KDebug>
|
||||
#include <KLocale>
|
||||
|
||||
namespace KSaneIface
|
||||
{
|
||||
|
||||
KSaneOptEntry::KSaneOptEntry(const SANE_Handle handle, const int index)
|
||||
: KSaneOption(handle, index), m_entry(0)
|
||||
{
|
||||
}
|
||||
|
||||
void KSaneOptEntry::createWidget(QWidget *parent)
|
||||
{
|
||||
if (m_widget) return;
|
||||
|
||||
readOption();
|
||||
|
||||
if (!m_optDesc) {
|
||||
kDebug() << "This is a bug";
|
||||
m_widget = new KSaneOptionWidget(parent, "");
|
||||
return;
|
||||
}
|
||||
|
||||
m_widget = m_entry = new LabeledEntry(parent, i18n(m_optDesc->title));
|
||||
m_widget->setToolTip(i18n(m_optDesc->desc));
|
||||
connect(m_entry, SIGNAL(entryEdited(QString)), this, SLOT(entryChanged(QString)));
|
||||
updateVisibility();
|
||||
readValue();
|
||||
}
|
||||
|
||||
void KSaneOptEntry::entryChanged(const QString& text)
|
||||
{
|
||||
QString tmp;
|
||||
tmp += text.left(m_optDesc->size);
|
||||
if (tmp != text) {
|
||||
m_entry->setText(tmp);
|
||||
writeData(tmp.toLatin1().data());
|
||||
}
|
||||
}
|
||||
|
||||
void KSaneOptEntry::readValue()
|
||||
{
|
||||
if (state() == STATE_HIDDEN) return;
|
||||
|
||||
// read that current value
|
||||
QVarLengthArray<unsigned char> data(m_optDesc->size);
|
||||
SANE_Status status;
|
||||
SANE_Int res;
|
||||
status = sane_control_option (m_handle, m_index, SANE_ACTION_GET_VALUE, data.data(), &res);
|
||||
if (status != SANE_STATUS_GOOD) {
|
||||
return;
|
||||
}
|
||||
|
||||
m_string = QString(reinterpret_cast<char*>(data.data()));
|
||||
if (m_entry != 0) {
|
||||
m_entry->setText(m_string);
|
||||
}
|
||||
}
|
||||
|
||||
bool KSaneOptEntry::getValue(float &) {return false;}
|
||||
bool KSaneOptEntry::setValue(float) {return false;}
|
||||
|
||||
bool KSaneOptEntry::getValue(QString &val)
|
||||
{
|
||||
if (state() == STATE_HIDDEN) return false;
|
||||
val = m_string;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool KSaneOptEntry::setValue(const QString &val)
|
||||
{
|
||||
if (state() == STATE_HIDDEN) return false;
|
||||
entryChanged(val);
|
||||
readValue();
|
||||
return true;
|
||||
}
|
||||
|
||||
} // NameSpace KSaneIface
|
65
libksane/libksane/options/ksane_opt_entry.h
Normal file
65
libksane/libksane/options/ksane_opt_entry.h
Normal file
|
@ -0,0 +1,65 @@
|
|||
/* ============================================================
|
||||
*
|
||||
* This file is part of the KDE project
|
||||
*
|
||||
* Date : 2009-01-21
|
||||
* Description : Sane interface for KDE
|
||||
*
|
||||
* Copyright (C) 2009 by Kare Sars <kare dot sars at iki dot fi>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) version 3, or any
|
||||
* later version accepted by the membership of KDE e.V. (or its
|
||||
* successor approved by the membership of KDE e.V.), which shall
|
||||
* act as a proxy defined in Section 6 of version 3 of the license.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* ============================================================ */
|
||||
|
||||
#ifndef KSANE_OPT_ENTRY_H
|
||||
#define KSANE_OPT_ENTRY_H
|
||||
|
||||
#include "ksane_option.h"
|
||||
|
||||
namespace KSaneIface
|
||||
{
|
||||
|
||||
class LabeledEntry;
|
||||
|
||||
class KSaneOptEntry : public KSaneOption
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
KSaneOptEntry(const SANE_Handle handle, const int index);
|
||||
|
||||
void createWidget(QWidget *parent);
|
||||
|
||||
void readValue();
|
||||
|
||||
bool getValue(float &val);
|
||||
bool setValue(float val);
|
||||
bool getValue(QString &val);
|
||||
bool setValue(const QString &val);
|
||||
bool hasGui() {return true;}
|
||||
|
||||
private Q_SLOTS:
|
||||
void entryChanged(const QString &text);
|
||||
|
||||
private:
|
||||
LabeledEntry *m_entry;
|
||||
QString m_string;
|
||||
};
|
||||
|
||||
} // NameSpace KSaneIface
|
||||
|
||||
#endif
|
176
libksane/libksane/options/ksane_opt_fslider.cpp
Normal file
176
libksane/libksane/options/ksane_opt_fslider.cpp
Normal file
|
@ -0,0 +1,176 @@
|
|||
/* ============================================================
|
||||
*
|
||||
* This file is part of the KDE project
|
||||
*
|
||||
* Date : 2009-01-21
|
||||
* Description : Sane interface for KDE
|
||||
*
|
||||
* Copyright (C) 2009 by Kare Sars <kare dot sars at iki dot fi>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) version 3, or any
|
||||
* later version accepted by the membership of KDE e.V. (or its
|
||||
* successor approved by the membership of KDE e.V.), which shall
|
||||
* act as a proxy defined in Section 6 of version 3 of the license.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* ============================================================ */
|
||||
// Local includes
|
||||
#include "ksane_opt_fslider.h"
|
||||
#include "ksane_opt_fslider.moc"
|
||||
|
||||
#include "labeled_fslider.h"
|
||||
|
||||
// Qt includes
|
||||
#include <QtCore/QVarLengthArray>
|
||||
|
||||
// KDE includes
|
||||
#include <KDebug>
|
||||
#include <KLocale>
|
||||
|
||||
static const float FIXED_MAX = 32767.0;
|
||||
static const float FIXED_MIN =-32768.0;
|
||||
static const float MIN_FIXED_STEP = 0.0001;
|
||||
namespace KSaneIface
|
||||
{
|
||||
|
||||
KSaneOptFSlider::KSaneOptFSlider(const SANE_Handle handle, const int index)
|
||||
: KSaneOption(handle, index), m_slider(0), m_fVal(0), m_minChange(MIN_FIXED_STEP)
|
||||
{
|
||||
}
|
||||
|
||||
void KSaneOptFSlider::createWidget(QWidget *parent)
|
||||
{
|
||||
if (m_widget) return;
|
||||
|
||||
m_widget = m_slider = new LabeledFSlider(parent, "", FIXED_MIN, FIXED_MAX, MIN_FIXED_STEP);
|
||||
readOption();
|
||||
m_widget->setToolTip(i18n(m_optDesc->desc));
|
||||
connect(m_slider, SIGNAL(valueChanged(float)), this, SLOT(sliderChanged(float)));
|
||||
readValue();
|
||||
}
|
||||
|
||||
void KSaneOptFSlider::readOption()
|
||||
{
|
||||
KSaneOption::readOption();
|
||||
|
||||
if (!m_slider) return;
|
||||
|
||||
if (m_optDesc->constraint_type == SANE_CONSTRAINT_RANGE) {
|
||||
m_slider->setRange(SANE_UNFIX(m_optDesc->constraint.range->min),
|
||||
SANE_UNFIX(m_optDesc->constraint.range->max));
|
||||
|
||||
float tmpStep = SANE_UNFIX(m_optDesc->constraint.range->quant);
|
||||
if (tmpStep < MIN_FIXED_STEP) tmpStep = MIN_FIXED_STEP;
|
||||
m_slider->setStep(tmpStep);
|
||||
}
|
||||
else {
|
||||
m_slider->setRange(FIXED_MIN, FIXED_MAX);
|
||||
m_slider->setStep(MIN_FIXED_STEP);
|
||||
}
|
||||
m_minChange = m_slider->step()/2;
|
||||
m_slider->setSuffix(unitDoubleString());
|
||||
m_slider->setLabelText(i18n(m_optDesc->title));
|
||||
}
|
||||
|
||||
void KSaneOptFSlider::readValue()
|
||||
{
|
||||
if (state() == STATE_HIDDEN) return;
|
||||
|
||||
// read that current value
|
||||
QVarLengthArray<unsigned char> data(m_optDesc->size);
|
||||
SANE_Status status;
|
||||
SANE_Int res;
|
||||
status = sane_control_option (m_handle, m_index, SANE_ACTION_GET_VALUE, data.data(), &res);
|
||||
if (status != SANE_STATUS_GOOD) {
|
||||
return;
|
||||
}
|
||||
|
||||
m_fVal = SANE_UNFIX(toSANE_Word(data.data()));
|
||||
if (m_slider != 0) {
|
||||
if (((m_slider->value() - m_fVal) >= m_minChange) ||
|
||||
((m_fVal- m_slider->value()) >= m_minChange))
|
||||
{
|
||||
m_slider->setValue(m_fVal);
|
||||
}
|
||||
}
|
||||
emit fValueRead(m_fVal);
|
||||
}
|
||||
|
||||
|
||||
void KSaneOptFSlider::sliderChanged(float val)
|
||||
{
|
||||
if (((val-m_fVal) >= m_minChange) || ((m_fVal-val) >= m_minChange)) {
|
||||
unsigned char data[4];
|
||||
SANE_Word fixed;
|
||||
//kDebug() <<m_optDesc->name << fVal << "!=" << val;
|
||||
m_fVal = val;
|
||||
fixed = SANE_FIX(val);
|
||||
fromSANE_Word(data, fixed);
|
||||
writeData(data);
|
||||
}
|
||||
}
|
||||
|
||||
bool KSaneOptFSlider::getMinValue(float &val)
|
||||
{
|
||||
if (m_optDesc->constraint_type == SANE_CONSTRAINT_RANGE) {
|
||||
val = SANE_UNFIX(m_optDesc->constraint.range->min);
|
||||
}
|
||||
else {
|
||||
val = FIXED_MIN;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool KSaneOptFSlider::getMaxValue(float &max)
|
||||
{
|
||||
if (m_optDesc->constraint_type == SANE_CONSTRAINT_RANGE) {
|
||||
max = SANE_UNFIX(m_optDesc->constraint.range->max);
|
||||
}
|
||||
else {
|
||||
max = FIXED_MAX;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool KSaneOptFSlider::getValue(float &val)
|
||||
{
|
||||
if (state() == STATE_HIDDEN) return false;
|
||||
val = m_fVal;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool KSaneOptFSlider::setValue(float val)
|
||||
{
|
||||
if (state() == STATE_HIDDEN) return false;
|
||||
sliderChanged(val);
|
||||
readValue();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool KSaneOptFSlider::getValue(QString &val)
|
||||
{
|
||||
if (state() == STATE_HIDDEN) return false;
|
||||
val = QString::number(m_fVal, 'F', 6);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool KSaneOptFSlider::setValue(const QString &val)
|
||||
{
|
||||
if (state() == STATE_HIDDEN) return false;
|
||||
sliderChanged(val.toFloat());
|
||||
readValue();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
} // NameSpace KSaneIface
|
72
libksane/libksane/options/ksane_opt_fslider.h
Normal file
72
libksane/libksane/options/ksane_opt_fslider.h
Normal file
|
@ -0,0 +1,72 @@
|
|||
/* ============================================================
|
||||
*
|
||||
* This file is part of the KDE project
|
||||
*
|
||||
* Date : 2009-01-21
|
||||
* Description : Sane interface for KDE
|
||||
*
|
||||
* Copyright (C) 2009 by Kare Sars <kare dot sars at iki dot fi>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) version 3, or any
|
||||
* later version accepted by the membership of KDE e.V. (or its
|
||||
* successor approved by the membership of KDE e.V.), which shall
|
||||
* act as a proxy defined in Section 6 of version 3 of the license.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* ============================================================ */
|
||||
|
||||
#ifndef KSANE_OPT_FSLIDER_H
|
||||
#define KSANE_OPT_FSLIDER_H
|
||||
|
||||
#include "ksane_option.h"
|
||||
|
||||
namespace KSaneIface
|
||||
{
|
||||
|
||||
class LabeledFSlider;
|
||||
|
||||
class KSaneOptFSlider : public KSaneOption
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
KSaneOptFSlider(const SANE_Handle handle, const int index);
|
||||
|
||||
void createWidget(QWidget *parent);
|
||||
|
||||
void readValue();
|
||||
void readOption();
|
||||
|
||||
bool getMinValue(float &max);
|
||||
bool getMaxValue(float &max);
|
||||
bool getValue(float &val);
|
||||
bool setValue(float val);
|
||||
bool getValue(QString &val);
|
||||
bool setValue(const QString &val);
|
||||
bool hasGui() {return true;}
|
||||
|
||||
Q_SIGNALS:
|
||||
void fValueRead(float);
|
||||
|
||||
private Q_SLOTS:
|
||||
void sliderChanged(float val);
|
||||
|
||||
private:
|
||||
LabeledFSlider *m_slider;
|
||||
float m_fVal;
|
||||
float m_minChange;
|
||||
};
|
||||
|
||||
} // NameSpace KSaneIface
|
||||
|
||||
#endif
|
109
libksane/libksane/options/ksane_opt_gamma.cpp
Normal file
109
libksane/libksane/options/ksane_opt_gamma.cpp
Normal file
|
@ -0,0 +1,109 @@
|
|||
/* ============================================================
|
||||
*
|
||||
* This file is part of the KDE project
|
||||
*
|
||||
* Date : 2009-01-31
|
||||
* Description : Sane interface for KDE
|
||||
*
|
||||
* Copyright (C) 2009 by Kare Sars <kare dot sars at iki dot fi>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) version 3, or any
|
||||
* later version accepted by the membership of KDE e.V. (or its
|
||||
* successor approved by the membership of KDE e.V.), which shall
|
||||
* act as a proxy defined in Section 6 of version 3 of the license.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* ============================================================ */
|
||||
// Local includes
|
||||
#include "ksane_opt_gamma.h"
|
||||
#include "ksane_opt_gamma.moc"
|
||||
|
||||
#include "labeled_gamma.h"
|
||||
|
||||
// Qt includes
|
||||
#include <QtCore/QVarLengthArray>
|
||||
|
||||
// KDE includes
|
||||
#include <KDebug>
|
||||
#include <KLocale>
|
||||
|
||||
namespace KSaneIface
|
||||
{
|
||||
|
||||
KSaneOptGamma::KSaneOptGamma(const SANE_Handle handle, const int index)
|
||||
: KSaneOption(handle, index), m_gamma(0)
|
||||
{
|
||||
}
|
||||
|
||||
void KSaneOptGamma::createWidget(QWidget *parent)
|
||||
{
|
||||
if (m_widget) return;
|
||||
|
||||
readOption();
|
||||
|
||||
if (!m_optDesc) {
|
||||
kDebug() << "This is a bug";
|
||||
m_widget = new KSaneOptionWidget(parent, "");
|
||||
return;
|
||||
}
|
||||
|
||||
m_widget = m_gamma = new LabeledGamma(parent, i18n(m_optDesc->title),
|
||||
m_optDesc->size/sizeof(SANE_Word));
|
||||
connect(m_gamma, SIGNAL(gammaTableChanged(QVector<int>)),
|
||||
this, SLOT(gammaTableChanged(QVector<int>)));
|
||||
if (strcmp(m_optDesc->name, SANE_NAME_GAMMA_VECTOR_R) == 0) m_gamma->setColor(Qt::red);
|
||||
if (strcmp(m_optDesc->name, SANE_NAME_GAMMA_VECTOR_G) == 0) m_gamma->setColor(Qt::green);
|
||||
if (strcmp(m_optDesc->name, SANE_NAME_GAMMA_VECTOR_B) == 0) m_gamma->setColor(Qt::blue);
|
||||
|
||||
m_widget->setToolTip(i18n(m_optDesc->desc));
|
||||
updateVisibility();
|
||||
readValue();
|
||||
}
|
||||
|
||||
void KSaneOptGamma::gammaTableChanged(const QVector<int> &gam_tbl)
|
||||
{
|
||||
QVector<int> copy = gam_tbl;
|
||||
writeData(copy.data());
|
||||
}
|
||||
|
||||
void KSaneOptGamma::readValue()
|
||||
{
|
||||
// Unfortunately gamma table to brigthness, contrast and gamma is
|
||||
// not easy nor fast.. ergo not done
|
||||
}
|
||||
|
||||
bool KSaneOptGamma::getValue(float &) {return false;}
|
||||
bool KSaneOptGamma::setValue(float) {return false;}
|
||||
|
||||
bool KSaneOptGamma::getValue(QString &val)
|
||||
{
|
||||
if (!m_gamma) return false;
|
||||
if (state() == STATE_HIDDEN) return false;
|
||||
int bri;
|
||||
int con;
|
||||
int gam;
|
||||
m_gamma->getValues(bri, con, gam);
|
||||
val = QString().sprintf("%d:%d:%d", bri, con, gam);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool KSaneOptGamma::setValue(const QString &val)
|
||||
{
|
||||
if (!m_gamma) return false;
|
||||
if (state() == STATE_HIDDEN) return false;
|
||||
|
||||
m_gamma->setValues(val);
|
||||
return true;
|
||||
}
|
||||
|
||||
} // NameSpace KSaneIface
|
64
libksane/libksane/options/ksane_opt_gamma.h
Normal file
64
libksane/libksane/options/ksane_opt_gamma.h
Normal file
|
@ -0,0 +1,64 @@
|
|||
/* ============================================================
|
||||
*
|
||||
* This file is part of the KDE project
|
||||
*
|
||||
* Date : 2009-01-31
|
||||
* Description : Sane interface for KDE
|
||||
*
|
||||
* Copyright (C) 2009 by Kare Sars <kare dot sars at iki dot fi>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) version 3, or any
|
||||
* later version accepted by the membership of KDE e.V. (or its
|
||||
* successor approved by the membership of KDE e.V.), which shall
|
||||
* act as a proxy defined in Section 6 of version 3 of the license.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* ============================================================ */
|
||||
|
||||
#ifndef KSANE_OPT_GAMMA_H
|
||||
#define KSANE_OPT_GAMMA_H
|
||||
|
||||
#include "ksane_option.h"
|
||||
|
||||
namespace KSaneIface
|
||||
{
|
||||
|
||||
class LabeledGamma;
|
||||
|
||||
class KSaneOptGamma : public KSaneOption
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
KSaneOptGamma(const SANE_Handle handle, const int index);
|
||||
|
||||
void createWidget(QWidget *parent);
|
||||
|
||||
void readValue();
|
||||
|
||||
bool getValue(float &val);
|
||||
bool setValue(float val);
|
||||
bool getValue(QString &val);
|
||||
bool setValue(const QString &val);
|
||||
bool hasGui() {return true;}
|
||||
|
||||
private Q_SLOTS:
|
||||
void gammaTableChanged(const QVector<int> &gam_tbl);
|
||||
|
||||
private:
|
||||
LabeledGamma *m_gamma;
|
||||
};
|
||||
|
||||
} // NameSpace KSaneIface
|
||||
|
||||
#endif
|
164
libksane/libksane/options/ksane_opt_slider.cpp
Normal file
164
libksane/libksane/options/ksane_opt_slider.cpp
Normal file
|
@ -0,0 +1,164 @@
|
|||
/* ============================================================
|
||||
*
|
||||
* This file is part of the KDE project
|
||||
*
|
||||
* Date : 2009-01-21
|
||||
* Description : Sane interface for KDE
|
||||
*
|
||||
* Copyright (C) 2009 by Kare Sars <kare dot sars at iki dot fi>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) version 3, or any
|
||||
* later version accepted by the membership of KDE e.V. (or its
|
||||
* successor approved by the membership of KDE e.V.), which shall
|
||||
* act as a proxy defined in Section 6 of version 3 of the license.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* ============================================================ */
|
||||
// Local includes
|
||||
#include "ksane_opt_slider.h"
|
||||
#include "ksane_opt_slider.moc"
|
||||
|
||||
#include "labeled_slider.h"
|
||||
|
||||
// Qt includes
|
||||
#include <QtCore/QVarLengthArray>
|
||||
|
||||
// KDE includes
|
||||
#include <KDebug>
|
||||
#include <KLocale>
|
||||
|
||||
static const int KSW_INT_MAX = 2147483647;
|
||||
static const int KSW_INT_MIN = -2147483647-1; // prevent warning
|
||||
|
||||
|
||||
namespace KSaneIface
|
||||
{
|
||||
|
||||
KSaneOptSlider::KSaneOptSlider(const SANE_Handle handle, const int index)
|
||||
: KSaneOption(handle, index), m_slider(0), m_iVal(0)
|
||||
{
|
||||
}
|
||||
|
||||
void KSaneOptSlider::createWidget(QWidget *parent)
|
||||
{
|
||||
if (m_widget) return;
|
||||
|
||||
m_widget = m_slider = new LabeledSlider(parent, "", KSW_INT_MIN, KSW_INT_MAX, 1);
|
||||
readOption();
|
||||
m_widget->setToolTip(i18n(m_optDesc->desc));
|
||||
connect(m_slider, SIGNAL(valueChanged(int)), this, SLOT(sliderChanged(int)));
|
||||
readValue();
|
||||
}
|
||||
|
||||
|
||||
void KSaneOptSlider::readValue()
|
||||
{
|
||||
if (state() == STATE_HIDDEN) return;
|
||||
|
||||
// read that current value
|
||||
QVarLengthArray<unsigned char> data(m_optDesc->size);
|
||||
SANE_Status status;
|
||||
SANE_Int res;
|
||||
status = sane_control_option (m_handle, m_index, SANE_ACTION_GET_VALUE, data.data(), &res);
|
||||
if (status != SANE_STATUS_GOOD) {
|
||||
return;
|
||||
}
|
||||
|
||||
m_iVal = toSANE_Word(data.data());
|
||||
if ((m_slider != 0) && (m_slider->value() != m_iVal)) {
|
||||
m_slider->setValue(m_iVal);
|
||||
}
|
||||
emit fValueRead((float)m_iVal);
|
||||
}
|
||||
|
||||
void KSaneOptSlider::readOption()
|
||||
{
|
||||
KSaneOption::readOption();
|
||||
|
||||
if (!m_slider) return;
|
||||
|
||||
if (m_optDesc->constraint_type == SANE_CONSTRAINT_RANGE) {
|
||||
m_slider->setRange(m_optDesc->constraint.range->min, m_optDesc->constraint.range->max);
|
||||
m_slider->setStep(m_optDesc->constraint.range->quant);
|
||||
}
|
||||
else {
|
||||
m_slider->setRange(KSW_INT_MIN, KSW_INT_MAX);
|
||||
m_slider->setStep(1);
|
||||
}
|
||||
m_slider->setSuffix(unitString());
|
||||
m_slider->setLabelText(i18n(m_optDesc->title));
|
||||
}
|
||||
|
||||
void KSaneOptSlider::sliderChanged(int val)
|
||||
{
|
||||
if (val == m_iVal) return;
|
||||
unsigned char data[4];
|
||||
m_iVal = val;
|
||||
fromSANE_Word(data, val);
|
||||
writeData(data);
|
||||
}
|
||||
|
||||
bool KSaneOptSlider::getMinValue(float &val)
|
||||
{
|
||||
if (m_optDesc->constraint_type == SANE_CONSTRAINT_RANGE) {
|
||||
val = (float)m_optDesc->constraint.range->min;
|
||||
}
|
||||
else {
|
||||
val = (float)KSW_INT_MIN;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool KSaneOptSlider::getMaxValue(float &val)
|
||||
{
|
||||
if (m_optDesc->constraint_type == SANE_CONSTRAINT_RANGE) {
|
||||
val = (float)m_optDesc->constraint.range->max;
|
||||
}
|
||||
else {
|
||||
val = (float)KSW_INT_MAX;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool KSaneOptSlider::getValue(float &val)
|
||||
{
|
||||
if (state() == STATE_HIDDEN) return false;
|
||||
val = (float)m_iVal;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool KSaneOptSlider::setValue(float val)
|
||||
{
|
||||
if (state() == STATE_HIDDEN) return false;
|
||||
sliderChanged((int)val);
|
||||
readValue();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool KSaneOptSlider::getValue(QString &val)
|
||||
{
|
||||
if (state() == STATE_HIDDEN) return false;
|
||||
val = QString::number(m_iVal);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool KSaneOptSlider::setValue(const QString &val)
|
||||
{
|
||||
if (state() == STATE_HIDDEN) return false;
|
||||
sliderChanged(val.toInt());
|
||||
readValue();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
} // NameSpace KSaneIface
|
71
libksane/libksane/options/ksane_opt_slider.h
Normal file
71
libksane/libksane/options/ksane_opt_slider.h
Normal file
|
@ -0,0 +1,71 @@
|
|||
/* ============================================================
|
||||
*
|
||||
* This file is part of the KDE project
|
||||
*
|
||||
* Date : 2009-01-21
|
||||
* Description : Sane interface for KDE
|
||||
*
|
||||
* Copyright (C) 2009 by Kare Sars <kare dot sars at iki dot fi>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) version 3, or any
|
||||
* later version accepted by the membership of KDE e.V. (or its
|
||||
* successor approved by the membership of KDE e.V.), which shall
|
||||
* act as a proxy defined in Section 6 of version 3 of the license.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* ============================================================ */
|
||||
|
||||
#ifndef KSANE_OPT_SLIDER_H
|
||||
#define KSANE_OPT_SLIDER_H
|
||||
|
||||
#include "ksane_option.h"
|
||||
|
||||
namespace KSaneIface
|
||||
{
|
||||
|
||||
class LabeledSlider;
|
||||
|
||||
class KSaneOptSlider : public KSaneOption
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
KSaneOptSlider(const SANE_Handle handle, const int index);
|
||||
|
||||
void createWidget(QWidget *parent);
|
||||
|
||||
void readValue();
|
||||
void readOption();
|
||||
|
||||
bool getMinValue(float &max);
|
||||
bool getMaxValue(float &max);
|
||||
bool getValue(float &val);
|
||||
bool setValue(float val);
|
||||
bool getValue(QString &val);
|
||||
bool setValue(const QString &val);
|
||||
bool hasGui() {return true;}
|
||||
|
||||
Q_SIGNALS:
|
||||
void fValueRead(float);
|
||||
|
||||
private Q_SLOTS:
|
||||
void sliderChanged(int val);
|
||||
|
||||
private:
|
||||
LabeledSlider *m_slider;
|
||||
int m_iVal;
|
||||
};
|
||||
|
||||
} // NameSpace KSaneIface
|
||||
|
||||
#endif
|
343
libksane/libksane/options/ksane_option.cpp
Normal file
343
libksane/libksane/options/ksane_option.cpp
Normal file
|
@ -0,0 +1,343 @@
|
|||
/* ============================================================
|
||||
*
|
||||
* This file is part of the KDE project
|
||||
*
|
||||
* Date : 2009-01-21
|
||||
* Description : Sane interface for KDE
|
||||
*
|
||||
* Copyright (C) 2009 by Kare Sars <kare dot sars at iki dot fi>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) version 3, or any
|
||||
* later version accepted by the membership of KDE e.V. (or its
|
||||
* successor approved by the membership of KDE e.V.), which shall
|
||||
* act as a proxy defined in Section 6 of version 3 of the license.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* ============================================================ */
|
||||
// Local includes
|
||||
#include "ksane_option.h"
|
||||
#include "ksane_option.moc"
|
||||
|
||||
// KDE includes
|
||||
#include <KDebug>
|
||||
#include <KLocale>
|
||||
|
||||
#include "ksane_option_widget.h"
|
||||
|
||||
namespace KSaneIface
|
||||
{
|
||||
|
||||
KSaneOption::KSaneOption(const SANE_Handle handle, const int index)
|
||||
: QObject(), m_handle(handle), m_index(index)
|
||||
{
|
||||
m_widget = 0;
|
||||
m_data = 0;
|
||||
readOption();
|
||||
}
|
||||
|
||||
KSaneOption::~KSaneOption()
|
||||
{
|
||||
if (m_data) {
|
||||
free(m_data);
|
||||
m_data = 0;
|
||||
}
|
||||
// delete the frame, just in case if no parent is set
|
||||
delete m_widget;
|
||||
m_widget = 0;
|
||||
}
|
||||
|
||||
void KSaneOption::createWidget(QWidget *parent)
|
||||
{
|
||||
if (!m_widget) {
|
||||
m_widget = new KSaneOptionWidget(parent, "");
|
||||
}
|
||||
|
||||
if (m_optDesc) {
|
||||
m_widget->setToolTip(i18n(m_optDesc->desc));
|
||||
}
|
||||
|
||||
readOption();
|
||||
readValue();
|
||||
}
|
||||
|
||||
void KSaneOption::readOption()
|
||||
{
|
||||
m_optDesc = sane_get_option_descriptor(m_handle, m_index);
|
||||
updateVisibility();
|
||||
}
|
||||
|
||||
void KSaneOption::updateVisibility()
|
||||
{
|
||||
if (!m_widget) return;
|
||||
|
||||
if (state() == STATE_HIDDEN) {
|
||||
m_widget->hide();
|
||||
}
|
||||
else {
|
||||
m_widget->show();
|
||||
m_widget->setEnabled(state() == STATE_SHOWN);
|
||||
}
|
||||
}
|
||||
|
||||
KSaneOption::KSaneOptWState KSaneOption::state()
|
||||
{
|
||||
if (!m_optDesc) return STATE_HIDDEN;
|
||||
|
||||
if (((m_optDesc->cap & SANE_CAP_SOFT_DETECT) == 0) ||
|
||||
(m_optDesc->cap & SANE_CAP_INACTIVE) ||
|
||||
((m_optDesc->size == 0) && (optionType(m_optDesc) != TYPE_BUTTON)))
|
||||
{
|
||||
return STATE_HIDDEN;
|
||||
}
|
||||
else if ((m_optDesc->cap & SANE_CAP_SOFT_SELECT) == 0) {
|
||||
return STATE_DISABLED;
|
||||
}
|
||||
return STATE_SHOWN;
|
||||
}
|
||||
|
||||
bool KSaneOption::needsPolling()
|
||||
{
|
||||
if (!m_optDesc) return false;
|
||||
|
||||
if ((m_optDesc->cap & SANE_CAP_SOFT_DETECT) && !(m_optDesc->cap & SANE_CAP_SOFT_SELECT)) {
|
||||
kDebug() << name() << "optDesc->cap =" << m_optDesc->cap;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
QString KSaneOption::name()
|
||||
{
|
||||
if (m_optDesc == 0) return QString("");
|
||||
return QString(m_optDesc->name);
|
||||
}
|
||||
|
||||
bool KSaneOption::writeData(void *data)
|
||||
{
|
||||
SANE_Status status;
|
||||
SANE_Int res;
|
||||
|
||||
if (state() == STATE_DISABLED) {
|
||||
return false;
|
||||
}
|
||||
|
||||
status = sane_control_option (m_handle, m_index, SANE_ACTION_SET_VALUE, data, &res);
|
||||
if (status != SANE_STATUS_GOOD) {
|
||||
kDebug() << m_optDesc->name << "sane_control_option returned:" << sane_strstatus(status);
|
||||
// write failed. re read the current setting
|
||||
readValue();
|
||||
return false;
|
||||
}
|
||||
if ((res & SANE_INFO_INEXACT) && (m_widget != 0)) {
|
||||
//kDebug() << "write was inexact. Reload value just in case...";
|
||||
readValue();
|
||||
}
|
||||
|
||||
if (res & SANE_INFO_RELOAD_OPTIONS) {
|
||||
emit optsNeedReload();
|
||||
// optReload reloads also the values
|
||||
}
|
||||
else if (res & SANE_INFO_RELOAD_PARAMS) {
|
||||
// 'else if' because with optReload we force also valReload :)
|
||||
emit valsNeedReload();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void KSaneOption::readValue() {}
|
||||
|
||||
SANE_Word KSaneOption::toSANE_Word(unsigned char *data)
|
||||
{
|
||||
SANE_Word tmp;
|
||||
// if __BYTE_ORDER is not defined we get #if 0 == 0
|
||||
#if __BYTE_ORDER == __LITTLE_ENDIAN
|
||||
tmp = (data[0]&0xff);
|
||||
tmp += ((SANE_Word)(data[1]&0xff))<<8;
|
||||
tmp += ((SANE_Word)(data[2]&0xff))<<16;
|
||||
tmp += ((SANE_Word)(data[3]&0xff))<<24;
|
||||
#else
|
||||
tmp = (data[3]&0xff);
|
||||
tmp += ((SANE_Word)(data[2]&0xff))<<8;
|
||||
tmp += ((SANE_Word)(data[1]&0xff))<<16;
|
||||
tmp += ((SANE_Word)(data[0]&0xff))<<24;
|
||||
#endif
|
||||
return tmp;
|
||||
}
|
||||
|
||||
void KSaneOption::fromSANE_Word(unsigned char *data, SANE_Word from)
|
||||
{
|
||||
// if __BYTE_ORDER is not defined we get #if 0 == 0
|
||||
#if __BYTE_ORDER == __LITTLE_ENDIAN
|
||||
data[0] = (from & 0x000000FF);
|
||||
data[1] = (from & 0x0000FF00)>>8;
|
||||
data[2] = (from & 0x00FF0000)>>16;
|
||||
data[3] = (from & 0xFF000000)>>24;
|
||||
#else
|
||||
data[3] = (from & 0x000000FF);
|
||||
data[2] = (from & 0x0000FF00)>>8;
|
||||
data[1] = (from & 0x00FF0000)>>16;
|
||||
data[0] = (from & 0xFF000000)>>24;
|
||||
#endif
|
||||
}
|
||||
|
||||
bool KSaneOption::getMinValue(float &) {return false;}
|
||||
bool KSaneOption::getMaxValue(float &) {return false;}
|
||||
bool KSaneOption::getValue(float &) {return false;}
|
||||
bool KSaneOption::setValue(float) {return false;}
|
||||
bool KSaneOption::getValue(QString &) {return false;}
|
||||
bool KSaneOption::setValue(const QString &) {return false;}
|
||||
int KSaneOption::getUnit() {return m_optDesc->unit;}
|
||||
|
||||
bool KSaneOption::storeCurrentData()
|
||||
{
|
||||
SANE_Status status;
|
||||
SANE_Int res;
|
||||
|
||||
// check if we can read the value
|
||||
if (!hasGui()) return false;
|
||||
if (state() == STATE_HIDDEN) return false;
|
||||
|
||||
// read that current value
|
||||
if (m_data != 0) free(m_data);
|
||||
m_data = (unsigned char *)malloc(m_optDesc->size);
|
||||
status = sane_control_option (m_handle, m_index, SANE_ACTION_GET_VALUE, m_data, &res);
|
||||
if (status != SANE_STATUS_GOOD) {
|
||||
kDebug() << m_optDesc->name << "sane_control_option returned" << status;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool KSaneOption::restoreSavedData()
|
||||
{
|
||||
// check if we have saved any data
|
||||
if (m_data == 0) return false;
|
||||
|
||||
// check if we can write the value
|
||||
if (!hasGui()) return false;
|
||||
if (state() == STATE_HIDDEN) return false;
|
||||
if (state() == STATE_DISABLED) return false;
|
||||
|
||||
writeData(m_data);
|
||||
readValue();
|
||||
return true;
|
||||
}
|
||||
|
||||
KSaneOption::KSaneOptType KSaneOption::optionType(const SANE_Option_Descriptor *optDesc)
|
||||
{
|
||||
if (!optDesc) return TYPE_DETECT_FAIL;
|
||||
|
||||
switch (optDesc->constraint_type) {
|
||||
case SANE_CONSTRAINT_NONE:
|
||||
switch(optDesc->type)
|
||||
{
|
||||
case SANE_TYPE_BOOL:
|
||||
return TYPE_CHECKBOX;
|
||||
case SANE_TYPE_INT:
|
||||
if (optDesc->size == sizeof(SANE_Word)) return TYPE_SLIDER;
|
||||
kDebug() << "Can not handle:"<< optDesc->title;
|
||||
kDebug() << "SANE_CONSTRAINT_NONE && SANE_TYPE_INT";
|
||||
kDebug() << "size" << optDesc->size<< "!= sizeof(SANE_Word)";
|
||||
break;
|
||||
case SANE_TYPE_FIXED:
|
||||
if (optDesc->size == sizeof(SANE_Word)) return TYPE_F_SLIDER;
|
||||
kDebug() << "Can not handle:"<< optDesc->title;
|
||||
kDebug() << "SANE_CONSTRAINT_NONE && SANE_TYPE_FIXED";
|
||||
kDebug() << "size" << optDesc->size<< "!= sizeof(SANE_Word)";
|
||||
break;
|
||||
case SANE_TYPE_BUTTON:
|
||||
return TYPE_BUTTON;
|
||||
case SANE_TYPE_STRING:
|
||||
return TYPE_ENTRY;
|
||||
case SANE_TYPE_GROUP:
|
||||
return TYPE_DETECT_FAIL;
|
||||
}
|
||||
break;
|
||||
case SANE_CONSTRAINT_RANGE:
|
||||
switch(optDesc->type) {
|
||||
case SANE_TYPE_BOOL:
|
||||
return TYPE_CHECKBOX;
|
||||
case SANE_TYPE_INT:
|
||||
if (optDesc->size == sizeof(SANE_Word)) return TYPE_SLIDER;
|
||||
|
||||
if ((strcmp(optDesc->name, SANE_NAME_GAMMA_VECTOR) == 0) ||
|
||||
(strcmp(optDesc->name, SANE_NAME_GAMMA_VECTOR_R) == 0) ||
|
||||
(strcmp(optDesc->name, SANE_NAME_GAMMA_VECTOR_G) == 0) ||
|
||||
(strcmp(optDesc->name, SANE_NAME_GAMMA_VECTOR_B) == 0))
|
||||
{
|
||||
return TYPE_GAMMA;
|
||||
}
|
||||
kDebug() << "Can not handle:"<< optDesc->title;
|
||||
kDebug() << "SANE_CONSTRAINT_RANGE && SANE_TYPE_INT && !SANE_NAME_GAMMA_VECTOR...";
|
||||
kDebug() << "size" << optDesc->size<< "!= sizeof(SANE_Word)";
|
||||
break;
|
||||
case SANE_TYPE_FIXED:
|
||||
if (optDesc->size == sizeof(SANE_Word)) return TYPE_F_SLIDER;
|
||||
kDebug() << "Can not handle:"<< optDesc->title;
|
||||
kDebug() << "SANE_CONSTRAINT_RANGE && SANE_TYPE_FIXED";
|
||||
kDebug() << "size" << optDesc->size<< "!= sizeof(SANE_Word)";
|
||||
kDebug() << "Analog Gamma vector?";
|
||||
break;
|
||||
case SANE_TYPE_STRING:
|
||||
kDebug() << "Can not handle:" << optDesc->title;
|
||||
kDebug() << "SANE_CONSTRAINT_RANGE && SANE_TYPE_STRING";
|
||||
return TYPE_DETECT_FAIL;
|
||||
case SANE_TYPE_BUTTON:
|
||||
return TYPE_BUTTON;
|
||||
case SANE_TYPE_GROUP:
|
||||
return TYPE_DETECT_FAIL;
|
||||
}
|
||||
break;
|
||||
case SANE_CONSTRAINT_WORD_LIST:
|
||||
case SANE_CONSTRAINT_STRING_LIST:
|
||||
return TYPE_COMBO;
|
||||
}
|
||||
return TYPE_DETECT_FAIL;
|
||||
}
|
||||
|
||||
KLocalizedString KSaneOption::unitString()
|
||||
{
|
||||
switch(m_optDesc->unit)
|
||||
{
|
||||
case SANE_UNIT_NONE: return KLocalizedString();
|
||||
case SANE_UNIT_PIXEL: return ki18ncp("SpinBox parameter unit", " Pixel", " Pixels");
|
||||
case SANE_UNIT_BIT: return ki18ncp("SpinBox parameter unit", " Bit", " Bits");
|
||||
case SANE_UNIT_MM: return ki18nc("SpinBox parameter unit (Millimeter)", " mm");
|
||||
case SANE_UNIT_DPI: return ki18nc("SpinBox parameter unit (Dots Per Inch)", " DPI");
|
||||
case SANE_UNIT_PERCENT: return ki18nc("SpinBox parameter unit (Percentage)", " %");
|
||||
case SANE_UNIT_MICROSECOND: return ki18nc("SpinBox parameter unit (Microseconds)", " µs");
|
||||
}
|
||||
return KLocalizedString();
|
||||
}
|
||||
|
||||
QString KSaneOption::unitDoubleString()
|
||||
{
|
||||
switch(m_optDesc->unit)
|
||||
{
|
||||
case SANE_UNIT_NONE: return QString("");
|
||||
case SANE_UNIT_PIXEL: return i18nc("Double numbers. SpinBox parameter unit", " Pixels");
|
||||
case SANE_UNIT_BIT: return i18nc("Double numbers. SpinBox parameter unit", " Bits");
|
||||
case SANE_UNIT_MM: return i18nc("Double numbers. SpinBox parameter unit (Millimeter)", " mm");
|
||||
case SANE_UNIT_DPI: return i18nc("Double numbers. SpinBox parameter unit (Dots Per Inch)", " DPI");
|
||||
case SANE_UNIT_PERCENT: return i18nc("Double numbers. SpinBox parameter unit (Percentage)", " %");
|
||||
case SANE_UNIT_MICROSECOND: return i18nc("Double numbers. SpinBox parameter unit (Microseconds)", " µs");
|
||||
}
|
||||
return QString("");
|
||||
}
|
||||
|
||||
|
||||
|
||||
} // NameSpace KSaneIface
|
122
libksane/libksane/options/ksane_option.h
Normal file
122
libksane/libksane/options/ksane_option.h
Normal file
|
@ -0,0 +1,122 @@
|
|||
/* ============================================================
|
||||
*
|
||||
* This file is part of the KDE project
|
||||
*
|
||||
* Date : 2009-01-21
|
||||
* Description : Sane interface for KDE
|
||||
*
|
||||
* Copyright (C) 2009 by Kare Sars <kare dot sars at iki dot fi>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) version 3, or any
|
||||
* later version accepted by the membership of KDE e.V. (or its
|
||||
* successor approved by the membership of KDE e.V.), which shall
|
||||
* act as a proxy defined in Section 6 of version 3 of the license.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* ============================================================ */
|
||||
|
||||
#ifndef KSANE_OPTION_H
|
||||
#define KSANE_OPTION_H
|
||||
|
||||
// Qt includes
|
||||
#include <QFrame>
|
||||
|
||||
//KDE includes
|
||||
#include <KLocalizedString>
|
||||
|
||||
// Sane includes
|
||||
extern "C"
|
||||
{
|
||||
#include <sane/sane.h>
|
||||
#include <sane/saneopts.h>
|
||||
}
|
||||
|
||||
namespace KSaneIface
|
||||
{
|
||||
|
||||
class KSaneOptionWidget;
|
||||
|
||||
class KSaneOption : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
|
||||
typedef enum
|
||||
{
|
||||
TYPE_DETECT_FAIL,
|
||||
TYPE_CHECKBOX,
|
||||
TYPE_SLIDER,
|
||||
TYPE_F_SLIDER,
|
||||
TYPE_COMBO,
|
||||
TYPE_ENTRY,
|
||||
TYPE_GAMMA,
|
||||
TYPE_BUTTON
|
||||
} KSaneOptType;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
STATE_HIDDEN,
|
||||
STATE_DISABLED,
|
||||
STATE_SHOWN
|
||||
} KSaneOptWState;
|
||||
|
||||
KSaneOption(const SANE_Handle handle, const int index);
|
||||
~KSaneOption();
|
||||
static KSaneOptType optionType(const SANE_Option_Descriptor *optDesc);
|
||||
|
||||
KSaneOptionWidget *widget() {return m_widget;}
|
||||
virtual bool hasGui() {return false;}
|
||||
bool needsPolling();
|
||||
KSaneOptWState state();
|
||||
QString name();
|
||||
|
||||
virtual void createWidget(QWidget *parent);
|
||||
|
||||
virtual void readOption();
|
||||
virtual void readValue();
|
||||
|
||||
virtual bool getMinValue(float &max);
|
||||
virtual bool getMaxValue(float &max);
|
||||
virtual bool getValue(float &val);
|
||||
virtual bool setValue(float val);
|
||||
virtual bool getValue(QString &val);
|
||||
virtual bool setValue(const QString &val);
|
||||
virtual int getUnit();
|
||||
|
||||
bool storeCurrentData();
|
||||
bool restoreSavedData();
|
||||
|
||||
Q_SIGNALS:
|
||||
void optsNeedReload();
|
||||
void valsNeedReload();
|
||||
|
||||
protected:
|
||||
|
||||
SANE_Word toSANE_Word(unsigned char *data);
|
||||
void fromSANE_Word(unsigned char *data, SANE_Word from);
|
||||
bool writeData(void *data);
|
||||
KLocalizedString unitString();
|
||||
QString unitDoubleString();
|
||||
void updateVisibility();
|
||||
|
||||
SANE_Handle m_handle;
|
||||
int m_index;
|
||||
const SANE_Option_Descriptor *m_optDesc; ///< This pointer is provided by sane
|
||||
unsigned char *m_data;
|
||||
KSaneOptionWidget *m_widget;
|
||||
};
|
||||
|
||||
} // NameSpace KSaneIface
|
||||
|
||||
#endif // KSANE_OPTION_H
|
262
libksane/libksane/selectionitem.cpp
Normal file
262
libksane/libksane/selectionitem.cpp
Normal file
|
@ -0,0 +1,262 @@
|
|||
/* ============================================================
|
||||
*
|
||||
* This file is part of the KDE project
|
||||
*
|
||||
* Date : 2008-11-15
|
||||
* Description :Selection QGraphicsItem for the image viewer.
|
||||
*
|
||||
* Copyright (C) 2008 by Kare Sars <kare dot sars at iki dot fi>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) version 3, or any
|
||||
* later version accepted by the membership of KDE e.V. (or its
|
||||
* successor approved by the membership of KDE e.V.), which shall
|
||||
* act as a proxy defined in Section 6 of version 3 of the license.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* ============================================================ */
|
||||
|
||||
#include "selectionitem.h"
|
||||
#include <QGraphicsView>
|
||||
#include <QGraphicsScene>
|
||||
#include <QCursor>
|
||||
#include <QList>
|
||||
|
||||
namespace KSaneIface
|
||||
{
|
||||
|
||||
|
||||
static const qreal selMargin = 4.0;
|
||||
static const QPointF boundMargin(selMargin,selMargin);
|
||||
static const qreal addRemMargin = 8.0;
|
||||
static const QPointF addRemMarginPoint(addRemMargin, addRemMargin);
|
||||
|
||||
struct SelectionItem::Private
|
||||
{
|
||||
QPen penDark;
|
||||
QPen penLight;
|
||||
QPen penAddRemFg;
|
||||
QRectF rect;
|
||||
qreal maxX;
|
||||
qreal maxY;
|
||||
bool hasMaxX;
|
||||
bool hasMaxY;
|
||||
bool hasMax;
|
||||
bool isSaved;
|
||||
bool showAddRem;
|
||||
qreal invZoom;
|
||||
qreal selMargin;
|
||||
QRectF addRemRect;
|
||||
};
|
||||
|
||||
|
||||
SelectionItem::SelectionItem(QRectF rect) : QGraphicsItem(), d(new Private)
|
||||
{
|
||||
d->hasMaxX = false;
|
||||
d->hasMaxY = false;
|
||||
d->hasMax = false;
|
||||
setRect(rect);
|
||||
|
||||
d->penDark.setColor(Qt::black);
|
||||
d->penDark.setStyle(Qt::SolidLine);
|
||||
d->penLight.setColor(Qt::white);
|
||||
d->penLight.setStyle(Qt::DashLine);
|
||||
|
||||
// FIXME We should probably use some standard KDE color here and not hard code it
|
||||
d->penAddRemFg.setColor(Qt::darkGreen);
|
||||
d->penAddRemFg.setStyle(Qt::SolidLine);
|
||||
d->penAddRemFg.setWidth(3);
|
||||
|
||||
d->isSaved = false;
|
||||
d->showAddRem = false;
|
||||
d->invZoom = 1;
|
||||
d->selMargin = selMargin;
|
||||
|
||||
d->addRemRect = QRectF(0,0,0,0);
|
||||
}
|
||||
|
||||
SelectionItem::~SelectionItem()
|
||||
{
|
||||
delete d;
|
||||
}
|
||||
|
||||
void SelectionItem::saveZoom(qreal zoom)
|
||||
{
|
||||
if (zoom < 0.00001) zoom = 0.00001;
|
||||
d->invZoom = 1/zoom;
|
||||
|
||||
d->selMargin = selMargin * d->invZoom;
|
||||
|
||||
qreal margin = addRemMargin * d->invZoom;
|
||||
QPointF pMargin = addRemMarginPoint * d->invZoom;
|
||||
d->addRemRect = QRectF(d->rect.center()-pMargin, QSizeF(margin*2.0, margin*2.0));
|
||||
d->penAddRemFg.setWidthF(3.0 * d->invZoom);
|
||||
}
|
||||
|
||||
void SelectionItem::setSaved(bool isSaved)
|
||||
{
|
||||
if (isSaved) {
|
||||
d->penDark.setColor(Qt::darkBlue);
|
||||
d->penLight.setColor(Qt::red);
|
||||
d->penAddRemFg.setColor(Qt::darkRed);
|
||||
d->isSaved = true;
|
||||
}
|
||||
else {
|
||||
d->penDark.setColor(Qt::black);
|
||||
d->penLight.setColor(Qt::white);
|
||||
d->penAddRemFg.setColor(Qt::darkGreen);
|
||||
d->isSaved = false;
|
||||
}
|
||||
}
|
||||
|
||||
void SelectionItem::setMaxRight(qreal maxX)
|
||||
{
|
||||
d->maxX = maxX;
|
||||
d->hasMaxX = true;
|
||||
if (d->hasMaxY) d->hasMax = true;
|
||||
}
|
||||
|
||||
void SelectionItem::setMaxBottom(qreal maxY)
|
||||
{
|
||||
d->maxY = maxY;
|
||||
d->hasMaxY = true;
|
||||
if (d->hasMaxX) d->hasMax = true;
|
||||
}
|
||||
|
||||
SelectionItem::Intersects SelectionItem::intersects(QPointF point)
|
||||
{
|
||||
bool oldState = d->showAddRem;
|
||||
d->showAddRem = false;
|
||||
|
||||
if ((point.x() < (d->rect.left()-d->selMargin)) ||
|
||||
(point.x() > (d->rect.right()+d->selMargin)) ||
|
||||
(point.y() < (d->rect.top()-d->selMargin)) ||
|
||||
(point.y() > (d->rect.bottom()+d->selMargin)))
|
||||
{
|
||||
if (oldState != d->showAddRem) update();
|
||||
return None;
|
||||
}
|
||||
|
||||
if (point.x() < (d->rect.left()+d->selMargin)) {
|
||||
if (oldState != d->showAddRem) update();
|
||||
if (point.y() < (d->rect.top()+d->selMargin)) return TopLeft;
|
||||
if (point.y() > (d->rect.bottom()-d->selMargin)) return BottomLeft;
|
||||
return Left;
|
||||
}
|
||||
|
||||
if (point.x() > (d->rect.right()-d->selMargin)) {
|
||||
if (oldState != d->showAddRem) update();
|
||||
if (point.y() < (d->rect.top()+d->selMargin)) return TopRight;
|
||||
if (point.y() > (d->rect.bottom()-d->selMargin)) return BottomRight;
|
||||
return Right;
|
||||
}
|
||||
|
||||
if (point.y() < (d->rect.top()+d->selMargin)) {
|
||||
if (oldState != d->showAddRem) update();
|
||||
return Top;
|
||||
}
|
||||
if (point.y() > (d->rect.bottom()-d->selMargin)) {
|
||||
if (oldState != d->showAddRem) update();
|
||||
return Bottom;
|
||||
}
|
||||
|
||||
d->showAddRem = true;
|
||||
if (oldState != d->showAddRem) update();
|
||||
|
||||
if ((point.x() > d->addRemRect.left()) &&
|
||||
(point.x() < d->addRemRect.right()) &&
|
||||
(point.y() > d->addRemRect.top()) &&
|
||||
(point.y() < d->addRemRect.bottom()))
|
||||
{
|
||||
return AddRemove;
|
||||
}
|
||||
return Move;
|
||||
}
|
||||
|
||||
void SelectionItem::setRect(QRectF rect)
|
||||
{
|
||||
prepareGeometryChange();
|
||||
d->rect = rect;
|
||||
d->rect = d->rect.normalized();
|
||||
if (d->hasMax) {
|
||||
if (d->rect.top() < 0) d->rect.setTop(0);
|
||||
if (d->rect.left() < 0) d->rect.setLeft(0);
|
||||
if (d->rect.right() > d->maxX) d->rect.setRight(d->maxX);
|
||||
if (d->rect.bottom() > d->maxY) d->rect.setBottom(d->maxY);
|
||||
}
|
||||
|
||||
// calculate the add/remove rectangle
|
||||
qreal margin = addRemMargin * d->invZoom;
|
||||
QPointF pMargin = addRemMarginPoint * d->invZoom;
|
||||
d->addRemRect = QRectF(d->rect.center()-pMargin, QSizeF(margin*2, margin*2));
|
||||
}
|
||||
|
||||
QPointF SelectionItem::fixTranslation(QPointF dp)
|
||||
{
|
||||
if ((d->rect.left() + dp.x()) < 0) dp.setX(-d->rect.left());
|
||||
if ((d->rect.top() + dp.y()) < 0) dp.setY(-d->rect.top());
|
||||
if ((d->rect.right() + dp.x()) > d->maxX) dp.setX(d->maxX - d->rect.right());
|
||||
if ((d->rect.bottom() + dp.y()) > d->maxY) dp.setY(d->maxY - d->rect.bottom());
|
||||
return dp;
|
||||
}
|
||||
|
||||
QRectF SelectionItem::rect()
|
||||
{
|
||||
return d->rect;
|
||||
}
|
||||
|
||||
QRectF SelectionItem::boundingRect() const
|
||||
{
|
||||
QRectF tmp(d->rect.topLeft()-boundMargin, d->rect.bottomRight()+boundMargin);
|
||||
if (tmp.top() > d->addRemRect.top()) {
|
||||
tmp.setTop(d->addRemRect.top());
|
||||
}
|
||||
if (tmp.left() > d->addRemRect.left()) {
|
||||
tmp.setLeft(d->addRemRect.left());
|
||||
}
|
||||
|
||||
if (tmp.bottom() < d->addRemRect.bottom()) {
|
||||
tmp.setBottom(d->addRemRect.bottom());
|
||||
}
|
||||
|
||||
if (tmp.right() < d->addRemRect.right()) {
|
||||
tmp.setRight(d->addRemRect.right());
|
||||
}
|
||||
|
||||
return tmp;
|
||||
}
|
||||
|
||||
void SelectionItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *)
|
||||
{
|
||||
painter->setPen(d->penDark);
|
||||
painter->drawRect(d->rect);
|
||||
|
||||
painter->setPen(d->penLight);
|
||||
painter->drawRect(d->rect);
|
||||
|
||||
if (d->showAddRem) {
|
||||
painter->fillRect(d->addRemRect, QBrush(Qt::white));
|
||||
QLineF minus(d->addRemRect.left()+3*d->invZoom, d->rect.center().y(),
|
||||
d->addRemRect.right()-3*d->invZoom, d->rect.center().y());
|
||||
painter->setPen(d->penAddRemFg);
|
||||
|
||||
painter->drawLine(minus);
|
||||
|
||||
if (!d->isSaved) {
|
||||
QLineF plus(d->rect.center().x(), d->addRemRect.top()+3*d->invZoom,
|
||||
d->rect.center().x(), d->addRemRect.bottom()-3*d->invZoom);
|
||||
painter->drawLine(plus);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // NameSpace KSaneIface
|
82
libksane/libksane/selectionitem.h
Normal file
82
libksane/libksane/selectionitem.h
Normal file
|
@ -0,0 +1,82 @@
|
|||
/* ============================================================
|
||||
*
|
||||
* This file is part of the KDE project
|
||||
*
|
||||
* Date : 2008-11-15
|
||||
* Description :Selection QGraphicsItem for the image viewer.
|
||||
*
|
||||
* Copyright (C) 2008 by Kare Sars <kare dot sars at iki dot fi>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) version 3, or any
|
||||
* later version accepted by the membership of KDE e.V. (or its
|
||||
* successor approved by the membership of KDE e.V.), which shall
|
||||
* act as a proxy defined in Section 6 of version 3 of the license.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* ============================================================ */
|
||||
#ifndef SELECTIONITEM_H
|
||||
#define SELECTIONITEM_H
|
||||
|
||||
#include <QGraphicsPixmapItem>
|
||||
#include <QPainter>
|
||||
|
||||
namespace KSaneIface
|
||||
{
|
||||
|
||||
class SelectionItem : public QGraphicsItem
|
||||
{
|
||||
public:
|
||||
typedef enum
|
||||
{
|
||||
None,
|
||||
Top,
|
||||
TopRight,
|
||||
Right,
|
||||
BottomRight,
|
||||
Bottom,
|
||||
BottomLeft,
|
||||
Left,
|
||||
TopLeft,
|
||||
Move,
|
||||
AddRemove
|
||||
} Intersects;
|
||||
|
||||
explicit SelectionItem(QRectF rect);
|
||||
~SelectionItem();
|
||||
|
||||
void setMaxRight(qreal maxRight);
|
||||
void setMaxBottom(qreal maxBottom);
|
||||
void setSaved(bool isSaved);
|
||||
|
||||
Intersects intersects(QPointF point);
|
||||
|
||||
void saveZoom(qreal zoom);
|
||||
|
||||
void setRect(QRectF rect);
|
||||
QPointF fixTranslation(QPointF dp);
|
||||
QRectF rect();
|
||||
|
||||
public:
|
||||
// Graphics Item methods
|
||||
QRectF boundingRect() const;
|
||||
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
|
||||
|
||||
private:
|
||||
struct Private;
|
||||
Private * const d;
|
||||
};
|
||||
|
||||
} // NameSpace KSaneIface
|
||||
|
||||
#endif
|
||||
|
307
libksane/libksane/splittercollapser.cpp
Normal file
307
libksane/libksane/splittercollapser.cpp
Normal file
|
@ -0,0 +1,307 @@
|
|||
// vim: set tabstop=4 shiftwidth=4 noexpandtab:
|
||||
/*
|
||||
Gwenview: an image viewer
|
||||
Copyright 2009 Aurélien Gâteau <agateau@kde.org>
|
||||
Copyright 2009 Kåre Sårs <kare.sars@iki.fi>
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) version 3, or any
|
||||
later version accepted by the membership of KDE e.V. (or its
|
||||
successor approved by the membership of KDE e.V.), which shall
|
||||
act as a proxy defined in Section 6 of version 3 of the license.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
*/
|
||||
// Self
|
||||
#include "splittercollapser.moc"
|
||||
|
||||
// Qt
|
||||
#include <QApplication>
|
||||
#include <QEvent>
|
||||
#include <QMouseEvent>
|
||||
#include <QSplitter>
|
||||
#include <QStyleOptionToolButton>
|
||||
#include <QStylePainter>
|
||||
#include <QTimeLine>
|
||||
|
||||
// KDE
|
||||
#include <kdebug.h>
|
||||
|
||||
// Local
|
||||
|
||||
namespace KSaneIface {
|
||||
|
||||
|
||||
enum Direction {
|
||||
LTR = 1 << 0,
|
||||
RTL = 1 << 1,
|
||||
Vertical = 1 << 2,
|
||||
TTB = Vertical + (1 << 0),
|
||||
BTT = Vertical + (1 << 1)
|
||||
};
|
||||
|
||||
const int TIMELINE_DURATION = 500;
|
||||
|
||||
const qreal MINIMUM_OPACITY = 0.3;
|
||||
|
||||
struct ArrowTypes {
|
||||
ArrowTypes()
|
||||
: visible(Qt::NoArrow), notVisible(Qt::NoArrow){}
|
||||
|
||||
ArrowTypes(Qt::ArrowType t1, Qt::ArrowType t2)
|
||||
: visible(t1), notVisible(t2) {}
|
||||
|
||||
Qt::ArrowType visible,
|
||||
notVisible;
|
||||
|
||||
Qt::ArrowType get(bool isVisible) {
|
||||
return isVisible ? visible : notVisible;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
struct SplitterCollapserPrivate {
|
||||
SplitterCollapser* q;
|
||||
QSplitter* mSplitter;
|
||||
QWidget* mWidget;
|
||||
Direction mDirection;
|
||||
QTimeLine* mOpacityTimeLine;
|
||||
int mSizeAtCollaps;
|
||||
|
||||
bool isVertical() const {
|
||||
return mDirection & Vertical;
|
||||
}
|
||||
|
||||
bool isVisible() const {
|
||||
bool isVisible = mWidget->isVisible();
|
||||
QRect widgetRect = mWidget->geometry();
|
||||
if (isVisible) {
|
||||
QPoint br = widgetRect.bottomRight();
|
||||
if ((br.x() <= 0) || (br.y() <=0)) {
|
||||
isVisible = false;
|
||||
}
|
||||
}
|
||||
return isVisible;
|
||||
}
|
||||
|
||||
void updatePosition() {
|
||||
int x, y;
|
||||
QRect widgetRect = mWidget->geometry();
|
||||
int splitterWidth = mSplitter->width();
|
||||
int handleWidth = mSplitter->handleWidth();
|
||||
int width = q->width();
|
||||
|
||||
if (!isVertical()) {
|
||||
// FIXME: Make this configurable
|
||||
y = 30;
|
||||
if (mDirection == LTR) {
|
||||
if (isVisible()) {
|
||||
x = widgetRect.right() + handleWidth;
|
||||
} else {
|
||||
x = 0;
|
||||
}
|
||||
} else { // RTL
|
||||
if (isVisible()) {
|
||||
x = widgetRect.left() - handleWidth - width;
|
||||
} else {
|
||||
x = splitterWidth - handleWidth - width;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// FIXME
|
||||
x = 0;
|
||||
y = 0;
|
||||
}
|
||||
q->move(x, y);
|
||||
}
|
||||
|
||||
|
||||
void updateArrow() {
|
||||
static QMap<Direction, ArrowTypes> arrowForDirection;
|
||||
if (arrowForDirection.isEmpty()) {
|
||||
arrowForDirection[LTR] = ArrowTypes(Qt::LeftArrow, Qt::RightArrow);
|
||||
arrowForDirection[RTL] = ArrowTypes(Qt::RightArrow, Qt::LeftArrow);
|
||||
arrowForDirection[TTB] = ArrowTypes(Qt::UpArrow, Qt::DownArrow);
|
||||
arrowForDirection[BTT] = ArrowTypes(Qt::DownArrow, Qt::UpArrow);
|
||||
}
|
||||
q->setArrowType(arrowForDirection[mDirection].get(isVisible()));
|
||||
}
|
||||
|
||||
|
||||
void widgetEventFilter(QEvent* event) {
|
||||
switch (event->type()) {
|
||||
case QEvent::Resize:
|
||||
updatePosition();
|
||||
updateOpacity();
|
||||
break;
|
||||
|
||||
case QEvent::Move:
|
||||
case QEvent::Show:
|
||||
case QEvent::Hide:
|
||||
updatePosition();
|
||||
updateOpacity();
|
||||
updateArrow();
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void updateOpacity() {
|
||||
QPoint pos = q->parentWidget()->mapFromGlobal(QCursor::pos());
|
||||
QRect opaqueRect = q->geometry();
|
||||
bool opaqueCollapser = opaqueRect.contains(pos);
|
||||
int frame = mOpacityTimeLine->currentFrame();
|
||||
if (opaqueCollapser && frame == mOpacityTimeLine->startFrame()) {
|
||||
mOpacityTimeLine->setDirection(QTimeLine::Forward);
|
||||
startTimeLine();
|
||||
} else if (!opaqueCollapser && frame == mOpacityTimeLine->endFrame()) {
|
||||
mOpacityTimeLine->setDirection(QTimeLine::Backward);
|
||||
startTimeLine();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void startTimeLine() {
|
||||
if (mOpacityTimeLine->state() != QTimeLine::Running) {
|
||||
mOpacityTimeLine->start();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
SplitterCollapser::SplitterCollapser(QSplitter* splitter, QWidget* widget)
|
||||
: QToolButton(),
|
||||
d(new SplitterCollapserPrivate)
|
||||
{
|
||||
d->q = this;
|
||||
|
||||
// We do not want our collapser to be added as a regular widget in the
|
||||
// splitter!
|
||||
setAttribute(Qt::WA_NoChildEventsForParent);
|
||||
|
||||
d->mOpacityTimeLine = new QTimeLine(TIMELINE_DURATION, this);
|
||||
d->mOpacityTimeLine->setFrameRange(int(MINIMUM_OPACITY * 1000), 1000);
|
||||
connect(d->mOpacityTimeLine, SIGNAL(valueChanged(qreal)), SLOT(update()));
|
||||
|
||||
d->mWidget = widget;
|
||||
d->mWidget->installEventFilter(this);
|
||||
|
||||
qApp->installEventFilter(this);
|
||||
|
||||
d->mSplitter = splitter;
|
||||
setParent(d->mSplitter);
|
||||
|
||||
if (splitter->indexOf(widget) < splitter->count() / 2) {
|
||||
d->mDirection = LTR;
|
||||
} else {
|
||||
d->mDirection = RTL;
|
||||
}
|
||||
if (splitter->orientation() == Qt::Vertical) {
|
||||
// FIXME: Ugly!
|
||||
d->mDirection = static_cast<Direction>(int(d->mDirection) + int(TTB));
|
||||
}
|
||||
|
||||
connect(this, SIGNAL(clicked()), SLOT(slotClicked()));
|
||||
|
||||
show();
|
||||
}
|
||||
|
||||
|
||||
SplitterCollapser::~SplitterCollapser() {
|
||||
delete d;
|
||||
}
|
||||
|
||||
|
||||
bool SplitterCollapser::eventFilter(QObject* object, QEvent* event) {
|
||||
if (object == d->mWidget) {
|
||||
d->widgetEventFilter(event);
|
||||
} else { /* app */
|
||||
if (event->type() == QEvent::MouseMove) {
|
||||
d->updateOpacity();
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
QSize SplitterCollapser::sizeHint() const {
|
||||
int extent = style()->pixelMetric(QStyle::PM_ScrollBarExtent);
|
||||
QSize sh(extent * 3 / 4, extent * 240 / 100);
|
||||
if (d->isVertical()) {
|
||||
sh.transpose();
|
||||
}
|
||||
return sh;
|
||||
}
|
||||
|
||||
|
||||
void SplitterCollapser::slotClicked() {
|
||||
QList<int> sizes = d->mSplitter->sizes();
|
||||
int index = d->mSplitter->indexOf(d->mWidget);
|
||||
if (d->isVisible()) {
|
||||
d->mSizeAtCollaps = sizes[index];
|
||||
sizes[index] = 0;
|
||||
}
|
||||
else {
|
||||
if (d->mSizeAtCollaps != 0) {
|
||||
sizes[index] = d->mSizeAtCollaps;
|
||||
}
|
||||
else {
|
||||
if (d->isVertical()) {
|
||||
sizes[index] = d->mWidget->sizeHint().height();
|
||||
}
|
||||
else {
|
||||
sizes[index] = d->mWidget->sizeHint().width();
|
||||
}
|
||||
}
|
||||
}
|
||||
d->mSplitter->setSizes(sizes);
|
||||
}
|
||||
|
||||
void SplitterCollapser::slotCollapse() {
|
||||
if (d->isVisible()) slotClicked();
|
||||
// else do nothing
|
||||
}
|
||||
|
||||
void SplitterCollapser::slotRestore() {
|
||||
if (!d->isVisible()) slotClicked();
|
||||
// else do nothing
|
||||
}
|
||||
|
||||
void SplitterCollapser::slotSetCollapsed(bool collapse) {
|
||||
if (collapse == d->isVisible()) slotClicked();
|
||||
// else do nothing
|
||||
}
|
||||
|
||||
void SplitterCollapser::paintEvent(QPaintEvent*) {
|
||||
QStylePainter painter(this);
|
||||
qreal opacity = d->mOpacityTimeLine->currentFrame() / 1000.;
|
||||
painter.setOpacity(opacity);
|
||||
|
||||
QStyleOptionToolButton opt;
|
||||
initStyleOption(&opt);
|
||||
if (d->mDirection == LTR) {
|
||||
opt.rect.setLeft(-width());
|
||||
} else {
|
||||
opt.rect.setWidth(width() * 2);
|
||||
}
|
||||
painter.drawPrimitive(QStyle::PE_PanelButtonTool, opt);
|
||||
|
||||
QStyleOptionToolButton opt2;
|
||||
initStyleOption(&opt2);
|
||||
painter.drawControl(QStyle::CE_ToolButtonLabel, opt2);
|
||||
}
|
||||
|
||||
|
||||
} // namespace
|
69
libksane/libksane/splittercollapser.h
Normal file
69
libksane/libksane/splittercollapser.h
Normal file
|
@ -0,0 +1,69 @@
|
|||
// vim: set tabstop=4 shiftwidth=4 noexpandtab:
|
||||
/*
|
||||
Gwenview: an image viewer
|
||||
Copyright 2009 Aurélien Gâteau <agateau@kde.org>
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) version 3, or any
|
||||
later version accepted by the membership of KDE e.V. (or its
|
||||
successor approved by the membership of KDE e.V.), which shall
|
||||
act as a proxy defined in Section 6 of version 3 of the license.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
*/
|
||||
#ifndef SPLITTERCOLLAPSER_H
|
||||
#define SPLITTERCOLLAPSER_H
|
||||
|
||||
// Qt
|
||||
#include <QToolButton>
|
||||
|
||||
// KDE
|
||||
|
||||
class QSplitter;
|
||||
|
||||
namespace KSaneIface {
|
||||
|
||||
|
||||
struct SplitterCollapserPrivate;
|
||||
/**
|
||||
* A button which appears on the side of a splitter handle and allows easy
|
||||
* collapsing of the widget on the opposite side
|
||||
*/
|
||||
class SplitterCollapser : public QToolButton {
|
||||
Q_OBJECT
|
||||
public:
|
||||
SplitterCollapser(QSplitter*, QWidget* widget);
|
||||
~SplitterCollapser();
|
||||
|
||||
virtual QSize sizeHint() const;
|
||||
|
||||
public Q_SLOTS:
|
||||
void slotCollapse();
|
||||
void slotRestore();
|
||||
void slotSetCollapsed(bool collapsed);
|
||||
|
||||
protected:
|
||||
virtual bool eventFilter(QObject*, QEvent*);
|
||||
|
||||
virtual void paintEvent(QPaintEvent*);
|
||||
|
||||
private:
|
||||
SplitterCollapserPrivate* const d;
|
||||
|
||||
private Q_SLOTS:
|
||||
void slotClicked();
|
||||
};
|
||||
|
||||
|
||||
} // namespace
|
||||
|
||||
#endif /* SPLITTERCOLLAPSER_H */
|
30
libksane/libksane/version.h.cmake.in
Normal file
30
libksane/libksane/version.h.cmake.in
Normal file
|
@ -0,0 +1,30 @@
|
|||
/* ============================================================
|
||||
*
|
||||
* This file is a part of kipi-plugins project
|
||||
* http://www.digikam.org
|
||||
*
|
||||
* Date : 2007-02-12
|
||||
* Description : Sane interface for KDE
|
||||
*
|
||||
* Copyright (C) 2007 by Gilles Caulier <caulier dot gilles at gmail dot com>
|
||||
*
|
||||
* This program is free software; you can redistribute it
|
||||
* and/or modify it under the terms of the GNU General
|
||||
* Public License as published by the Free Software Foundation;
|
||||
* either version 2, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* ============================================================ */
|
||||
|
||||
#ifndef KSANE_VERSION_H
|
||||
#define KSANE_VERSION_H
|
||||
|
||||
static const char ksane_version[] = "${KSANE_LIB_VERSION_STRING}";
|
||||
|
||||
#define KSANE_VERSION ${KSANE_LIB_VERSION_ID}
|
||||
|
||||
#endif // KSANE_VERSION_H
|
90
libksane/libksane/widgets/gamma_disp.cpp
Normal file
90
libksane/libksane/widgets/gamma_disp.cpp
Normal file
|
@ -0,0 +1,90 @@
|
|||
/* ============================================================
|
||||
*
|
||||
* This file is part of the KDE project
|
||||
*
|
||||
* Date : 2007-09-13
|
||||
* Description : Sane interface for KDE
|
||||
*
|
||||
* Copyright (C) 2007-2008 by Kare Sars <kare.sars@iki .fi>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) version 3, or any
|
||||
* later version accepted by the membership of KDE e.V. (or its
|
||||
* successor approved by the membership of KDE e.V.), which shall
|
||||
* act as a proxy defined in Section 6 of version 3 of the license.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* ============================================================ */
|
||||
|
||||
// Local includes
|
||||
#include "gamma_disp.h"
|
||||
#include "gamma_disp.moc"
|
||||
|
||||
// Qt includes
|
||||
#include <QPainter>
|
||||
|
||||
namespace KSaneIface
|
||||
{
|
||||
|
||||
GammaDisp::GammaDisp(QWidget *parent, QVector<int> *tbl)
|
||||
: QWidget(parent)
|
||||
{
|
||||
gam_tbl = tbl;
|
||||
gam_color.setRgb(0,0,0);
|
||||
}
|
||||
|
||||
QSize GammaDisp::minimumSizeHint() const
|
||||
{
|
||||
return QSize(75, 75);
|
||||
}
|
||||
|
||||
QSize GammaDisp::sizeHint() const
|
||||
{
|
||||
return QSize(75, 75);
|
||||
}
|
||||
|
||||
void GammaDisp::setColor(const QColor &color)
|
||||
{
|
||||
gam_color = color;
|
||||
}
|
||||
|
||||
void GammaDisp::resizeEvent (QResizeEvent*)
|
||||
{
|
||||
repaint();
|
||||
}
|
||||
|
||||
void GammaDisp::paintEvent(QPaintEvent *)
|
||||
{
|
||||
/* QMemArray<QRect> rects = event->region().rects();
|
||||
for (int i = 0; i < (int)rects.size(); i++) {
|
||||
bitBlt(this, rects[i].topLeft(), &pixmap, rects[i]);
|
||||
}*/
|
||||
QPointF p1, p2;
|
||||
QPainter painter(this);
|
||||
painter.fillRect(rect(), QBrush(Qt::white));
|
||||
|
||||
double xscale = (double)(size().width()-1) / (double)gam_tbl->size();
|
||||
double yscale = (double)(size().height()-1) / (double)gam_tbl->size();
|
||||
|
||||
painter.setPen(gam_color);
|
||||
for (int i=0; i<gam_tbl->size()-1; i++) {
|
||||
p1.setX(i*xscale);
|
||||
p1.setY(size().height()- 1 - (gam_tbl->at(i) * yscale));
|
||||
|
||||
p2.setX((i+1)*xscale);
|
||||
p2.setY(size().height()- 1 - (gam_tbl->at(i+1) * yscale));
|
||||
|
||||
painter.drawLine(p1, p2);
|
||||
}
|
||||
}
|
||||
|
||||
} // NameSpace KSaneIface
|
76
libksane/libksane/widgets/gamma_disp.h
Normal file
76
libksane/libksane/widgets/gamma_disp.h
Normal file
|
@ -0,0 +1,76 @@
|
|||
/* ============================================================
|
||||
*
|
||||
* This file is part of the KDE project
|
||||
*
|
||||
* Date : 2007-09-13
|
||||
* Description : Sane interface for KDE
|
||||
*
|
||||
* Copyright (C) 2007-2008 by Kare Sars <kare.sars@iki .fi>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) version 3, or any
|
||||
* later version accepted by the membership of KDE e.V. (or its
|
||||
* successor approved by the membership of KDE e.V.), which shall
|
||||
* act as a proxy defined in Section 6 of version 3 of the license.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* ============================================================ */
|
||||
|
||||
#ifndef GAMMA_DISP_H
|
||||
#define GAMMA_DISP_H
|
||||
|
||||
// Qt includes
|
||||
|
||||
#include <QWidget>
|
||||
|
||||
/**
|
||||
*@author Kåre Särs
|
||||
*
|
||||
* This is the widget that displays the gamma table.
|
||||
*/
|
||||
|
||||
namespace KSaneIface
|
||||
{
|
||||
|
||||
class GammaDisp : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* Create a gamma display.
|
||||
* \param parent parent widget
|
||||
*/
|
||||
GammaDisp(QWidget *parent, QVector<int> *tbl);
|
||||
~GammaDisp() {};
|
||||
|
||||
QSize sizeHint() const;
|
||||
QSize minimumSizeHint() const;
|
||||
|
||||
void setColor(const QColor &color);
|
||||
|
||||
protected:
|
||||
|
||||
void paintEvent (QPaintEvent *);
|
||||
void resizeEvent(QResizeEvent *);
|
||||
|
||||
private:
|
||||
|
||||
QVector<int> *gam_tbl;
|
||||
QColor gam_color;
|
||||
};
|
||||
|
||||
} // NameSpace KSaneIface
|
||||
|
||||
#endif // GAMMA_DISP_H
|
||||
|
51
libksane/libksane/widgets/ksane_button.cpp
Normal file
51
libksane/libksane/widgets/ksane_button.cpp
Normal file
|
@ -0,0 +1,51 @@
|
|||
/* ============================================================
|
||||
*
|
||||
* This file is part of the KDE project
|
||||
*
|
||||
* Copyright (C) 2008-2011 by Kare Sars <kare.sars@iki.fi>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) version 3, or any
|
||||
* later version accepted by the membership of KDE e.V. (or its
|
||||
* successor approved by the membership of KDE e.V.), which shall
|
||||
* act as a proxy defined in Section 6 of version 3 of the license.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* ============================================================ */
|
||||
|
||||
// Local includes
|
||||
#include "ksane_button.h"
|
||||
#include "ksane_button.moc"
|
||||
|
||||
// Qt includes
|
||||
#include <KDebug>
|
||||
|
||||
namespace KSaneIface
|
||||
{
|
||||
|
||||
KSaneButton::KSaneButton(QWidget *parent, const QString& ltext)
|
||||
: KSaneOptionWidget(parent, QString())
|
||||
{
|
||||
m_button = new QPushButton(ltext, this);
|
||||
m_layout->addWidget(m_button, 0, 1);
|
||||
m_layout->addWidget(new QWidget(this), 0, 2);
|
||||
m_layout->setColumnStretch(1, 0);
|
||||
m_layout->setColumnStretch(2, 50);
|
||||
|
||||
connect(m_button, SIGNAL(clicked(bool)), this, SIGNAL(clicked()));
|
||||
}
|
||||
|
||||
KSaneButton::~KSaneButton()
|
||||
{
|
||||
}
|
||||
|
||||
} // NameSpace KSaneIface
|
67
libksane/libksane/widgets/ksane_button.h
Normal file
67
libksane/libksane/widgets/ksane_button.h
Normal file
|
@ -0,0 +1,67 @@
|
|||
/* ============================================================
|
||||
*
|
||||
* This file is part of the KDE project
|
||||
*
|
||||
* Copyright (C) 2008-2011 by Kare Sars <kare.sars@iki .fi>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) version 3, or any
|
||||
* later version accepted by the membership of KDE e.V. (or its
|
||||
* successor approved by the membership of KDE e.V.), which shall
|
||||
* act as a proxy defined in Section 6 of version 3 of the license.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* ============================================================ */
|
||||
|
||||
#ifndef KSANE_BUTTON_H
|
||||
#define KSANE_BUTTON_H
|
||||
|
||||
#include "ksane_option_widget.h"
|
||||
|
||||
// Qt includes
|
||||
#include <QPushButton>
|
||||
#include <QGridLayout>
|
||||
|
||||
namespace KSaneIface
|
||||
{
|
||||
|
||||
/**
|
||||
*@author Kåre Särs
|
||||
*/
|
||||
|
||||
/**
|
||||
* A wrapper for a checkbox
|
||||
*/
|
||||
class KSaneButton : public KSaneOptionWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
/**
|
||||
* Create the checkbox.
|
||||
*
|
||||
* \param parent parent widget
|
||||
* \param text is the text describing the checkbox.
|
||||
*/
|
||||
KSaneButton(QWidget *parent, const QString& text);
|
||||
~KSaneButton();
|
||||
|
||||
Q_SIGNALS:
|
||||
void clicked();
|
||||
|
||||
private:
|
||||
QPushButton *m_button;
|
||||
};
|
||||
|
||||
} // NameSpace KSaneIface
|
||||
|
||||
#endif // KSANE_BUTTON_H
|
74
libksane/libksane/widgets/ksane_option_widget.cpp
Normal file
74
libksane/libksane/widgets/ksane_option_widget.cpp
Normal file
|
@ -0,0 +1,74 @@
|
|||
/* ============================================================
|
||||
*
|
||||
* This file is part of the KDE project
|
||||
*
|
||||
* Description : Base class for option widgets
|
||||
*
|
||||
* Copyright (C) 2011 by Kare Sars <kare.sars@iki.fi>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) version 3, or any
|
||||
* later version accepted by the membership of KDE e.V. (or its
|
||||
* successor approved by the membership of KDE e.V.), which shall
|
||||
* act as a proxy defined in Section 6 of version 3 of the license.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* ============================================================ */
|
||||
|
||||
// Local includes
|
||||
#include "ksane_option_widget.h"
|
||||
#include "ksane_option_widget.moc"
|
||||
|
||||
// Qt includes
|
||||
#include <KDebug>
|
||||
#include <KLocale>
|
||||
|
||||
namespace KSaneIface
|
||||
{
|
||||
|
||||
KSaneOptionWidget::KSaneOptionWidget(QWidget *parent, const QString& labelText)
|
||||
: QWidget(parent)
|
||||
{
|
||||
m_label = new QLabel;
|
||||
setLabelText(labelText);
|
||||
|
||||
m_layout = new QGridLayout(this);
|
||||
m_layout->addWidget(m_label, 0, 0, Qt::AlignRight);
|
||||
m_layout->setColumnStretch(0, 0);
|
||||
m_layout->setContentsMargins(0,0,0,0);
|
||||
}
|
||||
|
||||
KSaneOptionWidget::~KSaneOptionWidget()
|
||||
{
|
||||
}
|
||||
|
||||
void KSaneOptionWidget::setLabelText(const QString &text)
|
||||
{
|
||||
if (text.isEmpty()) {
|
||||
m_label->setText(QString());
|
||||
} else {
|
||||
m_label->setText(i18nc("Label for a scanner option", "%1:", text));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int KSaneOptionWidget::labelWidthHint()
|
||||
{
|
||||
return m_label->sizeHint().width();
|
||||
}
|
||||
|
||||
void KSaneOptionWidget::setLabelWidth(int labelWidth)
|
||||
{
|
||||
m_layout->setColumnMinimumWidth(0, labelWidth);
|
||||
}
|
||||
|
||||
} // NameSpace KSaneIface
|
70
libksane/libksane/widgets/ksane_option_widget.h
Normal file
70
libksane/libksane/widgets/ksane_option_widget.h
Normal file
|
@ -0,0 +1,70 @@
|
|||
/* ============================================================
|
||||
*
|
||||
* This file is part of the KDE project
|
||||
*
|
||||
* Description : Base class for option widgets
|
||||
*
|
||||
* Copyright (C) 2011 by Kare Sars <kare.sars@iki.fi>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) version 3, or any
|
||||
* later version accepted by the membership of KDE e.V. (or its
|
||||
* successor approved by the membership of KDE e.V.), which shall
|
||||
* act as a proxy defined in Section 6 of version 3 of the license.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* ============================================================ */
|
||||
|
||||
#ifndef KSANE_OPTION_WIDGET_H
|
||||
#define KSANE_OPTION_WIDGET_H
|
||||
|
||||
// Qt includes
|
||||
#include <QWidget>
|
||||
#include <QLabel>
|
||||
#include <QGridLayout>
|
||||
|
||||
namespace KSaneIface
|
||||
{
|
||||
|
||||
/**
|
||||
*@author Kåre Särs
|
||||
*/
|
||||
|
||||
/**
|
||||
* A wrapper for a checkbox
|
||||
*/
|
||||
class KSaneOptionWidget : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
/**
|
||||
* Create the Wodget.
|
||||
* \param parent parent widget
|
||||
* \param Label text.
|
||||
*/
|
||||
KSaneOptionWidget(QWidget *parent, const QString &labelText);
|
||||
~KSaneOptionWidget();
|
||||
|
||||
void setLabelText(const QString &text);
|
||||
|
||||
int labelWidthHint();
|
||||
void setLabelWidth(int labelWidth);
|
||||
|
||||
protected:
|
||||
QLabel *m_label;
|
||||
QGridLayout *m_layout;
|
||||
};
|
||||
|
||||
} // NameSpace KSaneIface
|
||||
|
||||
#endif // KSANE_OPTION_WIDGET_H
|
62
libksane/libksane/widgets/labeled_checkbox.cpp
Normal file
62
libksane/libksane/widgets/labeled_checkbox.cpp
Normal file
|
@ -0,0 +1,62 @@
|
|||
/* ============================================================
|
||||
*
|
||||
* This file is part of the KDE project
|
||||
*
|
||||
* Date : 2007-09-13
|
||||
* Description : Sane interface for KDE
|
||||
*
|
||||
* Copyright (C) 2007-2011 by Kare Sars <kare.sars@iki .fi>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) version 3, or any
|
||||
* later version accepted by the membership of KDE e.V. (or its
|
||||
* successor approved by the membership of KDE e.V.), which shall
|
||||
* act as a proxy defined in Section 6 of version 3 of the license.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* ============================================================ */
|
||||
|
||||
// Local includes
|
||||
#include "labeled_checkbox.h"
|
||||
#include "labeled_checkbox.moc"
|
||||
|
||||
// Qt includes
|
||||
#include <KDebug>
|
||||
|
||||
namespace KSaneIface
|
||||
{
|
||||
|
||||
LabeledCheckbox::LabeledCheckbox(QWidget *parent, const QString& ltext)
|
||||
: KSaneOptionWidget(parent, QString())
|
||||
{
|
||||
chbx = new QCheckBox(ltext, this);
|
||||
m_layout->addWidget(chbx, 0, 1);
|
||||
m_layout->setColumnStretch(1, 50);
|
||||
|
||||
connect(chbx, SIGNAL(toggled(bool)), this, SIGNAL(toggled(bool)));
|
||||
}
|
||||
|
||||
LabeledCheckbox::~LabeledCheckbox()
|
||||
{
|
||||
}
|
||||
|
||||
void LabeledCheckbox::setChecked(bool is_checked)
|
||||
{
|
||||
if (is_checked != chbx->isChecked()) chbx->setChecked(is_checked);
|
||||
}
|
||||
|
||||
bool LabeledCheckbox::isChecked()
|
||||
{
|
||||
return chbx->isChecked();
|
||||
}
|
||||
|
||||
} // NameSpace KSaneIface
|
74
libksane/libksane/widgets/labeled_checkbox.h
Normal file
74
libksane/libksane/widgets/labeled_checkbox.h
Normal file
|
@ -0,0 +1,74 @@
|
|||
/* ============================================================
|
||||
*
|
||||
* This file is part of the KDE project
|
||||
*
|
||||
* Date : 2007-09-13
|
||||
* Description : Sane interface for KDE
|
||||
*
|
||||
* Copyright (C) 2007-2011 by Kare Sars <kare.sars@iki .fi>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) version 3, or any
|
||||
* later version accepted by the membership of KDE e.V. (or its
|
||||
* successor approved by the membership of KDE e.V.), which shall
|
||||
* act as a proxy defined in Section 6 of version 3 of the license.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* ============================================================ */
|
||||
|
||||
#ifndef LABELED_CHECKBOX_H
|
||||
#define LABELED_CHECKBOX_H
|
||||
|
||||
#include "ksane_option_widget.h"
|
||||
|
||||
// Qt includes
|
||||
#include <QCheckBox>
|
||||
#include <QGridLayout>
|
||||
|
||||
namespace KSaneIface
|
||||
{
|
||||
|
||||
/**
|
||||
*@author Kåre Särs
|
||||
*/
|
||||
|
||||
/**
|
||||
* A wrapper for a checkbox
|
||||
*/
|
||||
class LabeledCheckbox : public KSaneOptionWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* Create the checkbox.
|
||||
*
|
||||
* \param parent parent widget
|
||||
* \param text is the text describing the checkbox.
|
||||
*/
|
||||
LabeledCheckbox(QWidget *parent, const QString& text);
|
||||
~LabeledCheckbox();
|
||||
void setChecked(bool);
|
||||
bool isChecked();
|
||||
|
||||
Q_SIGNALS:
|
||||
void toggled(bool);
|
||||
|
||||
private:
|
||||
|
||||
QCheckBox *chbx;
|
||||
};
|
||||
|
||||
} // NameSpace KSaneIface
|
||||
|
||||
#endif // LABELED_CHECKBOX_H
|
101
libksane/libksane/widgets/labeled_combo.cpp
Normal file
101
libksane/libksane/widgets/labeled_combo.cpp
Normal file
|
@ -0,0 +1,101 @@
|
|||
/* ============================================================
|
||||
*
|
||||
* This file is part of the KDE project
|
||||
*
|
||||
* Date : 2007-09-13
|
||||
* Description : Sane interface for KDE
|
||||
*
|
||||
* Copyright (C) 2007-2011 by Kare Sars <kare.sars@iki .fi>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) version 3, or any
|
||||
* later version accepted by the membership of KDE e.V. (or its
|
||||
* successor approved by the membership of KDE e.V.), which shall
|
||||
* act as a proxy defined in Section 6 of version 3 of the license.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* ============================================================ */
|
||||
#include "labeled_combo.h"
|
||||
#include "labeled_combo.moc"
|
||||
|
||||
// Qt includes
|
||||
#include <QLabel>
|
||||
|
||||
// KDE includes
|
||||
#include <KComboBox>
|
||||
#include <KDebug>
|
||||
|
||||
namespace KSaneIface
|
||||
{
|
||||
|
||||
LabeledCombo::LabeledCombo(QWidget *parent, const QString& ltext, const QStringList& list)
|
||||
: KSaneOptionWidget(parent, ltext)
|
||||
{
|
||||
m_combo = new KComboBox(this);
|
||||
m_combo->addItems(list);
|
||||
|
||||
m_label->setBuddy(m_combo);
|
||||
|
||||
connect(m_combo, SIGNAL(activated(int)), this, SIGNAL(activated(int)));
|
||||
|
||||
m_layout->addWidget(m_combo, 0, 1);
|
||||
m_layout->addWidget(new QWidget(this), 0, 2);
|
||||
m_layout->setColumnStretch(1, 0);
|
||||
m_layout->setColumnStretch(2, 50);
|
||||
setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Fixed);
|
||||
}
|
||||
|
||||
void LabeledCombo::addItems(const QStringList &list)
|
||||
{
|
||||
m_combo->addItems(list);
|
||||
|
||||
QString tmp;
|
||||
for (int i=0; i<m_combo->count(); i++) {
|
||||
tmp = m_combo->itemText(i);
|
||||
m_combo->setItemData(i, tmp, Qt::ToolTipRole);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void LabeledCombo::setCurrentText(const QString &t)
|
||||
{
|
||||
int i;
|
||||
for (i=0; i<m_combo->count(); i++) {
|
||||
if (m_combo->itemText(i) == t) {
|
||||
m_combo->setCurrentIndex(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
QString LabeledCombo::currentText()
|
||||
{
|
||||
return m_combo->currentText();
|
||||
}
|
||||
|
||||
|
||||
bool LabeledCombo::setIcon(const QIcon &icon, const QString& str)
|
||||
{
|
||||
for (int i=0; i < m_combo->count(); i++) {
|
||||
if (m_combo->itemText(i) == str) {
|
||||
m_combo->setItemIcon(i, icon);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void LabeledCombo::setCurrentIndex(int i)
|
||||
{
|
||||
m_combo->setCurrentIndex(i);
|
||||
}
|
||||
|
||||
} // NameSpace KSaneIface
|
100
libksane/libksane/widgets/labeled_combo.h
Normal file
100
libksane/libksane/widgets/labeled_combo.h
Normal file
|
@ -0,0 +1,100 @@
|
|||
/* ============================================================
|
||||
*
|
||||
* This file is part of the KDE project
|
||||
*
|
||||
* Description : Sane interface for KDE
|
||||
*
|
||||
* Copyright (C) 2007-2011 by Kare Sars <kare.sars@iki .fi>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) version 3, or any
|
||||
* later version accepted by the membership of KDE e.V. (or its
|
||||
* successor approved by the membership of KDE e.V.), which shall
|
||||
* act as a proxy defined in Section 6 of version 3 of the license.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* ============================================================ */
|
||||
|
||||
#ifndef LABELED_COMBO_H
|
||||
#define LABELED_COMBO_H
|
||||
|
||||
#include "ksane_option_widget.h"
|
||||
|
||||
// KDE includes
|
||||
#include <KComboBox>
|
||||
|
||||
namespace KSaneIface
|
||||
{
|
||||
|
||||
/**
|
||||
* A label and a combobox.
|
||||
*/
|
||||
class LabeledCombo : public KSaneOptionWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
/**
|
||||
* create a label and combobox combination.
|
||||
* \param parent parent widget
|
||||
* \param label is the lext for the label
|
||||
* \param list a stringlist with values the list should contain.
|
||||
*/
|
||||
LabeledCombo(QWidget *parent, const QString& label, const QStringList& list);
|
||||
|
||||
|
||||
public Q_SLOTS:
|
||||
|
||||
/**
|
||||
* Add string entries to the combobox
|
||||
*/
|
||||
void addItems(const QStringList &list);
|
||||
|
||||
/**
|
||||
* Remove all string entries
|
||||
*/
|
||||
void clear() { m_combo->clear(); }
|
||||
|
||||
/**
|
||||
* If the given string can be found in the comobox, activate that entry.
|
||||
* If not, the entry is not changed.
|
||||
*/
|
||||
void setCurrentText(const QString &);
|
||||
|
||||
/**
|
||||
* This function is used to read the current string of the combobox
|
||||
*/
|
||||
QString currentText();
|
||||
|
||||
/**
|
||||
* set the current item of the combobox.
|
||||
*/
|
||||
void setCurrentIndex(int);
|
||||
|
||||
/**
|
||||
* add an icon for a string in the combobox
|
||||
* @param icon the icon to set.
|
||||
* @param str the string for which the pixmap should be set.
|
||||
*/
|
||||
bool setIcon(const QIcon& icon, const QString& str);
|
||||
|
||||
Q_SIGNALS:
|
||||
|
||||
void activated(int);
|
||||
|
||||
private:
|
||||
KComboBox *m_combo;
|
||||
};
|
||||
|
||||
} // NameSpace KSaneIface
|
||||
|
||||
#endif // LABELED_COMBO_H
|
81
libksane/libksane/widgets/labeled_entry.cpp
Normal file
81
libksane/libksane/widgets/labeled_entry.cpp
Normal file
|
@ -0,0 +1,81 @@
|
|||
/* ============================================================
|
||||
*
|
||||
* This file is part of the KDE project
|
||||
*
|
||||
* Date : 2007-09-13
|
||||
* Description : Sane interface for KDE
|
||||
*
|
||||
* Copyright (C) 2007-2011 by Kare Sars <kare.sars@iki .fi>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) version 3, or any
|
||||
* later version accepted by the membership of KDE e.V. (or its
|
||||
* successor approved by the membership of KDE e.V.), which shall
|
||||
* act as a proxy defined in Section 6 of version 3 of the license.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* ============================================================ */
|
||||
|
||||
// Local includes
|
||||
#include "labeled_entry.h"
|
||||
#include "labeled_entry.moc"
|
||||
|
||||
// Qt includes
|
||||
#include <QHBoxLayout>
|
||||
#include <QLabel>
|
||||
#include <KLineEdit>
|
||||
#include <KLocale>
|
||||
#include <QPushButton>
|
||||
|
||||
namespace KSaneIface
|
||||
{
|
||||
|
||||
LabeledEntry::LabeledEntry(QWidget *parent, const QString& ltext)
|
||||
: KSaneOptionWidget(parent, ltext)
|
||||
{
|
||||
m_entry = new KLineEdit(this);
|
||||
m_reset = new QPushButton(this);
|
||||
m_reset->setText(i18nc("Label for button to reset text in a KLineEdit", "Reset"));
|
||||
m_set = new QPushButton(this);
|
||||
m_set->setText(i18nc("Label for button to write text in a KLineEdit to sane", "Set"));
|
||||
|
||||
m_layout->addWidget(m_entry, 1, 0, 1, 2);
|
||||
m_layout->addWidget(m_reset, 1, 2);
|
||||
m_layout->addWidget(m_set, 1, 3);
|
||||
m_layout->setColumnStretch(1, 50);
|
||||
|
||||
connect(m_reset, SIGNAL(clicked()), this, SLOT(resetClicked()));
|
||||
connect(m_set, SIGNAL(clicked()), this, SLOT(setClicked()));
|
||||
}
|
||||
|
||||
LabeledEntry::~LabeledEntry()
|
||||
{
|
||||
}
|
||||
|
||||
void LabeledEntry::setText(const QString& text)
|
||||
{
|
||||
m_eText = text;
|
||||
m_entry->setText(text);
|
||||
}
|
||||
|
||||
void LabeledEntry::resetClicked()
|
||||
{
|
||||
m_entry->setText(m_eText);
|
||||
}
|
||||
|
||||
void LabeledEntry::setClicked()
|
||||
{
|
||||
m_eText = m_entry->text();
|
||||
emit entryEdited(m_eText);
|
||||
}
|
||||
|
||||
} // NameSpace KSaneIface
|
81
libksane/libksane/widgets/labeled_entry.h
Normal file
81
libksane/libksane/widgets/labeled_entry.h
Normal file
|
@ -0,0 +1,81 @@
|
|||
/* ============================================================
|
||||
*
|
||||
* This file is part of the KDE project
|
||||
*
|
||||
* Date : 2007-09-13
|
||||
* Description : Sane interface for KDE
|
||||
*
|
||||
* Copyright (C) 2007-2011 by Kare Sars <kare.sars@iki .fi>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) version 3, or any
|
||||
* later version accepted by the membership of KDE e.V. (or its
|
||||
* successor approved by the membership of KDE e.V.), which shall
|
||||
* act as a proxy defined in Section 6 of version 3 of the license.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* ============================================================ */
|
||||
|
||||
#ifndef LABELED_ENTRY_H
|
||||
#define LABELED_ENTRY_H
|
||||
|
||||
#include "ksane_option_widget.h"
|
||||
|
||||
/**
|
||||
*@author Kåre Särs
|
||||
*/
|
||||
|
||||
class QPushButton;
|
||||
class KLineEdit;
|
||||
|
||||
namespace KSaneIface
|
||||
{
|
||||
|
||||
/**
|
||||
* A text entry field with a set and reset button
|
||||
*/
|
||||
class LabeledEntry : public KSaneOptionWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* Create the entry.
|
||||
*
|
||||
* \param parent parent widget
|
||||
* \param text is the text describing the entry.
|
||||
*/
|
||||
LabeledEntry(QWidget *parent, const QString& text);
|
||||
~LabeledEntry();
|
||||
void setText(const QString& text);
|
||||
|
||||
private Q_SLOTS:
|
||||
|
||||
void setClicked();
|
||||
void resetClicked();
|
||||
|
||||
Q_SIGNALS:
|
||||
|
||||
void entryEdited(const QString& text);
|
||||
|
||||
private:
|
||||
|
||||
KLineEdit *m_entry;
|
||||
QPushButton *m_set;
|
||||
QPushButton *m_reset;
|
||||
QString m_eText;
|
||||
};
|
||||
|
||||
} // NameSpace KSaneIface
|
||||
|
||||
#endif // LABELED_ENTRY_H
|
176
libksane/libksane/widgets/labeled_fslider.cpp
Normal file
176
libksane/libksane/widgets/labeled_fslider.cpp
Normal file
|
@ -0,0 +1,176 @@
|
|||
/* ============================================================
|
||||
*
|
||||
* This file is part of the KDE project
|
||||
*
|
||||
* Date : 2007-09-13
|
||||
* Description : Sane interface for KDE
|
||||
*
|
||||
* Copyright (C) 2007-2011 by Kare Sars <kare.sars@iki .fi>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) version 3, or any
|
||||
* later version accepted by the membership of KDE e.V. (or its
|
||||
* successor approved by the membership of KDE e.V.), which shall
|
||||
* act as a proxy defined in Section 6 of version 3 of the license.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* ============================================================ */
|
||||
|
||||
// Local includes
|
||||
#include "labeled_fslider.h"
|
||||
#include "labeled_fslider.moc"
|
||||
|
||||
#define FLOAT_MULTIP 32768.0
|
||||
#define TO_FLOAT(v) ((float)v / FLOAT_MULTIP)
|
||||
#define TO_FIX(v) ((int)(v * FLOAT_MULTIP))
|
||||
|
||||
namespace KSaneIface
|
||||
{
|
||||
|
||||
LabeledFSlider::LabeledFSlider(QWidget *parent, const QString& ltext,
|
||||
float min, float max, float step)
|
||||
: KSaneOptionWidget(parent, ltext)
|
||||
{
|
||||
int imin = TO_FIX(min);
|
||||
int imax = TO_FIX(max);
|
||||
m_istep = TO_FIX(step);
|
||||
m_fstep = step;
|
||||
if (m_istep == 0) {
|
||||
m_istep = 1;
|
||||
m_fstep = TO_FLOAT(m_istep);
|
||||
}
|
||||
|
||||
//std::cout << "min=" << min << ", max=" << max << ", m_fstep="<<m_fstep<<std::endl;
|
||||
//std::cout << "imin=" << imin << ", imax=" << imax << ", m_istep="<<m_istep<<std::endl;
|
||||
m_slider = new QSlider(this);
|
||||
m_slider->setOrientation(Qt::Horizontal);
|
||||
m_slider->setMinimum(imin);
|
||||
m_slider->setMaximum(imax);
|
||||
m_slider->setSingleStep(m_istep);
|
||||
m_slider->setValue(imin);
|
||||
|
||||
m_spinb = new QDoubleSpinBox(this);
|
||||
m_spinb->setMinimum(min);
|
||||
m_spinb->setMaximum(max);
|
||||
m_spinb->setSingleStep(m_fstep);
|
||||
int decimals=0;
|
||||
float tmp_step = m_fstep;
|
||||
while (tmp_step < 1) {
|
||||
tmp_step *= 10;
|
||||
decimals++;
|
||||
if (decimals > 5) break;
|
||||
}
|
||||
m_spinb->setDecimals(decimals);
|
||||
m_spinb->setValue(max);
|
||||
//m_spinb->setMinimumWidth(m_spinb->sizeHint().width()+35);
|
||||
m_spinb->setMinimumWidth(m_spinb->sizeHint().width());
|
||||
m_spinb->setAlignment(Qt::AlignRight);
|
||||
m_spinb->setValue(min);
|
||||
|
||||
m_label->setBuddy(m_spinb);
|
||||
|
||||
connect(m_spinb, SIGNAL(valueChanged(double)), this, SLOT(syncValues(double)));
|
||||
connect(m_slider, SIGNAL(valueChanged(int)), this, SLOT(syncValues(int)));
|
||||
connect(m_slider, SIGNAL(sliderReleased()), this, SLOT(fixValue()));
|
||||
|
||||
m_layout->addWidget(m_slider, 0,2);
|
||||
m_layout->addWidget(m_spinb, 0, 1);
|
||||
m_layout->setColumnStretch(1, 0);
|
||||
m_layout->setColumnStretch(2, 50);
|
||||
m_layout->activate();
|
||||
}
|
||||
|
||||
LabeledFSlider::~LabeledFSlider()
|
||||
{
|
||||
}
|
||||
|
||||
void LabeledFSlider::setSuffix(const QString &text)
|
||||
{
|
||||
m_spinb->setSuffix(text);
|
||||
}
|
||||
|
||||
void LabeledFSlider::setRange(float min, float max)
|
||||
{
|
||||
//kDebug() << "min,max(" << m_spinb->minimum() << " - " << m_spinb->maximum();
|
||||
//kDebug() << ") -> (" << min << " - " << max << ")" << std::endl;
|
||||
int imin=TO_FIX(min);
|
||||
int imax=TO_FIX(max);
|
||||
m_slider->setRange(imin, imax);
|
||||
//std::cout << "fixedmin=" << imin << " fixedmax=" << imax << std::endl;
|
||||
|
||||
m_spinb->setRange(min, max);
|
||||
}
|
||||
|
||||
void LabeledFSlider::setStep(float step)
|
||||
{
|
||||
m_istep = TO_FIX(step);
|
||||
m_fstep = step;
|
||||
if (m_istep == 0) {
|
||||
m_istep = 1;
|
||||
m_fstep = TO_FLOAT(m_istep);
|
||||
}
|
||||
m_slider->setSingleStep(m_istep);
|
||||
m_spinb->setSingleStep(m_fstep);
|
||||
|
||||
int decimals=0;
|
||||
float tmp_step = m_fstep;
|
||||
while (tmp_step < 1) {
|
||||
tmp_step *= 10;
|
||||
decimals++;
|
||||
if (decimals > 5) break;
|
||||
}
|
||||
m_spinb->setDecimals(decimals);
|
||||
}
|
||||
|
||||
void LabeledFSlider::setValue(float value)
|
||||
{
|
||||
int ivalue = TO_FIX(value);
|
||||
|
||||
if (((value - m_spinb->value()) > m_fstep) || ((m_spinb->value() - value) > m_fstep)) {
|
||||
m_spinb->setValue(value);
|
||||
}
|
||||
else if (ivalue != m_slider->value()) m_slider->setValue(ivalue);
|
||||
}
|
||||
|
||||
void LabeledFSlider::syncValues(int ivalue)
|
||||
{
|
||||
double value = TO_FLOAT(ivalue);
|
||||
if (((value - m_spinb->value()) > m_fstep) || ((m_spinb->value() - value) > m_fstep)) {
|
||||
m_spinb->setValue(value);
|
||||
}
|
||||
else if (ivalue != m_slider->value())m_slider->setValue(ivalue);
|
||||
else emit valueChanged(value);
|
||||
}
|
||||
|
||||
void LabeledFSlider::syncValues(double value)
|
||||
{
|
||||
int ivalue = TO_FIX(value);
|
||||
if (((value - m_spinb->value()) > m_fstep) || ((m_spinb->value() - value) > m_fstep)) {
|
||||
m_spinb->setValue(value);
|
||||
}
|
||||
else if (ivalue != m_slider->value())m_slider->setValue(ivalue);
|
||||
else emit valueChanged((float)value);
|
||||
}
|
||||
|
||||
void LabeledFSlider::fixValue()
|
||||
{
|
||||
//ensure that the value step is followed also for the m_slider
|
||||
int rest = (m_slider->value() - m_slider->minimum())%m_istep;
|
||||
|
||||
if (rest != 0) {
|
||||
if (rest > (m_istep/2)) m_slider->setValue(m_slider->value()+(m_istep-rest));
|
||||
else m_slider->setValue(m_slider->value()-rest);
|
||||
m_spinb->setValue(TO_FLOAT(m_slider->value()));
|
||||
}
|
||||
}
|
||||
|
||||
} // NameSpace KSaneIface
|
110
libksane/libksane/widgets/labeled_fslider.h
Normal file
110
libksane/libksane/widgets/labeled_fslider.h
Normal file
|
@ -0,0 +1,110 @@
|
|||
/* ============================================================
|
||||
*
|
||||
* This file is part of the KDE project
|
||||
*
|
||||
* Date : 2007-09-13
|
||||
* Description : Sane interface for KDE
|
||||
*
|
||||
* Copyright (C) 2007-2011 by Kare Sars <kare.sars@iki .fi>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) version 3, or any
|
||||
* later version accepted by the membership of KDE e.V. (or its
|
||||
* successor approved by the membership of KDE e.V.), which shall
|
||||
* act as a proxy defined in Section 6 of version 3 of the license.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* ============================================================ */
|
||||
|
||||
#ifndef LABELED_FSLIDER_H
|
||||
#define LABELED_FSLIDER_H
|
||||
|
||||
#include "ksane_option_widget.h"
|
||||
|
||||
// Qt includes
|
||||
#include <QSlider>
|
||||
#include <QDoubleSpinBox>
|
||||
|
||||
/**
|
||||
*@author Kåre Särs
|
||||
*/
|
||||
|
||||
namespace KSaneIface
|
||||
{
|
||||
|
||||
/**
|
||||
* A combination of a label a slider and a spinbox.
|
||||
* The slider is connected to the spinbox so that they have the same value.
|
||||
*/
|
||||
class LabeledFSlider : public KSaneOptionWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* Create the slider.
|
||||
*
|
||||
* \param parent parent widget
|
||||
* \param text is the text describing the slider value. If the text
|
||||
* contains a '&', a buddy for the slider will be created.
|
||||
* \param min minimum slider value
|
||||
* \param max maximum slider value
|
||||
* \param quant is the step between values.
|
||||
*/
|
||||
LabeledFSlider(QWidget *parent, const QString& text,
|
||||
float min, float max, float st);
|
||||
~LabeledFSlider();
|
||||
|
||||
/**
|
||||
* \return the slider value.
|
||||
*/
|
||||
float value() const {return (float)m_spinb->value();}
|
||||
float step() const {return m_fstep;}
|
||||
|
||||
public Q_SLOTS:
|
||||
|
||||
/** Set the slider/spinbox value */
|
||||
void setValue(float);
|
||||
void setRange(float, float);
|
||||
void setStep(float);
|
||||
/** Set the unit */
|
||||
void setSuffix(const QString &text);
|
||||
|
||||
private Q_SLOTS:
|
||||
|
||||
/**
|
||||
* Sync the values and emit valueChanged()
|
||||
*/
|
||||
// FIXME this has to be changes later
|
||||
void syncValues(int);
|
||||
void syncValues(double);
|
||||
void fixValue();
|
||||
|
||||
Q_SIGNALS:
|
||||
|
||||
/**
|
||||
* Emit the slider value changes
|
||||
*/
|
||||
void valueChanged(float);
|
||||
|
||||
private:
|
||||
|
||||
QSlider *m_slider;
|
||||
QDoubleSpinBox *m_spinb;
|
||||
float m_fstep;
|
||||
int m_istep;
|
||||
};
|
||||
|
||||
} // NameSpace KSaneIface
|
||||
|
||||
#endif // LABELED_SFSLIDER_H
|
199
libksane/libksane/widgets/labeled_gamma.cpp
Normal file
199
libksane/libksane/widgets/labeled_gamma.cpp
Normal file
|
@ -0,0 +1,199 @@
|
|||
/* ============================================================
|
||||
*
|
||||
* This file is part of the KDE project
|
||||
*
|
||||
* Date : 2007-09-13
|
||||
* Description : Sane interface for KDE
|
||||
*
|
||||
* Copyright (C) 2007-2011 by Kare Sars <kare.sars@iki .fi>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) version 3, or any
|
||||
* later version accepted by the membership of KDE e.V. (or its
|
||||
* successor approved by the membership of KDE e.V.), which shall
|
||||
* act as a proxy defined in Section 6 of version 3 of the license.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* ============================================================ */
|
||||
|
||||
// Local includes
|
||||
#include "labeled_gamma.h"
|
||||
#include "labeled_gamma.moc"
|
||||
|
||||
// C++ includes
|
||||
#include <cmath>
|
||||
|
||||
// Qt includes
|
||||
#include <QGroupBox>
|
||||
|
||||
// KDE includes
|
||||
#include <klocale.h>
|
||||
|
||||
namespace KSaneIface
|
||||
{
|
||||
|
||||
LabeledGamma::LabeledGamma(QWidget *parent, const QString& text, int size)
|
||||
: KSaneOptionWidget(parent, text)
|
||||
{
|
||||
m_bri_slider = new LabeledSlider(this, i18n("Brightness"), -50, 50, 1);
|
||||
m_bri_slider->setValue(0);
|
||||
|
||||
m_con_slider = new LabeledSlider(this, i18n("Contrast"), -50, 50, 1);
|
||||
m_con_slider->setValue(0);
|
||||
|
||||
m_gam_slider = new LabeledSlider(this, i18n("Gamma"), 30, 300, 1);
|
||||
m_gam_slider->setValue(100);
|
||||
|
||||
// Calculate the size of the widgets in the sliders
|
||||
int labelMax = m_bri_slider->labelWidthHint();
|
||||
labelMax = qMax(labelMax, m_con_slider->labelWidthHint());
|
||||
labelMax = qMax(labelMax, m_gam_slider->labelWidthHint());
|
||||
// set the calculated widths
|
||||
m_bri_slider->setLabelWidth(labelMax);
|
||||
m_con_slider->setLabelWidth(labelMax);
|
||||
m_gam_slider->setLabelWidth(labelMax);
|
||||
|
||||
m_gam_tbl.resize(size);
|
||||
for (int i=0; i<m_gam_tbl.size(); i++) {
|
||||
m_gam_tbl[i] = i;
|
||||
}
|
||||
m_max_val = size-1; // assume a gamma table 0 -> max
|
||||
|
||||
m_gamma_disp = new GammaDisp(this, &m_gam_tbl);
|
||||
|
||||
QGroupBox *groupBox = new QGroupBox(text, this);
|
||||
QGridLayout *gr_lay = new QGridLayout(groupBox);
|
||||
|
||||
gr_lay->addWidget(m_bri_slider, 0, 0);
|
||||
gr_lay->addWidget(m_con_slider, 1, 0);
|
||||
gr_lay->addWidget(m_gam_slider, 2, 0);
|
||||
gr_lay->addWidget(m_gamma_disp, 0, 1, 3, 1);
|
||||
|
||||
m_label->hide();
|
||||
m_layout->addWidget(groupBox, 1, 0, 1,3);
|
||||
|
||||
connect(m_bri_slider, SIGNAL(valueChanged(int)), this, SLOT(calculateGT()));
|
||||
connect(m_con_slider, SIGNAL(valueChanged(int)), this, SLOT(calculateGT()));
|
||||
connect(m_gam_slider, SIGNAL(valueChanged(int)), this, SLOT(calculateGT()));
|
||||
}
|
||||
|
||||
LabeledGamma::~LabeledGamma()
|
||||
{
|
||||
}
|
||||
|
||||
void LabeledGamma::setColor(const QColor &color)
|
||||
{
|
||||
if (m_gamma_disp != 0) {
|
||||
m_gamma_disp->setColor(color);
|
||||
}
|
||||
}
|
||||
|
||||
void LabeledGamma::setValues(int bri, int con, int gam)
|
||||
{
|
||||
m_bri_slider->blockSignals(true);
|
||||
m_con_slider->blockSignals(true);
|
||||
m_gam_slider->blockSignals(true);
|
||||
|
||||
m_bri_slider->setValue(bri);
|
||||
m_con_slider->setValue(con);
|
||||
m_gam_slider->setValue(gam);
|
||||
|
||||
calculateGT();
|
||||
|
||||
m_bri_slider->blockSignals(false);
|
||||
m_con_slider->blockSignals(false);
|
||||
m_gam_slider->blockSignals(false);
|
||||
}
|
||||
|
||||
void LabeledGamma::setValues(const QString &values)
|
||||
{
|
||||
m_bri_slider->blockSignals(true);
|
||||
m_con_slider->blockSignals(true);
|
||||
m_gam_slider->blockSignals(true);
|
||||
|
||||
QStringList gammaValues;
|
||||
int bri;
|
||||
int con;
|
||||
int gam;
|
||||
bool ok = true;
|
||||
|
||||
gammaValues = values.split(':');
|
||||
bri = gammaValues.at(0).toInt(&ok);
|
||||
if (ok) con = gammaValues.at(1).toInt(&ok);
|
||||
if (ok) gam = gammaValues.at(2).toInt(&ok);
|
||||
|
||||
if (ok) {
|
||||
m_bri_slider->setValue(bri);
|
||||
m_con_slider->setValue(con);
|
||||
m_gam_slider->setValue(gam);
|
||||
calculateGT();
|
||||
}
|
||||
|
||||
m_bri_slider->blockSignals(false);
|
||||
m_con_slider->blockSignals(false);
|
||||
m_gam_slider->blockSignals(false);
|
||||
}
|
||||
|
||||
|
||||
bool LabeledGamma::getValues(int &bri, int &con, int &gam)
|
||||
{
|
||||
|
||||
bri = m_bri_slider->value();
|
||||
con = m_con_slider->value();
|
||||
gam = m_gam_slider->value();
|
||||
return true;
|
||||
}
|
||||
|
||||
void LabeledGamma::setSize(int size)
|
||||
{
|
||||
m_gam_tbl.resize(size);
|
||||
for (int i=0; i<m_gam_tbl.size(); i++) {
|
||||
m_gam_tbl[i] = i;
|
||||
}
|
||||
m_bri_slider->setValue(0);
|
||||
m_con_slider->setValue(0);
|
||||
m_gam_slider->setValue(0);
|
||||
}
|
||||
|
||||
|
||||
void LabeledGamma::calculateGT()
|
||||
{
|
||||
double gam = 100.0/m_gam_slider->value();
|
||||
double con = (200.0/(100.0 - m_con_slider->value()))-1;
|
||||
double half_max = m_max_val/2.0;
|
||||
double bri = (m_bri_slider->value()/half_max) * m_max_val;
|
||||
double x;
|
||||
|
||||
for (int i = 0; i<m_gam_tbl.size(); i++) {
|
||||
// apply gamma
|
||||
x = std::pow(i/m_max_val, gam) * m_max_val;
|
||||
|
||||
// apply contrast
|
||||
x = (con*(x-half_max)) + half_max;
|
||||
|
||||
// apply brightness + rounding
|
||||
x += bri + 0.5;
|
||||
|
||||
// ensure correct value
|
||||
if (x > m_max_val) x = m_max_val;
|
||||
if (x < 0) x = 0;
|
||||
|
||||
m_gam_tbl[i] = (int)x;
|
||||
}
|
||||
|
||||
m_gamma_disp->update();
|
||||
emit gammaChanged(m_bri_slider->value(), m_con_slider->value(), m_gam_slider->value());
|
||||
emit gammaTableChanged(m_gam_tbl);
|
||||
}
|
||||
|
||||
|
||||
} // NameSpace KSaneIface
|
93
libksane/libksane/widgets/labeled_gamma.h
Normal file
93
libksane/libksane/widgets/labeled_gamma.h
Normal file
|
@ -0,0 +1,93 @@
|
|||
/* ============================================================
|
||||
*
|
||||
* This file is part of the KDE project
|
||||
*
|
||||
* Date : 2007-09-13
|
||||
* Description : Sane interface for KDE
|
||||
*
|
||||
* Copyright (C) 2007-2011 by Kare Sars <kare.sars@iki .fi>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) version 3, or any
|
||||
* later version accepted by the membership of KDE e.V. (or its
|
||||
* successor approved by the membership of KDE e.V.), which shall
|
||||
* act as a proxy defined in Section 6 of version 3 of the license.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* ============================================================ */
|
||||
|
||||
#ifndef LABELED_GAMMA_H
|
||||
#define LABELED_GAMMA_H
|
||||
|
||||
// Local includes
|
||||
#include "labeled_slider.h"
|
||||
#include "gamma_disp.h"
|
||||
|
||||
/**
|
||||
*@author Kåre Särs
|
||||
*/
|
||||
|
||||
namespace KSaneIface
|
||||
{
|
||||
|
||||
/**
|
||||
* A wrapper for a checkbox
|
||||
*/
|
||||
class LabeledGamma : public KSaneOptionWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* Create the checkbox.
|
||||
*
|
||||
* \param parent parent widget
|
||||
* \param text is the text describing the checkbox.
|
||||
*/
|
||||
LabeledGamma(QWidget *parent, const QString& text, int elements);
|
||||
~LabeledGamma();
|
||||
|
||||
void setColor(const QColor &color);
|
||||
void setSize(int size);
|
||||
const QVector<int> &gammaTablePtr() { return m_gam_tbl; }
|
||||
int size() {return (int)(m_max_val+1);}
|
||||
|
||||
bool getValues(int &bri, int &con, int &gam);
|
||||
|
||||
public Q_SLOTS:
|
||||
void setValues(int bri, int con, int gam);
|
||||
void setValues(const QString &values);
|
||||
|
||||
private Q_SLOTS:
|
||||
void calculateGT();
|
||||
|
||||
Q_SIGNALS:
|
||||
|
||||
void gammaChanged(int bri, int con, int gam);
|
||||
void gammaTableChanged(const QVector<int> &gamma_tbl);
|
||||
|
||||
private:
|
||||
|
||||
LabeledSlider *m_bri_slider;
|
||||
LabeledSlider *m_con_slider;
|
||||
LabeledSlider *m_gam_slider;
|
||||
|
||||
QVector<int> m_gam_tbl;
|
||||
double m_max_val;
|
||||
|
||||
GammaDisp *m_gamma_disp;
|
||||
};
|
||||
|
||||
} // NameSpace KSaneIface
|
||||
|
||||
#endif // LABELED_GAMMA_H
|
141
libksane/libksane/widgets/labeled_slider.cpp
Normal file
141
libksane/libksane/widgets/labeled_slider.cpp
Normal file
|
@ -0,0 +1,141 @@
|
|||
/* ============================================================
|
||||
*
|
||||
* This file is part of the KDE project
|
||||
*
|
||||
* Date : 2007-09-13
|
||||
* Description : Sane interface for KDE
|
||||
*
|
||||
* Copyright (C) 2007-2011 by Kare Sars <kare.sars@iki .fi>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) version 3, or any
|
||||
* later version accepted by the membership of KDE e.V. (or its
|
||||
* successor approved by the membership of KDE e.V.), which shall
|
||||
* act as a proxy defined in Section 6 of version 3 of the license.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* ============================================================ */
|
||||
|
||||
// Local includes
|
||||
#include "labeled_slider.h"
|
||||
#include "labeled_slider.moc"
|
||||
|
||||
// KDE includes
|
||||
#include <KNumInput>
|
||||
|
||||
// Qt includes
|
||||
#include <QLabel>
|
||||
#include <QSlider>
|
||||
|
||||
namespace KSaneIface
|
||||
{
|
||||
|
||||
LabeledSlider::LabeledSlider(QWidget *parent, const QString& ltext,
|
||||
int min, int max, int ste)
|
||||
: KSaneOptionWidget(parent, ltext)
|
||||
{
|
||||
m_step = ste;
|
||||
if (m_step == 0) m_step = 1;
|
||||
|
||||
m_slider = new QSlider(this);
|
||||
m_slider->setOrientation(Qt::Horizontal);
|
||||
m_slider->setMinimum(min);
|
||||
m_slider->setMaximum(max);
|
||||
m_slider->setSingleStep(m_step);
|
||||
|
||||
m_spinb = new KIntSpinBox(this);
|
||||
m_spinb->setMinimum(min);
|
||||
m_spinb->setMaximum(max);
|
||||
m_slider->setSingleStep(m_step);
|
||||
m_spinb->setValue(max);
|
||||
//m_spinb->setMinimumWidth(m_spinb->sizeHint().width()+35);
|
||||
m_spinb->setAlignment(Qt::AlignRight);
|
||||
m_spinb->setValue(min);
|
||||
|
||||
m_spinb->setValue(min);
|
||||
m_label->setBuddy(m_spinb);
|
||||
|
||||
connect(m_spinb, SIGNAL(valueChanged(int)), this, SLOT(syncValues(int)));
|
||||
connect(m_slider, SIGNAL(valueChanged(int)), this, SLOT(syncValues(int)));
|
||||
connect(m_slider, SIGNAL(sliderReleased()), this, SLOT(fixValue()));
|
||||
|
||||
m_layout->addWidget(m_slider, 0, 2);
|
||||
m_layout->addWidget(m_spinb, 0, 1);
|
||||
m_layout->setColumnStretch(1, 0);
|
||||
m_layout->setColumnStretch(2, 50);
|
||||
|
||||
}
|
||||
|
||||
LabeledSlider::~LabeledSlider()
|
||||
{
|
||||
}
|
||||
|
||||
void LabeledSlider::setSuffix(const KLocalizedString &text)
|
||||
{
|
||||
m_spinb->setSuffix(text);
|
||||
}
|
||||
|
||||
void LabeledSlider::setValue(int value)
|
||||
{
|
||||
if (value != m_slider->value()) m_slider->setValue(value);
|
||||
else if (value != m_spinb->value()) m_spinb->setValue(value);
|
||||
}
|
||||
|
||||
void LabeledSlider::setRange(int min, int max)
|
||||
{
|
||||
//std::cout << "min=" << min << ", max=" << max << std::endl;
|
||||
m_slider->setRange(min, max);
|
||||
m_spinb->setRange(min, max);
|
||||
}
|
||||
|
||||
void LabeledSlider::setStep(int st)
|
||||
{
|
||||
m_step = st;
|
||||
if (m_step == 0) m_step = 1;
|
||||
m_slider->setSingleStep(m_step);
|
||||
m_spinb->setSingleStep(m_step);
|
||||
}
|
||||
|
||||
void LabeledSlider::syncValues(int value)
|
||||
{
|
||||
if (value != m_spinb->value()) m_spinb->setValue(value);
|
||||
else if (value != m_slider->value()) {
|
||||
//ensure that the value m_step is followed also for the m_slider
|
||||
if ((value - m_slider->minimum())%m_step != 0) {
|
||||
if (value > m_spinb->value()) {
|
||||
m_slider->setValue(m_slider->value()+(m_step-(value - m_spinb->value())));
|
||||
}
|
||||
else {
|
||||
m_slider->setValue(m_slider->value()-(m_step-(m_spinb->value() - value)));
|
||||
}
|
||||
// this function will be reentered with the signal fom the m_slider
|
||||
}
|
||||
else {
|
||||
m_slider->setValue(value);
|
||||
}
|
||||
}
|
||||
else emit valueChanged(value);
|
||||
}
|
||||
|
||||
void LabeledSlider::fixValue()
|
||||
{
|
||||
//ensure that the value m_step is followed also for the m_slider
|
||||
int rest = (m_slider->value() - m_slider->minimum())%m_step;
|
||||
|
||||
if (rest != 0) {
|
||||
if (rest > (m_step/2)) m_slider->setValue(m_slider->value()+(m_step-rest));
|
||||
else m_slider->setValue(m_slider->value()-rest);
|
||||
m_spinb->setValue(m_slider->value());
|
||||
}
|
||||
}
|
||||
|
||||
} // NameSpace KSaneIface
|
104
libksane/libksane/widgets/labeled_slider.h
Normal file
104
libksane/libksane/widgets/labeled_slider.h
Normal file
|
@ -0,0 +1,104 @@
|
|||
/* ============================================================
|
||||
*
|
||||
* This file is part of the KDE project
|
||||
*
|
||||
* Date : 2007-09-13
|
||||
* Description : Sane interface for KDE
|
||||
*
|
||||
* Copyright (C) 2007-2011 by Kare Sars <kare.sars@iki .fi>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) version 3, or any
|
||||
* later version accepted by the membership of KDE e.V. (or its
|
||||
* successor approved by the membership of KDE e.V.), which shall
|
||||
* act as a proxy defined in Section 6 of version 3 of the license.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* ============================================================ */
|
||||
|
||||
#ifndef LABELED_SLIDER_H
|
||||
#define LABELED_SLIDER_H
|
||||
|
||||
#include "ksane_option_widget.h"
|
||||
|
||||
// Qt includes
|
||||
#include <QSlider>
|
||||
|
||||
/**
|
||||
*@author Kåre Särs
|
||||
*/
|
||||
|
||||
class KIntSpinBox;
|
||||
class KLocalizedString;
|
||||
|
||||
namespace KSaneIface
|
||||
{
|
||||
|
||||
/**
|
||||
* A combination of a label a slider and a spinbox.
|
||||
* The slider is connected to the spinbox so that they have the same value.
|
||||
*/
|
||||
class LabeledSlider : public KSaneOptionWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* Create the slider.
|
||||
*
|
||||
* \param parent parent widget
|
||||
* \param text is the text describing the slider value. If the text
|
||||
* contains a '&', a buddy for the slider will be created.
|
||||
* \param min minimum slider value
|
||||
* \param max maximum slider value
|
||||
* \param quant is the step between values.
|
||||
*/
|
||||
LabeledSlider(QWidget *parent, const QString& text,
|
||||
int min, int max, int st);
|
||||
~LabeledSlider();
|
||||
|
||||
int value() const { return( m_slider->value()); }
|
||||
|
||||
public Q_SLOTS:
|
||||
|
||||
/** Set the slider value */
|
||||
void setValue(int);
|
||||
void setRange(int min, int max);
|
||||
void setStep(int);
|
||||
/** Set the unit */
|
||||
void setSuffix(const KLocalizedString &text);
|
||||
|
||||
private Q_SLOTS:
|
||||
|
||||
/** Sync the values and emit valueChanged() */
|
||||
void syncValues(int);
|
||||
/** Ensure step value is followed */
|
||||
void fixValue();
|
||||
|
||||
Q_SIGNALS:
|
||||
|
||||
/**
|
||||
* Emit the slider value changes
|
||||
*/
|
||||
void valueChanged(int);
|
||||
|
||||
private:
|
||||
|
||||
QSlider *m_slider;
|
||||
KIntSpinBox *m_spinb;
|
||||
int m_step;
|
||||
};
|
||||
|
||||
} // NameSpace KSaneIface
|
||||
|
||||
#endif // LABELED_SLIDER_H
|
3
skanlite/.directory
Normal file
3
skanlite/.directory
Normal file
|
@ -0,0 +1,3 @@
|
|||
[Dolphin]
|
||||
Timestamp=2015,1,1,1,18,3
|
||||
Version=3
|
21
skanlite/CMakeLists.txt
Normal file
21
skanlite/CMakeLists.txt
Normal file
|
@ -0,0 +1,21 @@
|
|||
cmake_minimum_required(VERSION 2.6)
|
||||
|
||||
project(skanlite)
|
||||
|
||||
|
||||
find_package(KDE4 REQUIRED)
|
||||
include(KDE4Defaults)
|
||||
include_directories (${KDE4_INCLUDES})
|
||||
|
||||
find_package(KSane REQUIRED)
|
||||
find_package(PNG REQUIRED)
|
||||
|
||||
set(SKANLITE_VERSION_MAJOR "1")
|
||||
set(SKANLITE_VERSION_MINOR "1")
|
||||
set(SKANLITE_VERSION_STRING "${SKANLITE_VERSION_MAJOR}.${SKANLITE_VERSION_MINOR}")
|
||||
|
||||
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/src/version.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/src/version.h)
|
||||
|
||||
|
||||
add_subdirectory(src)
|
||||
|
14
skanlite/src/CMakeLists.txt
Normal file
14
skanlite/src/CMakeLists.txt
Normal file
|
@ -0,0 +1,14 @@
|
|||
include_directories(${KSANE_INCLUDE_DIR})
|
||||
|
||||
set(skanlite_SRCS main.cpp skanlite.cpp ImageViewer.cpp KSaneImageSaver.cpp SaveLocation.cpp)
|
||||
|
||||
kde4_add_ui_files(skanlite_SRCS settings.ui SaveLocation.ui)
|
||||
|
||||
kde4_add_app_icon(skanlite_SRCS "${KDE4_INSTALL_DIR}/share/icons/oxygen/*/devices/scanner.png")
|
||||
|
||||
kde4_add_executable(skanlite ${skanlite_SRCS})
|
||||
|
||||
target_link_libraries(skanlite ${KDE4_KIO_LIBS} ${KSANE_LIBRARY} ${PNG_LIBRARY})
|
||||
|
||||
install(TARGETS skanlite ${INSTALL_TARGETS_DEFAULT_ARGS})
|
||||
install( PROGRAMS skanlite.desktop DESTINATION ${XDG_APPS_INSTALL_DIR} )
|
346
skanlite/src/COPYING
Normal file
346
skanlite/src/COPYING
Normal file
|
@ -0,0 +1,346 @@
|
|||
NOTE! The GPL below is copyrighted by the Free Software Foundation, but
|
||||
the instance of code that it refers to (the kde programs) are copyrighted
|
||||
by the authors who actually wrote it.
|
||||
|
||||
---------------------------------------------------------------------------
|
||||
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 2, June 1991
|
||||
|
||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
License is intended to guarantee your freedom to share and change free
|
||||
software--to make sure the software is free for all its users. This
|
||||
General Public License applies to most of the Free Software
|
||||
Foundation's software and to any other program whose authors commit to
|
||||
using it. (Some other Free Software Foundation software is covered by
|
||||
the GNU Library General Public License instead.) You can apply it to
|
||||
your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
this service if you wish), that you receive source code or can get it
|
||||
if you want it, that you can change the software or use pieces of it
|
||||
in new free programs; and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid
|
||||
anyone to deny you these rights or to ask you to surrender the rights.
|
||||
These restrictions translate to certain responsibilities for you if you
|
||||
distribute copies of the software, or if you modify it.
|
||||
|
||||
For example, if you distribute copies of such a program, whether
|
||||
gratis or for a fee, you must give the recipients all the rights that
|
||||
you have. You must make sure that they, too, receive or can get the
|
||||
source code. And you must show them these terms so they know their
|
||||
rights.
|
||||
|
||||
We protect your rights with two steps: (1) copyright the software, and
|
||||
(2) offer you this license which gives you legal permission to copy,
|
||||
distribute and/or modify the software.
|
||||
|
||||
Also, for each author's protection and ours, we want to make certain
|
||||
that everyone understands that there is no warranty for this free
|
||||
software. If the software is modified by someone else and passed on, we
|
||||
want its recipients to know that what they have is not the original, so
|
||||
that any problems introduced by others will not reflect on the original
|
||||
authors' reputations.
|
||||
|
||||
Finally, any free program is threatened constantly by software
|
||||
patents. We wish to avoid the danger that redistributors of a free
|
||||
program will individually obtain patent licenses, in effect making the
|
||||
program proprietary. To prevent this, we have made it clear that any
|
||||
patent must be licensed for everyone's free use or not licensed at all.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License applies to any program or other work which contains
|
||||
a notice placed by the copyright holder saying it may be distributed
|
||||
under the terms of this General Public License. The "Program", below,
|
||||
refers to any such program or work, and a "work based on the Program"
|
||||
means either the Program or any derivative work under copyright law:
|
||||
that is to say, a work containing the Program or a portion of it,
|
||||
either verbatim or with modifications and/or translated into another
|
||||
language. (Hereinafter, translation is included without limitation in
|
||||
the term "modification".) Each licensee is addressed as "you".
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running the Program is not restricted, and the output from the Program
|
||||
is covered only if its contents constitute a work based on the
|
||||
Program (independent of having been made by running the Program).
|
||||
Whether that is true depends on what the Program does.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Program's
|
||||
source code as you receive it, in any medium, provided that you
|
||||
conspicuously and appropriately publish on each copy an appropriate
|
||||
copyright notice and disclaimer of warranty; keep intact all the
|
||||
notices that refer to this License and to the absence of any warranty;
|
||||
and give any other recipients of the Program a copy of this License
|
||||
along with the Program.
|
||||
|
||||
You may charge a fee for the physical act of transferring a copy, and
|
||||
you may at your option offer warranty protection in exchange for a fee.
|
||||
|
||||
2. You may modify your copy or copies of the Program or any portion
|
||||
of it, thus forming a work based on the Program, and copy and
|
||||
distribute such modifications or work under the terms of Section 1
|
||||
above, provided that you also meet all of these conditions:
|
||||
|
||||
a) You must cause the modified files to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
|
||||
b) You must cause any work that you distribute or publish, that in
|
||||
whole or in part contains or is derived from the Program or any
|
||||
part thereof, to be licensed as a whole at no charge to all third
|
||||
parties under the terms of this License.
|
||||
|
||||
c) If the modified program normally reads commands interactively
|
||||
when run, you must cause it, when started running for such
|
||||
interactive use in the most ordinary way, to print or display an
|
||||
announcement including an appropriate copyright notice and a
|
||||
notice that there is no warranty (or else, saying that you provide
|
||||
a warranty) and that users may redistribute the program under
|
||||
these conditions, and telling the user how to view a copy of this
|
||||
License. (Exception: if the Program itself is interactive but
|
||||
does not normally print such an announcement, your work based on
|
||||
the Program is not required to print an announcement.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Program,
|
||||
and can be reasonably considered independent and separate works in
|
||||
themselves, then this License, and its terms, do not apply to those
|
||||
sections when you distribute them as separate works. But when you
|
||||
distribute the same sections as part of a whole which is a work based
|
||||
on the Program, the distribution of the whole must be on the terms of
|
||||
this License, whose permissions for other licensees extend to the
|
||||
entire whole, and thus to each and every part regardless of who wrote it.
|
||||
|
||||
Thus, it is not the intent of this section to claim rights or contest
|
||||
your rights to work written entirely by you; rather, the intent is to
|
||||
exercise the right to control the distribution of derivative or
|
||||
collective works based on the Program.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Program
|
||||
with the Program (or with a work based on the Program) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
3. You may copy and distribute the Program (or a work based on it,
|
||||
under Section 2) in object code or executable form under the terms of
|
||||
Sections 1 and 2 above provided that you also do one of the following:
|
||||
|
||||
a) Accompany it with the complete corresponding machine-readable
|
||||
source code, which must be distributed under the terms of Sections
|
||||
1 and 2 above on a medium customarily used for software interchange; or,
|
||||
|
||||
b) Accompany it with a written offer, valid for at least three
|
||||
years, to give any third party, for a charge no more than your
|
||||
cost of physically performing source distribution, a complete
|
||||
machine-readable copy of the corresponding source code, to be
|
||||
distributed under the terms of Sections 1 and 2 above on a medium
|
||||
customarily used for software interchange; or,
|
||||
|
||||
c) Accompany it with the information you received as to the offer
|
||||
to distribute corresponding source code. (This alternative is
|
||||
allowed only for noncommercial distribution and only if you
|
||||
received the program in object code or executable form with such
|
||||
an offer, in accord with Subsection b above.)
|
||||
|
||||
The source code for a work means the preferred form of the work for
|
||||
making modifications to it. For an executable work, complete source
|
||||
code means all the source code for all modules it contains, plus any
|
||||
associated interface definition files, plus the scripts used to
|
||||
control compilation and installation of the executable. However, as a
|
||||
special exception, the source code distributed need not include
|
||||
anything that is normally distributed (in either source or binary
|
||||
form) with the major components (compiler, kernel, and so on) of the
|
||||
operating system on which the executable runs, unless that component
|
||||
itself accompanies the executable.
|
||||
|
||||
If distribution of executable or object code is made by offering
|
||||
access to copy from a designated place, then offering equivalent
|
||||
access to copy the source code from the same place counts as
|
||||
distribution of the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
4. You may not copy, modify, sublicense, or distribute the Program
|
||||
except as expressly provided under this License. Any attempt
|
||||
otherwise to copy, modify, sublicense or distribute the Program is
|
||||
void, and will automatically terminate your rights under this License.
|
||||
However, parties who have received copies, or rights, from you under
|
||||
this License will not have their licenses terminated so long as such
|
||||
parties remain in full compliance.
|
||||
|
||||
5. You are not required to accept this License, since you have not
|
||||
signed it. However, nothing else grants you permission to modify or
|
||||
distribute the Program or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Program (or any work based on the
|
||||
Program), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Program or works based on it.
|
||||
|
||||
6. Each time you redistribute the Program (or any work based on the
|
||||
Program), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute or modify the Program subject to
|
||||
these terms and conditions. You may not impose any further
|
||||
restrictions on the recipients' exercise of the rights granted herein.
|
||||
You are not responsible for enforcing compliance by third parties to
|
||||
this License.
|
||||
|
||||
7. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues),
|
||||
conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot
|
||||
distribute so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you
|
||||
may not distribute the Program at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Program by
|
||||
all those who receive copies directly or indirectly through you, then
|
||||
the only way you could satisfy both it and this License would be to
|
||||
refrain entirely from distribution of the Program.
|
||||
|
||||
If any portion of this section is held invalid or unenforceable under
|
||||
any particular circumstance, the balance of the section is intended to
|
||||
apply and the section as a whole is intended to apply in other
|
||||
circumstances.
|
||||
|
||||
It is not the purpose of this section to induce you to infringe any
|
||||
patents or other property right claims or to contest validity of any
|
||||
such claims; this section has the sole purpose of protecting the
|
||||
integrity of the free software distribution system, which is
|
||||
implemented by public license practices. Many people have made
|
||||
generous contributions to the wide range of software distributed
|
||||
through that system in reliance on consistent application of that
|
||||
system; it is up to the author/donor to decide if he or she is willing
|
||||
to distribute software through any other system and a licensee cannot
|
||||
impose that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
8. If the distribution and/or use of the Program is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Program under this License
|
||||
may add an explicit geographical distribution limitation excluding
|
||||
those countries, so that distribution is permitted only in or among
|
||||
countries not thus excluded. In such case, this License incorporates
|
||||
the limitation as if written in the body of this License.
|
||||
|
||||
9. The Free Software Foundation may publish revised and/or new versions
|
||||
of the General Public License from time to time. Such new versions will
|
||||
be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Program
|
||||
specifies a version number of this License which applies to it and "any
|
||||
later version", you have the option of following the terms and conditions
|
||||
either of that version or of any later version published by the Free
|
||||
Software Foundation. If the Program does not specify a version number of
|
||||
this License, you may choose any version ever published by the Free Software
|
||||
Foundation.
|
||||
|
||||
10. If you wish to incorporate parts of the Program into other free
|
||||
programs whose distribution conditions are different, write to the author
|
||||
to ask for permission. For software which is copyrighted by the Free
|
||||
Software Foundation, write to the Free Software Foundation; we sometimes
|
||||
make exceptions for this. Our decision will be guided by the two goals
|
||||
of preserving the free status of all derivatives of our free software and
|
||||
of promoting the sharing and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
|
||||
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
||||
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
||||
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
|
||||
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
|
||||
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
|
||||
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
|
||||
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
|
||||
REPAIR OR CORRECTION.
|
||||
|
||||
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
|
||||
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
|
||||
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
|
||||
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
|
||||
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
|
||||
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
free software which everyone can redistribute and change under these terms.
|
||||
|
||||
To do so, attach the following notices to the program. It is safest
|
||||
to attach them to the start of each source file to most effectively
|
||||
convey the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) 19yy <name of author>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program is interactive, make it output a short notice like this
|
||||
when it starts in an interactive mode:
|
||||
|
||||
Gnomovision version 69, Copyright (C) 19yy name of author
|
||||
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
|
||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||
parts of the General Public License. Of course, the commands you use may
|
||||
be called something other than `show w' and `show c'; they could even be
|
||||
mouse-clicks or menu items--whatever suits your program.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or your
|
||||
school, if any, to sign a "copyright disclaimer" for the program, if
|
||||
necessary. Here is a sample; alter the names:
|
||||
|
||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
|
||||
`Gnomovision' (which makes passes at compilers) written by James Hacker.
|
||||
|
||||
<signature of Ty Coon>, 1 April 1989
|
||||
Ty Coon, President of Vice
|
||||
|
||||
This General Public License does not permit incorporating your program into
|
||||
proprietary programs. If your program is a subroutine library, you may
|
||||
consider it more useful to permit linking proprietary applications with the
|
||||
library. If this is what you want to do, use the GNU Library General
|
||||
Public License instead of this License.
|
138
skanlite/src/ImageViewer.cpp
Normal file
138
skanlite/src/ImageViewer.cpp
Normal file
|
@ -0,0 +1,138 @@
|
|||
/* ============================================================
|
||||
* Date : 2008-08-26
|
||||
* Description : Preview image viewer.
|
||||
*
|
||||
* Copyright (C) 2008-2012 by Kåre Särs <kare.sars@iki .fi>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of
|
||||
* the License or (at your option) version 3 or any later version
|
||||
* accepted by the membership of KDE e.V. (or its successor approved
|
||||
* by the membership of KDE e.V.), which shall act as a proxy
|
||||
* defined in Section 14 of version 3 of the license.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License.
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
*
|
||||
* ============================================================ */
|
||||
|
||||
#include "ImageViewer.h"
|
||||
#include "ImageViewer.moc"
|
||||
|
||||
#include <QGraphicsPixmapItem>
|
||||
#include <QGraphicsScene>
|
||||
#include <QScrollBar>
|
||||
#include <QAction>
|
||||
#include <KIcon>
|
||||
#include <KLocale>
|
||||
|
||||
#include <KDebug>
|
||||
|
||||
struct ImageViewer::Private
|
||||
{
|
||||
QGraphicsScene *scene;
|
||||
QImage *img;
|
||||
|
||||
QAction *zoomInAction;
|
||||
QAction *zoomOutAction;
|
||||
QAction *zoom100Action;
|
||||
QAction *zoom2FitAction;
|
||||
};
|
||||
|
||||
ImageViewer::ImageViewer(QWidget *parent) : QGraphicsView(parent), d(new Private)
|
||||
{
|
||||
//setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
|
||||
//setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
|
||||
setMouseTracking(true);
|
||||
|
||||
// Init the scene
|
||||
d->scene = new QGraphicsScene;
|
||||
setScene(d->scene);
|
||||
|
||||
// create context menu
|
||||
d->zoomInAction = new QAction(KIcon("zoom-in"), i18n("Zoom In"), this);
|
||||
connect(d->zoomInAction, SIGNAL(triggered()), this, SLOT(zoomIn()));
|
||||
|
||||
d->zoomOutAction = new QAction(KIcon("zoom-out"), i18n("Zoom Out"), this);
|
||||
connect(d->zoomOutAction, SIGNAL(triggered()), this, SLOT(zoomOut()));
|
||||
|
||||
d->zoom100Action = new QAction(KIcon("zoom-fit-best"), i18n("Zoom to Actual size"), this);
|
||||
connect(d->zoom100Action, SIGNAL(triggered()), this, SLOT(zoomActualSize()));
|
||||
|
||||
d->zoom2FitAction = new QAction(KIcon("document-preview"), i18n("Zoom to Fit"), this);
|
||||
connect(d->zoom2FitAction, SIGNAL(triggered()), this, SLOT(zoom2Fit()));
|
||||
|
||||
addAction(d->zoomInAction);
|
||||
addAction(d->zoomOutAction);
|
||||
addAction(d->zoom100Action);
|
||||
addAction(d->zoom2FitAction);
|
||||
setContextMenuPolicy(Qt::ActionsContextMenu);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
ImageViewer::~ImageViewer()
|
||||
{
|
||||
delete d;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
void ImageViewer::setQImage(QImage *img)
|
||||
{
|
||||
if (img == 0) return;
|
||||
|
||||
d->img = img;
|
||||
d->scene->setSceneRect(0, 0, img->width(), img->height());
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
void ImageViewer::drawBackground(QPainter *painter, const QRectF &rect)
|
||||
{
|
||||
painter->fillRect(rect, QColor(0x70, 0x70, 0x70));
|
||||
painter->drawImage(rect, *d->img, rect);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
void ImageViewer::zoomIn()
|
||||
{
|
||||
scale(1.5, 1.5);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
void ImageViewer::zoomOut()
|
||||
{
|
||||
scale(1.0 / 1.5, 1.0 / 1.5);
|
||||
}
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
void ImageViewer::zoomActualSize()
|
||||
{
|
||||
setMatrix(QMatrix());
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
void ImageViewer::zoom2Fit()
|
||||
{
|
||||
fitInView(d->img->rect(), Qt::KeepAspectRatio);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
void ImageViewer::wheelEvent(QWheelEvent *e)
|
||||
{
|
||||
if(e->modifiers() == Qt::ControlModifier) {
|
||||
if(e->delta() > 0) {
|
||||
zoomIn();
|
||||
} else {
|
||||
zoomOut();
|
||||
}
|
||||
} else {
|
||||
QGraphicsView::wheelEvent(e);
|
||||
}
|
||||
}
|
||||
|
58
skanlite/src/ImageViewer.h
Normal file
58
skanlite/src/ImageViewer.h
Normal file
|
@ -0,0 +1,58 @@
|
|||
/* ============================================================
|
||||
* Date : 2009-08-26
|
||||
* Description : Preview image viewer.
|
||||
*
|
||||
* Copyright (C) 2008-2012 by Kåre Särs <kare.sars@iki .fi>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of
|
||||
* the License or (at your option) version 3 or any later version
|
||||
* accepted by the membership of KDE e.V. (or its successor approved
|
||||
* by the membership of KDE e.V.), which shall act as a proxy
|
||||
* defined in Section 14 of version 3 of the license.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License.
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
*
|
||||
* ============================================================ */
|
||||
|
||||
#ifndef IMAGE_VIEWER_H
|
||||
#define IMAGE_VIEWER_H
|
||||
|
||||
#include <QGraphicsView>
|
||||
#include <QWheelEvent>
|
||||
|
||||
class ImageViewer : public QGraphicsView
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
ImageViewer(QWidget *parent = 0);
|
||||
~ImageViewer();
|
||||
|
||||
void setQImage(QImage *img);
|
||||
|
||||
public Q_SLOTS:
|
||||
void zoomIn();
|
||||
void zoomOut();
|
||||
void zoom2Fit();
|
||||
void zoomActualSize();
|
||||
|
||||
protected:
|
||||
void wheelEvent(QWheelEvent *e);
|
||||
void drawBackground(QPainter *painter, const QRectF &rect);
|
||||
|
||||
private:
|
||||
struct Private;
|
||||
Private * const d;
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
|
236
skanlite/src/KSaneImageSaver.cpp
Normal file
236
skanlite/src/KSaneImageSaver.cpp
Normal file
|
@ -0,0 +1,236 @@
|
|||
/* ============================================================
|
||||
* Date : 2010-07-02
|
||||
* Description : Image saver class for libksane image data.
|
||||
*
|
||||
* Copyright (C) 2010-2012 by Kåre Särs <kare.sars@iki .fi>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of
|
||||
* the License or (at your option) version 3 or any later version
|
||||
* accepted by the membership of KDE e.V. (or its successor approved
|
||||
* by the membership of KDE e.V.), which shall act as a proxy
|
||||
* defined in Section 14 of version 3 of the license.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License.
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
*
|
||||
* ============================================================ */
|
||||
|
||||
#include "KSaneImageSaver.h"
|
||||
|
||||
#include <png.h>
|
||||
|
||||
#include <KDebug>
|
||||
#include <QMutex>
|
||||
|
||||
|
||||
struct KSaneImageSaver::Private
|
||||
{
|
||||
enum ImageType {
|
||||
ImageTypePNG,
|
||||
ImageTypeTIFF
|
||||
};
|
||||
|
||||
bool m_savedOk;
|
||||
QMutex m_runMutex;
|
||||
KSaneImageSaver *q;
|
||||
|
||||
QString m_name;
|
||||
QByteArray m_data;
|
||||
int m_width;
|
||||
int m_height;
|
||||
int m_format;
|
||||
ImageType m_type;
|
||||
|
||||
bool savePng();
|
||||
bool saveTiff();
|
||||
};
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
KSaneImageSaver::KSaneImageSaver(QObject *parent) : QThread(parent), d(new Private)
|
||||
{
|
||||
d->q = this;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
KSaneImageSaver::~KSaneImageSaver()
|
||||
{
|
||||
delete d;
|
||||
}
|
||||
|
||||
bool KSaneImageSaver::savePng(const QString &name, const QByteArray &data, int width, int height, int format)
|
||||
{
|
||||
if (!d->m_runMutex.tryLock()) return false;
|
||||
|
||||
d->m_name = name;
|
||||
d->m_data = data;
|
||||
d->m_width = width;
|
||||
d->m_height = height;
|
||||
d->m_format = format;
|
||||
d->m_type = Private::ImageTypePNG;
|
||||
|
||||
start();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool KSaneImageSaver::savePngSync(const QString &name, const QByteArray &data, int width, int height, int format)
|
||||
{
|
||||
if (!savePng(name, data, width, height, format)) {
|
||||
kDebug() << "fail";
|
||||
return false;
|
||||
}
|
||||
wait();
|
||||
return d->m_savedOk;
|
||||
}
|
||||
|
||||
bool KSaneImageSaver::saveTiff(const QString &name, const QByteArray &data, int width, int height, int format)
|
||||
{
|
||||
if (!d->m_runMutex.tryLock()) return false;
|
||||
|
||||
d->m_name = name;
|
||||
d->m_data = data;
|
||||
d->m_width = width;
|
||||
d->m_height = height;
|
||||
d->m_format = format;
|
||||
d->m_type = Private::ImageTypeTIFF;
|
||||
|
||||
kDebug() << "saving Tiff images is not yet supported";
|
||||
d->m_runMutex.unlock();
|
||||
return false;
|
||||
}
|
||||
|
||||
bool KSaneImageSaver::saveTiffSync(const QString &name, const QByteArray &data, int width, int height, int format)
|
||||
{
|
||||
if (!saveTiff(name, data, width, height, format)) {
|
||||
return false;
|
||||
}
|
||||
wait();
|
||||
return d->m_savedOk;
|
||||
}
|
||||
|
||||
void KSaneImageSaver::run()
|
||||
{
|
||||
if (d->m_type == Private::ImageTypeTIFF) {
|
||||
d->m_savedOk = d->saveTiff();
|
||||
emit imageSaved(d->m_savedOk);
|
||||
}
|
||||
else {
|
||||
d->m_savedOk = d->savePng();
|
||||
emit imageSaved(d->m_savedOk);
|
||||
}
|
||||
d->m_runMutex.unlock();
|
||||
}
|
||||
|
||||
bool KSaneImageSaver::Private::saveTiff()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool KSaneImageSaver::Private::savePng()
|
||||
{
|
||||
FILE *file;
|
||||
png_structp png_ptr;
|
||||
png_infop info_ptr;
|
||||
png_color_8 sig_bit;
|
||||
png_bytep row_ptr;
|
||||
int bytesPerPixel;
|
||||
|
||||
// open the file
|
||||
file = fopen(qPrintable(m_name), "wb");
|
||||
if (!file) return false;
|
||||
|
||||
// create the png struct
|
||||
png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
|
||||
if (!png_ptr) {
|
||||
fclose(file);
|
||||
return false;
|
||||
}
|
||||
|
||||
// create the image information srtuct
|
||||
info_ptr = png_create_info_struct(png_ptr);
|
||||
if (!png_ptr) {
|
||||
fclose(file);
|
||||
png_destroy_write_struct(&png_ptr, (png_infopp)NULL);
|
||||
return false;
|
||||
}
|
||||
|
||||
// initialize IO
|
||||
png_init_io(png_ptr, file);
|
||||
|
||||
// set the image attributes
|
||||
switch ((KSaneIface::KSaneWidget::ImageFormat)m_format)
|
||||
{
|
||||
case KSaneIface::KSaneWidget::FormatGrayScale16:
|
||||
png_set_IHDR(png_ptr, info_ptr, m_width, m_height, 16, PNG_COLOR_TYPE_GRAY,
|
||||
PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);
|
||||
sig_bit.gray = 16;
|
||||
bytesPerPixel = 2;
|
||||
break;
|
||||
case KSaneIface::KSaneWidget::FormatRGB_16_C:
|
||||
png_set_IHDR(png_ptr, info_ptr, m_width, m_height, 16, PNG_COLOR_TYPE_RGB,
|
||||
PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);
|
||||
sig_bit.red = 16;
|
||||
sig_bit.green = 16;
|
||||
sig_bit.blue = 16;
|
||||
bytesPerPixel = 6;
|
||||
break;
|
||||
default:
|
||||
fclose(file);
|
||||
png_destroy_write_struct(&png_ptr, (png_infopp)NULL);
|
||||
return false;
|
||||
}
|
||||
|
||||
png_set_sBIT(png_ptr, info_ptr, &sig_bit);
|
||||
|
||||
/* Optionally write comments into the image */
|
||||
// text_ptr[0].key = "Title";
|
||||
// text_ptr[0].text = "Mona Lisa";
|
||||
// text_ptr[0].compression = PNG_TEXT_COMPRESSION_NONE;
|
||||
// text_ptr[1].key = "Author";
|
||||
// text_ptr[1].text = "Leonardo DaVinci";
|
||||
// text_ptr[1].compression = PNG_TEXT_COMPRESSION_NONE;
|
||||
// text_ptr[2].key = "Description";
|
||||
// text_ptr[2].text = "<long text>";
|
||||
// text_ptr[2].compression = PNG_TEXT_COMPRESSION_zTXt;
|
||||
// png_set_text(png_ptr, info_ptr, text_ptr, 2);
|
||||
|
||||
/* Write the file header information. */
|
||||
png_write_info(png_ptr, info_ptr);
|
||||
|
||||
//png_set_shift(png_ptr, &sig_bit);
|
||||
//png_set_packing(png_ptr);
|
||||
|
||||
png_set_compression_level(png_ptr, 9);
|
||||
|
||||
// This is not nice :( swap bytes in the 16 bit color....
|
||||
char tmp;
|
||||
// Make sure we have a buffer size that is divisible by 2
|
||||
int dataSize = m_data.size();
|
||||
if ((dataSize % 2) > 0) dataSize--;
|
||||
for (int i=0; i<dataSize; i+=2) {
|
||||
tmp = m_data[i];
|
||||
m_data[i] = m_data[i+1];
|
||||
m_data[i+1] = tmp;
|
||||
}
|
||||
|
||||
row_ptr = (png_bytep)m_data.data();
|
||||
|
||||
for (int i=0; i<m_height; i++) {
|
||||
png_write_rows(png_ptr, &row_ptr, 1);
|
||||
row_ptr += m_width * bytesPerPixel;
|
||||
}
|
||||
|
||||
png_write_end(png_ptr, info_ptr);
|
||||
png_destroy_write_struct(&png_ptr, (png_infopp) & info_ptr);
|
||||
png_destroy_info_struct(png_ptr, (png_infopp) & info_ptr);
|
||||
fclose(file);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Reference in a new issue