Initial revision

This commit is contained in:
Bart Hakvoort 2004-09-19 20:24:53 +00:00
commit 26d433260d
46 changed files with 12913 additions and 0 deletions

3
AUTHORS Normal file
View File

@ -0,0 +1,3 @@
Bart
email: gparted@users.sourceforge.net
IRC : irc.gnome.org #gparted

340
COPYING Normal file
View File

@ -0,0 +1,340 @@
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
59 Temple Place, Suite 330, Boston, MA 02111-1307 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 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.

71
ChangeLog Normal file
View File

@ -0,0 +1,71 @@
**changes**
- replaced some 'dunglish' terms with more decent english. (Thanks to Tino Meinen)
- cleaned up autoconf stuff a bit
- gparted now gets installed in the sbin/ instead of bin/ (1023181)
- maximum amount of primary partition isn't static anymore, it gets asked from the partition table.
- lots of internal code cleanups. this improved performance and stability.
- doubleclick now invokes infodialog
**fixes**
- sometimes creating new fat filesystems in very small spaces resulted in errors. fixed.
- use copies from buildfiles instead of symlinks to them. (Thanks to Kristof Vansant)
- when performing operations on just copied partitions, there was a chance the operation would be executed on another partition. fixed.
- fixed a rare bug that caused incorrect partitiontable display after an operation went wrong.
- some errormessages were not entirely threadsafe, fixed (hopefully :P )
--------------------------------------------------------------------------
GParted-0.0.4 04 Sep 2004 :
- fixed another bug with hotpluggable stuff (usbdevices etc...)
- fixed "random" chrasher while performing actions on a device with a mounted partition.
- better alignment of information in deviceinfo and partitioninfo. (there were some problems with certain fonts)
- changed checking for filesystemlimits in new partition dialog a bit.
- fixed small bug in new partition dialog which made it possible to add fat16 partition > 1023MB
- time left in progressbar shows now minutes and seconds
- implemented copy'n paste functionality
- fixed small bug with resizer
- internal code cleanups, gained some performance
- made the operationtitles a bit more informative
- fixed bug with converting non-existent (new) partitions
- implemented new operationslist
- lots of small stuff
-------------------------------------------------------
GParted-0.0.3 26 Aug 2004 :
- and as always, lots of small fixed/changes..
- fixed bug with resizing extended partition
- fixed bug which occasionally occurred when deleting filesystems with errors on them
- fixed small bug with deleting new logical partitions while a partition with a higher number is mounted
- added read-only support for partition flags (e.g. lba, boot, etc...)
- implemented conversion between filesystems. (no big deal, all data is destroyed in the process)
- compiling/running tested on 64bits arch, went perfectly :)
- fixed another small bug with re-reading devices (optionmenu wasn't updated)
- Early check for errors on filesystem. Disable appropiate actions and explain in Info
- When a device can't be read it isn't listed anymore.
------------------------------------------------------
GParted-0.0.2 18 Aug 2004 :
- new create dialog
- far more compliant with HIG
- unallocated space now visible in treeview
- fixed bug with re-reading devices (segfault)
- fixed bug with new extended (segfault)
- a couple of other small things, fixes and improvements
---------------------------------------------
GParted-0.0.1 12 Aug 2004 :
***FIRST RELEASE!
- Create (ext2, linux-swap, fat16, fat32)
- resize (ext2, ext3, linux-swap, fat16, fat32 )
- move (linux-swap, fat16, fat32)
- Full operationslist with undo
- much more little stuff
- basicly working, but not tested very well

182
INSTALL Normal file
View File

@ -0,0 +1,182 @@
Basic Installation
==================
These are generic installation instructions.
The `configure' shell script attempts to guess correct values for
various system-dependent variables used during compilation. It uses
those values to create a `Makefile' in each directory of the package.
It may also create one or more `.h' files containing system-dependent
definitions. Finally, it creates a shell script `config.status' that
you can run in the future to recreate the current configuration, a file
`config.cache' that saves the results of its tests to speed up
reconfiguring, and a file `config.log' containing compiler output
(useful mainly for debugging `configure').
If you need to do unusual things to compile the package, please try
to figure out how `configure' could check whether to do them, and mail
diffs or instructions to the address given in the `README' so they can
be considered for the next release. If at some point `config.cache'
contains results you don't want to keep, you may remove or edit it.
The file `configure.in' is used to create `configure' by a program
called `autoconf'. You only need `configure.in' if you want to change
it or regenerate `configure' using a newer version of `autoconf'.
The simplest way to compile this package is:
1. `cd' to the directory containing the package's source code and type
`./configure' to configure the package for your system. If you're
using `csh' on an old version of System V, you might need to type
`sh ./configure' instead to prevent `csh' from trying to execute
`configure' itself.
Running `configure' takes awhile. While running, it prints some
messages telling which features it is checking for.
2. Type `make' to compile the package.
3. Optionally, type `make check' to run any self-tests that come with
the package.
4. Type `make install' to install the programs and any data files and
documentation.
5. You can remove the program binaries and object files from the
source code directory by typing `make clean'. To also remove the
files that `configure' created (so you can compile the package for
a different kind of computer), type `make distclean'. There is
also a `make maintainer-clean' target, but that is intended mainly
for the package's developers. If you use it, you may have to get
all sorts of other programs in order to regenerate files that came
with the distribution.
Compilers and Options
=====================
Some systems require unusual options for compilation or linking that
the `configure' script does not know about. You can give `configure'
initial values for variables by setting them in the environment. Using
a Bourne-compatible shell, you can do that on the command line like
this:
CC=c89 CFLAGS=-O2 LIBS=-lposix ./configure
Or on systems that have the `env' program, you can do it like this:
env CPPFLAGS=-I/usr/local/include LDFLAGS=-s ./configure
Compiling For Multiple Architectures
====================================
You can compile the package for more than one kind of computer at the
same time, by placing the object files for each architecture in their
own directory. To do this, you must use a version of `make' that
supports the `VPATH' variable, such as GNU `make'. `cd' to the
directory where you want the object files and executables to go and run
the `configure' script. `configure' automatically checks for the
source code in the directory that `configure' is in and in `..'.
If you have to use a `make' that does not supports the `VPATH'
variable, you have to compile the package for one architecture at a time
in the source code directory. After you have installed the package for
one architecture, use `make distclean' before reconfiguring for another
architecture.
Installation Names
==================
By default, `make install' will install the package's files in
`/usr/local/bin', `/usr/local/man', etc. You can specify an
installation prefix other than `/usr/local' by giving `configure' the
option `--prefix=PATH'.
You can specify separate installation prefixes for
architecture-specific files and architecture-independent files. If you
give `configure' the option `--exec-prefix=PATH', the package will use
PATH as the prefix for installing programs and libraries.
Documentation and other data files will still use the regular prefix.
In addition, if you use an unusual directory layout you can give
options like `--bindir=PATH' to specify different values for particular
kinds of files. Run `configure --help' for a list of the directories
you can set and what kinds of files go in them.
If the package supports it, you can cause programs to be installed
with an extra prefix or suffix on their names by giving `configure' the
option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'.
Optional Features
=================
Some packages pay attention to `--enable-FEATURE' options to
`configure', where FEATURE indicates an optional part of the package.
They may also pay attention to `--with-PACKAGE' options, where PACKAGE
is something like `gnu-as' or `x' (for the X Window System). The
`README' should mention any `--enable-' and `--with-' options that the
package recognizes.
For packages that use the X Window System, `configure' can usually
find the X include and library files automatically, but if it doesn't,
you can use the `configure' options `--x-includes=DIR' and
`--x-libraries=DIR' to specify their locations.
Specifying the System Type
==========================
There may be some features `configure' can not figure out
automatically, but needs to determine by the type of host the package
will run on. Usually `configure' can figure that out, but if it prints
a message saying it can not guess the host type, give it the
`--host=TYPE' option. TYPE can either be a short name for the system
type, such as `sun4', or a canonical name with three fields:
CPU-COMPANY-SYSTEM
See the file `config.sub' for the possible values of each field. If
`config.sub' isn't included in this package, then this package doesn't
need to know the host type.
If you are building compiler tools for cross-compiling, you can also
use the `--target=TYPE' option to select the type of system they will
produce code for and the `--build=TYPE' option to select the type of
system on which you are compiling the package.
Sharing Defaults
================
If you want to set default values for `configure' scripts to share,
you can create a site shell script called `config.site' that gives
default values for variables like `CC', `cache_file', and `prefix'.
`configure' looks for `PREFIX/share/config.site' if it exists, then
`PREFIX/etc/config.site' if it exists. Or, you can set the
`CONFIG_SITE' environment variable to the location of the site script.
A warning: not all `configure' scripts look for a site script.
Operation Controls
==================
`configure' recognizes the following options to control how it
operates.
`--cache-file=FILE'
Use and save the results of the tests in FILE instead of
`./config.cache'. Set FILE to `/dev/null' to disable caching, for
debugging `configure'.
`--help'
Print a summary of the options to `configure', and exit.
`--quiet'
`--silent'
`-q'
Do not print messages saying which checks are being made. To
suppress all normal output, redirect it to `/dev/null' (any error
messages will still be shown).
`--srcdir=DIR'
Look for the package's source code in directory DIR. Usually
`configure' can determine that directory automatically.
`--version'
Print the version of Autoconf used to generate the `configure'
script, and exit.
`configure' also accepts some other, not widely useful, options.

1
Makefile.am Normal file
View File

@ -0,0 +1 @@
SUBDIRS = include src

9
README Normal file
View File

@ -0,0 +1,9 @@
GParted stands for Gnome Partition Editor and is a graphical frontend to libparted. Among other features it supports creating, resizing, moving and copying of partitions.
The first goal of GParted is to provide all libparted's features as outlined at http://www.gnu.org/software/parted/#features.
When this is done and GParted is stable enough for normal use, i will look into support for other filesystems such as ntfs .
GParted is written in C++ and uses gtkmm as Graphical Toolkit. The general approach is to keep the GUI as simple as possible. That's why i try to conform to the GNOME Human Interface Guidelines .
Visit http://gparted.sourceforge.net/ for more information

14
acconfig.h Normal file
View File

@ -0,0 +1,14 @@
#undef ENABLE_NLS
#undef HAVE_CATGETS
#undef HAVE_GETTEXT
#undef HAVE_LC_MESSAGES
#undef HAVE_STPCPY
#undef HAVE_LIBSM
#undef PACKAGE_LOCALE_DIR
#undef PACKAGE_DOC_DIR
#undef PACKAGE_DATA_DIR
#undef PACKAGE_PIXMAPS_DIR
#undef PACKAGE_HELP_DIR
#undef PACKAGE_MENU_DIR
#undef PACKAGE_SOURCE_DIR
#undef GETTEXT_PACKAGE

1
acinclude.m4 Normal file
View File

@ -0,0 +1 @@
AC_DEFUN([AM_GNU_GETTEXT_VERSION], [])

6324
aclocal.m4 vendored Normal file

File diff suppressed because it is too large Load Diff

127
autogen.sh Executable file
View File

@ -0,0 +1,127 @@
#!/bin/sh
# Run this to generate all the initial makefiles, etc.
srcdir=`dirname $0`
PKG_NAME="the package."
DIE=0
(autoconf --version) < /dev/null > /dev/null 2>&1 || {
echo
echo "**Error**: You must have \`autoconf' installed to."
echo "Download the appropriate package for your distribution,"
echo "or get the source tarball at ftp://ftp.gnu.org/pub/gnu/"
DIE=1
}
(grep "^AM_PROG_LIBTOOL" $srcdir/configure.in >/dev/null) && {
(libtool --version) < /dev/null > /dev/null 2>&1 || {
echo
echo "**Error**: You must have \`libtool' installed."
echo "Get ftp://ftp.gnu.org/pub/gnu/"
echo "(or a newer version if it is available)"
DIE=1
}
}
(automake --version) < /dev/null > /dev/null 2>&1 || {
echo
echo "**Error**: You must have \`automake' installed."
echo "Get ftp://ftp.gnu.org/pub/gnu/"
echo "(or a newer version if it is available)"
DIE=1
NO_AUTOMAKE=yes
}
# if no automake, don't bother testing for aclocal
test -n "$NO_AUTOMAKE" || (aclocal --version) < /dev/null > /dev/null 2>&1 || {
echo
echo "**Error**: Missing \`aclocal'. The version of \`automake'"
echo "installed doesn't appear recent enough."
echo "Get ftp://ftp.gnu.org/pub/gnu/"
echo "(or a newer version if it is available)"
DIE=1
}
if test "$DIE" -eq 1; then
exit 1
fi
if test -z "$*"; then
echo "**Warning**: I am going to run \`configure' with no arguments."
echo "If you wish to pass any to it, please specify them on the"
echo \`$0\'" command line."
echo
fi
case $CC in
xlc )
am_opt=--include-deps;;
esac
for coin in `find $srcdir -name configure.in -print`
do
dr=`dirname $coin`
if test -f $dr/NO-AUTO-GEN; then
echo skipping $dr -- flagged as no auto-gen
else
echo processing $dr
macrodirs=`sed -n -e 's,AM_ACLOCAL_INCLUDE(\(.*\)),\1,gp' < $coin`
( cd $dr
aclocalinclude="$ACLOCAL_FLAGS"
for k in $macrodirs; do
if test -d $k; then
aclocalinclude="$aclocalinclude -I $k"
##else
## echo "**Warning**: No such directory \`$k'. Ignored."
fi
done
if grep "^AM_GNU_GETTEXT" configure.in >/dev/null; then
if grep "sed.*POTFILES" configure.in >/dev/null; then
: do nothing -- we still have an old unmodified configure.in
else
echo "Creating $dr/aclocal.m4 ..."
test -r $dr/aclocal.m4 || touch $dr/aclocal.m4
echo "Running gettextize... Ignore non-fatal messages."
./setup-gettext
echo "Making $dr/aclocal.m4 writable ..."
test -r $dr/aclocal.m4 && chmod u+w $dr/aclocal.m4
fi
fi
if grep "^AM_GNOME_GETTEXT" configure.in >/dev/null; then
echo "Creating $dr/aclocal.m4 ..."
test -r $dr/aclocal.m4 || touch $dr/aclocal.m4
echo "Running gettextize... Ignore non-fatal messages."
./setup-gettext
echo "Making $dr/aclocal.m4 writable ..."
test -r $dr/aclocal.m4 && chmod u+w $dr/aclocal.m4
fi
if grep "^AM_PROG_LIBTOOL" configure.in >/dev/null; then
echo "Running libtoolize..."
libtoolize --force --copy
fi
test -d m4 && aclocalinclude="$aclocalinclude -I m4"
echo "Running aclocal $aclocalinclude ..."
aclocal $aclocalinclude
if grep "^AM_CONFIG_HEADER" configure.in >/dev/null; then
echo "Running autoheader..."
autoheader
fi
echo "Running automake --gnu $am_opt ..."
automake --add-missing --copy --gnu $am_opt
echo "Running autoconf ..."
autoconf
)
fi
done
#conf_flags="--enable-maintainer-mode --enable-compile-warnings" #--enable-iso-c
if test x$NOCONFIGURE = x; then
echo Running $srcdir/configure $conf_flags "$@" ...
$srcdir/configure $conf_flags "$@" \
&& echo Now type \`make\' to compile $PKG_NAME
else
echo Skipping configure process.
fi

92
configure.in Normal file
View File

@ -0,0 +1,92 @@
dnl Process this file with autoconf to produce a configure script.
dnl Created by Anjuta - will be overwritten
dnl If you don't want it to overwrite it,
dnl Please disable it in the Anjuta project configuration
AC_INIT(configure.in)
AM_INIT_AUTOMAKE(GParted, 0.1)
AM_CONFIG_HEADER(config.h)
AC_ISC_POSIX
CFLAGS=""
AC_SUBST(CFLAGS)
CXXFLAGS=""
AC_SUBST(CXXFLAGS)
AC_PROG_CC
AC_PROG_CXX
AM_PROG_CC_STDC
AC_HEADER_STDC
AM_PROG_LIBTOOL
PKG_CHECK_MODULES(GTKMM, gtkmm-2.4,,exit)
AC_CHECK_LIB(parted, ped_device_probe_all, [], AC_MSG_ERROR([*** libparted >= 1.6.13 not installed - please install first ***]), -luuid -ldl)
AC_SUBST(GTKMM_LIBS)
AC_SUBST(GTKMM_CFLAGS)
dnl Checks for programs.
dnl Checks for libraries.
dnl Checks for header files.
dnl Checks for typedefs, structures, and compiler characteristics.
dnl Checks for library functions.
dnl Checks for Additional stuffs.
dnl Set PACKAGE SOURCE DIR in config.h.
packagesrcdir=`cd $srcdir && pwd`
dnl Set PACKAGE PREFIX
if test "x${prefix}" = "xNONE"; then
packageprefix=${ac_default_prefix}
else
packageprefix=${prefix}
fi
dnl Set PACKAGE DATA & DOC DIR
packagedatadir=share
packagedocdir=doc/${PACKAGE}
dnl Set PACKAGE DIRS in config.h.
packagepixmapsdir=${packagedatadir}/pixmaps
packagehelpdir=${packagedatadir}/help
packagemenudir=${packagedatadir}
dnl Subst PACKAGE_DATA_DIR.
NO_PREFIX_PACKAGE_DATA_DIR="${packagedatadir}"
AC_SUBST(NO_PREFIX_PACKAGE_DATA_DIR)
PACKAGE_DATA_DIR="${packageprefix}/${packagedatadir}"
AC_SUBST(PACKAGE_DATA_DIR)
dnl Subst PACKAGE_DOC_DIR.
NO_PREFIX_PACKAGE_DOC_DIR="${packagedocdir}"
AC_SUBST(NO_PREFIX_PACKAGE_DOC_DIR)
PACKAGE_DOC_DIR="${packageprefix}/${packagedocdir}"
AC_SUBST(PACKAGE_DOC_DIR)
dnl Subst PACKAGE_PIXMAPS_DIR.
NO_PREFIX_PACKAGE_PIXMAPS_DIR="${packagepixmapsdir}"
AC_SUBST(NO_PREFIX_PACKAGE_PIXMAPS_DIR)
PACKAGE_PIXMAPS_DIR="${packageprefix}/${packagepixmapsdir}"
AC_SUBST(PACKAGE_PIXMAPS_DIR)
dnl Subst PACKAGE_HELP_DIR.
NO_PREFIX_PACKAGE_HELP_DIR="${packagehelpdir}"
AC_SUBST(NO_PREFIX_PACKAGE_HELP_DIR)
PACKAGE_HELP_DIR="${packageprefix}/${packagehelpdir}"
AC_SUBST(PACKAGE_HELP_DIR)
dnl Subst PACKAGE_MENU_DIR.
NO_PREFIX_PACKAGE_MENU_DIR="${packagemenudir}"
AC_SUBST(NO_PREFIX_PACKAGE_MENU_DIR)
PACKAGE_MENU_DIR="${packageprefix}/${packagemenudir}"
AC_SUBST(PACKAGE_MENU_DIR)
AC_DEFINE_UNQUOTED(PACKAGE_DATA_DIR, "${packageprefix}/${packagedatadir}")
AC_DEFINE_UNQUOTED(PACKAGE_DOC_DIR, "${packageprefix}/${packagedocdir}")
AC_DEFINE_UNQUOTED(PACKAGE_PIXMAPS_DIR, "${packageprefix}/${packagepixmapsdir}")
AC_DEFINE_UNQUOTED(PACKAGE_HELP_DIR, "${packageprefix}/${packagehelpdir}")
AC_DEFINE_UNQUOTED(PACKAGE_MENU_DIR, "${packageprefix}/${packagemenudir}")
AC_DEFINE_UNQUOTED(PACKAGE_SOURCE_DIR, "${packagesrcdir}")
AC_OUTPUT([
Makefile
include/Makefile
src/Makefile
])

2
include/.cvsignore Normal file
View File

@ -0,0 +1,2 @@
Makefile
Makefile.in

110
include/Device.h Normal file
View File

@ -0,0 +1,110 @@
/* Copyright (C) 2004 Bart
*
* 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 Library 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/******************************************************
This class.... is a mess ;-)
It's does some kind of wrapping around libparted, but it's not very clear and it looks like shit.
The one thing i have to say in favor of it is: IT JUST WORKS :)
When i've time i will look into it and try to sort things out a bit.
Maybe building a small decent wrapper or so...
********************************************************/
#ifndef DEVICE
#define DEVICE
#include <parted/parted.h>
#include "../include/Partition.h"
#include <gtkmm/messagedialog.h>
#include <gtkmm/checkbutton.h>
#include <gtkmm/frame.h>
#include <gtkmm/label.h>
#include <gtkmm/stock.h>
#include <fstream>
#include <sstream>
namespace GParted
{
class Device
{
public:
Device() ;
Device( const Glib::ustring & device_path);
~Device() ;
//this function creates a fresh list with al the partitions and free spaces
void Read_Disk_Layout() ;
bool Delete_Partition( const Partition & partition ) ;
bool Create_Partition_With_Filesystem( Partition & new_part, PedTimer *timer) ;
bool Move_Resize_Partition( const Partition & partition_original, const Partition & partition_new , PedTimer *timer) ;
bool Set_Partition_Filesystem( const Partition & new_partition, PedTimer * timer);
bool Copy_Partition( Device *source_device, const Partition & source_partition, PedTimer * timer ) ;
int Create_Empty_Partition( const Partition & new_partition, PedConstraint * constraint = NULL ) ;
bool Commit() ;
PedPartition * Get_c_partition( int part_num );
std::vector<Partition> Get_Partitions() ;
Sector Get_Length() ;
long Get_Heads() ;
long Get_Sectors() ;
long Get_Cylinders() ;
Glib::ustring Get_Model() ;
Glib::ustring Get_Path() ;
Glib::ustring Get_RealPath() ;
Glib::ustring Get_DiskType() ;
bool Get_any_busy() ;
int Get_Max_Amount_Of_Primary_Partitions() ;
private:
//make a try to get the amount of used sectors on a filesystem ( see comments in implementation )
Sector Get_Used_Sectors( PedPartition *c_partition, const Glib::ustring & sym_path );
Glib::ustring Get_Flags( PedPartition *c_partition ) ;
bool open_device_and_disk() ;
void close_device_and_disk() ;
bool Resize_Extended( const Partition & partition, PedTimer *timer) ;
std::vector<Partition> device_partitions;
Sector length;
long heads ;
long sectors ;
long cylinders ;
Glib::ustring model;
Glib::ustring path;
Glib::ustring realpath;
Glib::ustring disktype;
//private variables
PedDevice *device ;
PedDisk *disk ;
PedPartition *c_partition ;
std::vector <PedPartitionFlag> flags;
Glib::ustring temp, error ; //error may contain an errormessage for an specific partition ( see Get_Used_Sectors() )
std::ostringstream os;
Partition partition_temp ;
};
} //GParted
#endif //DEVICE

50
include/Dialog_About.h Normal file
View File

@ -0,0 +1,50 @@
/* Copyright (C) 2004 Bart
*
* 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 Library 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/*
of course i could've used Gnome::UI::About but that would add another dependacy to GParted
Besides, i always wanted to build my own creditsdialog :-P
*/
#ifndef DIALOG_ABOUT
#define DIALOG_ABOUT
#include <gtkmm/dialog.h>
#include <gtkmm/button.h>
#include <gtkmm/label.h>
#include <gtkmm/stock.h>
#include <gtkmm/notebook.h>
//i18n stuff ....
#include <libintl.h>
#define _(String) gettext(String)
class Dialog_About : public Gtk::Dialog
{
public:
Dialog_About() ;
private:
void Show_Credits() ;
Gtk::Label *label_temp ;
Gtk::Button button_credits;
};
#endif

View File

@ -0,0 +1,100 @@
/* Copyright (C) 2004 Bart
*
* 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 Library 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifndef DIALOG_BASE_PARTITION
#define DIALOG_BASE_PARTITION
#include "../include/Frame_Resizer_Extended.h"
#include "../include/Partition.h"
#include <gtkmm/dialog.h>
#include <gtkmm/stock.h>
#include <gtkmm/label.h>
#include <gtkmm/spinbutton.h>
#include <gtkmm/table.h>
#include <gtkmm/box.h>
#include <gtkmm/tooltips.h>
namespace GParted
{
class Dialog_Base_Partition : public Gtk::Dialog
{
public:
Dialog_Base_Partition( ) ;
~Dialog_Base_Partition() ;
void Set_Resizer( bool extended ) ;
Partition Get_New_Partition() ;
protected:
enum SPINBUTTON {
BEFORE = 0,
SIZE = 1,
AFTER = 2
};
enum CONFIRMBUTTON {
RESIZE_MOVE = 0,
NEW = 1,
PASTE = 2
};
void Set_Confirm_Button( CONFIRMBUTTON button_type ) ;
double MB_PER_PIXEL ;
long TOTAL_MB ;
Frame_Resizer_Base *frame_resizer_base;
Partition selected_partition ;
Sector START; //the first sector of the first relevant partition ( this is either current or current -1 ) needed in Get_Resized_Partition()
Sector total_length ; //total amount of sectors ( this can be up to 3 partitions...
Gtk::HBox hbox_main;
Gtk::Label label_minmax ;
Gtk::SpinButton spinbutton_before, spinbutton_size, spinbutton_after;
//used to enable/disable OKbutton...
int ORIG_BEFORE,ORIG_SIZE, ORIG_AFTER ;
//signal handlers
void on_signal_move( int, int );
void on_signal_resize( int, int, Frame_Resizer_Base::ArrowType );
void on_spinbutton_value_changed( SPINBUTTON ) ;
bool fixed_start, GRIP;
std::ostringstream os;
double before_value ;
int x_start, x_end ;
private:
void Check_Change() ;
Gtk::VBox vbox_resize_move;
Gtk::Label *label_temp;
Gtk::Table table_resize;
Gtk::HBox hbox_table, hbox_resizer, hbox_resize_move;
Gtk::Tooltips tooltips;
Gtk::Button button_resize_move ;
Gtk::Image *image_temp ;
};
} //GParted
#endif //DIALOG_BASE_PARTITION

View File

@ -0,0 +1,40 @@
/* Copyright (C) 2004 Bart
*
* 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 Library 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifndef DIALOG_PARTITION_COPY
#define DIALOG_PARTITION_COPY
#include "../include/Dialog_Base_Partition.h"
namespace GParted
{
class Dialog_Partition_Copy : public Dialog_Base_Partition
{
public:
Dialog_Partition_Copy() ;
void Set_Data( Partition & selected_partition, Partition & copied_partition );
private:
};
}//GParted
#endif //DIALOG_PARTITION_COPY

View File

@ -0,0 +1,77 @@
/* Copyright (C) 2004 Bart
*
* 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 Library 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifndef DIALOG_PARTITION_INFO
#define DIALOG_PARTITION_INFO
//what kind of info would one prefer to see here?
//my guess is, it's best to keep the amount of info minimal and wait for users requests
#include "../include/Partition.h"
#include <gtkmm/dialog.h>
#include <gtkmm/stock.h>
#include <gtkmm/label.h>
#include <gtkmm/frame.h>
#include <gtkmm/drawingarea.h>
#include <gtkmm/table.h>
#include <vector>
#include <fstream>
#define BORDER 8
namespace GParted
{
class Dialog_Partition_Info : public Gtk::Dialog
{
public:
Dialog_Partition_Info( const Partition & );
~Dialog_Partition_Info();
private:
void init_drawingarea() ;
void Display_Info();
void Find_Status() ;
//signalhandlers
void drawingarea_on_realize( );
bool drawingarea_on_expose( GdkEventExpose * );
Partition partition ;
Gtk::HBox *hbox ;
Gtk::DrawingArea drawingarea ;
Gtk::Frame *frame ;
Gtk::Label *label ;
Gtk::Image *image;
Gtk::Table *table;
Glib::RefPtr<Gdk::GC> gc;
Glib::RefPtr<Pango::Layout> pango_layout;
Gdk::Color color_partition, color_used, color_unused, color_text ;
int used,unused ;
std::ostringstream os, os_percent;
};
} //GParted
#endif //DIALOG_PARTITION_INFO

View File

@ -0,0 +1,56 @@
/* Copyright (C) 2004 Bart
*
* 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 Library 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifndef DIALOG_PARTITION_NEW
#define DIALOG_PARTITION_NEW
#include "../include/Dialog_Base_Partition.h"
#include <gtkmm/messagedialog.h>
#include <gtkmm/optionmenu.h>
namespace GParted
{
class Dialog_Partition_New : public Dialog_Base_Partition
{
public:
Dialog_Partition_New() ;
void Set_Data( const Partition & partition, bool any_extended, unsigned short new_count );
Partition Get_New_Partition() ;//overridden function
private:
void Build_Filesystems_Menu() ;
//bool Check_Restrictions() ;
Gtk::Table table_create;
Gtk::OptionMenu optionmenu_type, optionmenu_filesystem;
Gtk::Label label_type,label_filesystem,label_start,label_size;
Gtk::Menu menu_type, menu_filesystem;
std::vector <Glib::ustring> filesystems ;
//signal handlers
void optionmenu_changed( bool );
Gdk::Color color_temp;
unsigned short new_count ;
};
} //GParted
#endif //DIALOG_PARTITION_NEW

View File

@ -0,0 +1,40 @@
/* Copyright (C) 2004 Bart
*
* 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 Library 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifndef DIALOG_PARTITION_RESIZE_MOVE
#define DIALOG_PARTITION_RESIZE_MOVE
#include "../include/Dialog_Base_Partition.h"
namespace GParted
{
class Dialog_Partition_Resize_Move : public Dialog_Base_Partition
{
public:
Dialog_Partition_Resize_Move( ) ;
void Set_Data( const Partition & selected_partition, const std::vector <Partition> & partitions ) ;
private:
void Resize_Move_Normal( const std::vector <Partition> & partitions ) ;
void Resize_Move_Extended( const std::vector <Partition> & partitions ) ;
};
} //GParted
#endif //DIALOG_PARTITION_RESIZE_MOVE

55
include/Dialog_Progress.h Normal file
View File

@ -0,0 +1,55 @@
/* Copyright (C) 2004 Bart
*
* 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 Library 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifndef DIALOG_PARTITION_PROGRESS
#define DIALOG_PARTITION_PROGRESS
#include <gtkmm/dialog.h>
#include <gtkmm/progressbar.h>
#include <gtkmm/stock.h>
#include <gtkmm/label.h>
#include <sstream>
//i18n stuff ....
#include <libintl.h>
#define _(String) gettext(String)
class Dialog_Progress : public Gtk::Dialog
{
public:
Dialog_Progress( int, const Glib::ustring & );
~Dialog_Progress();
void Set_Next_Operation( );
void Set_Progress_Current_Operation();
Glib::ustring current_operation;
float fraction_current;
int time_left ;
private:
Gtk::Label label_all_operations, label_current, *label_temp;
Gtk::ProgressBar progressbar_all, progressbar_current ;
double fraction;
std::ostringstream os;
int count_operations, current_operation_number;
char c_buf[ 1024 ] ; //used by sprintf, which is needed for i18n
};
#endif //DIALOG_PARTITION_PROGRESS

View File

@ -0,0 +1,93 @@
/* Copyright (C) 2004 Bart
*
* 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 Library 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifndef FRAME_RESIZER_BASE
#define FRAME_RESIZER_BASE
#include <gtkmm/frame.h>
#include <gtkmm/drawingarea.h>
#include <gdkmm/cursor.h>
#define BORDER 8
class Frame_Resizer_Base : public Gtk::Frame, virtual public sigc::trackable
{
public:
enum ArrowType {
ARROW_LEFT = 0,
ARROW_RIGHT = 1
};
Frame_Resizer_Base( ) ;
~Frame_Resizer_Base() ;
void set_rgb_partition_color( const Gdk::Color & ) ;
void override_default_rgb_unused_color( const Gdk::Color & ) ;
void set_x_start( int ) ;
void set_x_end( int ) ;
void set_used( int );
void set_fixed_start( bool ) ;
void set_used_start( int used_start ) ;
int get_used();
int get_x_start() ;
int get_x_end() ;
virtual void Draw_Partition() ;
//public signal (emitted upon resize/move)
sigc::signal<void,int,int, ArrowType> signal_resize;
sigc::signal<void,int,int> signal_move;
protected:
int X_START, USED, UNUSED, X_END, X_START_MOVE, USED_START;
bool GRIP_LEFT, GRIP_RIGHT, GRIP_MOVE ;
//signal handlers
void drawingarea_on_realize( );
bool drawingarea_on_expose( GdkEventExpose * );
virtual bool drawingarea_on_mouse_motion( GdkEventMotion* ) ;
bool drawingarea_on_button_press_event( GdkEventButton* ) ;
bool drawingarea_on_button_release_event( GdkEventButton* ) ;
bool drawingarea_on_leave_notify( GdkEventCrossing* ) ;
void Draw_Resize_Grip( ArrowType ) ;
Gtk::DrawingArea drawingarea;
Glib::RefPtr<Gdk::GC> gc;
Gdk::Color color_used, color_unused, color_arrow, color_background,color_partition,color_arrow_rectangle;
std::vector <Gdk::Point> arrow_points;
Gdk::Cursor *cursor_resize, *cursor_normal, *cursor_move;
int temp_x, temp_y ;
bool fixed_start; //a fixed start disables moving the start and thereby the whole move functionality..
private:
void init() ;
};
#endif // FRAME_RESIZER_BASE

View File

@ -0,0 +1,49 @@
/* Copyright (C) 2004 Bart
*
* 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 Library 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifndef FRAME_RESIZER_EXTENDED
#define FRAME_RESIZER_EXTENDED
#include "../include/Frame_Resizer_Base.h"
class Frame_Resizer_Extended : public Frame_Resizer_Base
{
public:
Frame_Resizer_Extended( ) ;
private:
int UNUSED_BEFORE ;
//overridden signal handler
virtual bool drawingarea_on_mouse_motion( GdkEventMotion* ) ;
virtual void Draw_Partition() ;
};
#endif // FRAME_RESIZER_EXTENDED

1
include/Makefile.am Normal file
View File

@ -0,0 +1 @@
gparted_includedir = $(pkgincludedir)

76
include/Operation.h Normal file
View File

@ -0,0 +1,76 @@
/* Copyright (C) 2004 Bart
*
* 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 Library 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifndef OPERATION
#define OPERATION
#include "../include/Partition.h"
#include "../include/Device.h"
#include <gtkmm/messagedialog.h>
#include <glibmm/ustring.h>
//i18n stuff ....
#include <libintl.h>
#define _(String) gettext(String)
namespace GParted
{
enum OperationType {
DELETE = 0,
CREATE = 1,
RESIZE_MOVE = 2,
CONVERT = 3,
COPY = 4
};
class Operation
{
public:
Operation( Device *device, Device *source_device, const Partition &, const Partition &,OperationType );
Glib::ustring Get_String();
//this one can be a little confusing, it *DOES NOT* change any visual representation. It only applies the operation to the list with partitions.
//this new list can be used to change the visual representation. For real writing to disk, see Apply_To_Disk()
std::vector<Partition> Apply_Operation_To_Visual( std::vector<Partition> & partitions );
void Apply_To_Disk( PedTimer * );
//public variables
Device *device, *source_device; //source_device is only used in copy operations
Glib::ustring device_path, source_device_path ;
OperationType operationtype;
Partition partition_new; //the new situation ( can be an whole new partition or simply the old one with a new size or.... )
private:
std::vector<Partition> Apply_Delete_To_Visual( std::vector<Partition> & partitions );
std::vector<Partition> Apply_Create_To_Visual( std::vector<Partition> & partitions );
std::vector<Partition> Apply_Resize_Move_To_Visual( std::vector<Partition> & partitions );
std::vector<Partition> Apply_Resize_Move_Extended_To_Visual( std::vector<Partition> & partitions );
std::vector<Partition> Apply_Convert_To_Visual( std::vector<Partition> & partitions );
void Show_Error( const Glib::ustring & message ) ;
Partition partition_original; //the original situation
char c_buf[ 1024 ] ; //used by sprintf, which is needed for i18n
};
} //GParted
#endif //OPERATION

133
include/Partition.h Normal file
View File

@ -0,0 +1,133 @@
/* Copyright (C) 2004 Bart
*
* 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 Library 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/* READ THIS!!
* Partition isn't really a partition. It's more like a geometry, a continuous part of the disk. I use ut to represent partitions as well as unallocated spaces
*/
#ifndef PARTITION
#define PARTITION
#include <glibmm/ustring.h>
#include <gdkmm/colormap.h>
#include <sstream>
#include <iostream>
//i18n stuff ....
#include <libintl.h>
#define _(String) gettext(String)
#define MEGABYTE 2048 //try it: 2048 * 512 / 1024 /1024 == 1 :P
namespace GParted
{
typedef long long Sector;//one day this won't be sufficient, oh how i dream of that day... :-P
inline long Sector_To_MB( Sector sectors )
{
return (long) ( (double) sectors * 512/1024/1024 +0.5) ;
}
inline long Round( double double_value )
{
return (long) ( double_value + 0.5) ;
}
inline Sector Abs( Sector sectors )
{
return sectors < 0 ? sectors - 2*sectors : sectors ;
}
enum PartitionType {
PRIMARY = 0,
LOGICAL = 1,
EXTENDED = 2,
UNALLOCATED = 3
};
/*
enum FileSystem {
ext2 = 0,
ext3 = 1,
linux_swap = 2,
reiserfs = 3,
hfs = 4,
jfs = 5,
hp_ufs = 6,
sun_ufs = 7,
xfs = 8,
fat16 = 9,
fat32 = 10,
ntfs = 11
};
*/
class Partition
{
public:
Partition();
~Partition() ;
//simple Set-functions. only for convenience, since most members are public
void Set( const Glib::ustring & partition,
const int partition_number,
const PartitionType type,
const Glib::ustring & filesystem,
const Sector & sector_start,
const Sector & sector_end,
const Sector & sectors_used,
const bool inside_extended,
const bool busy ) ;
void Set_Unallocated( Sector sector_start, Sector sector_end, bool inside_extended );
//get color associated with filesystem
Glib::ustring Get_Color( const Glib::ustring & filesystem );
//update partition number (used when a logical partition is deleted)
void Update_Number( int new_number );
long Get_Length_MB( );
long Get_Used_MB( );
long Get_Unused_MB( );
//some public members
Glib::ustring partition;//the symbolic path (e.g. /dev/hda1 )
int partition_number;
PartitionType type;// UNALLOCATED, PRIMARY, LOGICAL, etc...
Glib::ustring filesystem;// ext2, ext3, ntfs, etc....
Sector sector_start;
Sector sector_end;
Sector sectors_used;
Sector sectors_unused;
Gdk::Color color;
Glib::ustring color_string;
bool inside_extended;//this one is stupid ;-) i use it to check wether unallocated space resides inside extended partition or not.
bool busy;
Glib::ustring error;
Glib::ustring flags;
private:
};
}//GParted
#endif //PARTITION

88
include/TreeView_Detail.h Normal file
View File

@ -0,0 +1,88 @@
/* Copyright (C) 2004 Bart
*
* 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 Library 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifndef TREEVIEW_DETAIL
#define TREEVIEW_DETAIL
#include "../include/Partition.h"
#include <gtkmm/treeview.h>
#include <gtkmm/treestore.h>
#include <gtkmm/entry.h>
#include <gtkmm/stock.h>
#include <gdkmm/pixbuf.h>
#include <vector>
#include <sstream>
namespace GParted
{
class TreeView_Detail : public Gtk::TreeView
{
public:
TreeView_Detail( );
void Load_Partitions( std::vector<Partition> & partitions ) ;
void Set_Selected( const Partition & partition );
//signals for interclass communication
sigc::signal<void,GdkEventButton *,const Partition &> signal_mouse_click;
private:
void Create_Row( const Gtk::TreeRow &, Partition &);
//overridden signal
virtual bool on_button_press_event(GdkEventButton *);
Gtk::TreeRow row,childrow;
Gtk::TreeIter iter,iter_child;
Glib::RefPtr<Gtk::TreeStore> treestore_detail;
Glib::RefPtr<Gtk::TreeSelection> treeselection;
//columns for this treeview
struct treeview_detail_Columns : public Gtk::TreeModelColumnRecord
{
Gtk::TreeModelColumn<Glib::ustring> partition;
Gtk::TreeModelColumn<Glib::ustring> type;
Gtk::TreeModelColumn<Glib::ustring> size;
Gtk::TreeModelColumn<Glib::ustring> used;
Gtk::TreeModelColumn<Glib::ustring> unused;
Gtk::TreeModelColumn<Glib::ustring> color;
Gtk::TreeModelColumn<Glib::ustring> text_color;
Gtk::TreeModelColumn< Glib::RefPtr<Gdk::Pixbuf> > status_icon;
Gtk::TreeModelColumn<Glib::ustring> flags;
Gtk::TreeModelColumn< Partition > partition_struct; //hidden column ( see also on_button_press_event )
treeview_detail_Columns() {
add( partition ); add( type ); add( size ); add( used ); add( unused ); add( color ); add( text_color ); add( status_icon ); add( flags ); add(partition_struct);
}
};
treeview_detail_Columns treeview_detail_columns;
Partition partition_temp ; //used in Set_Selected to make the check a bit more readable
std::ostringstream os;//for int to string conversions
};
} //GParted
#endif //TREEVIEW_DETAIL

101
include/VBox_VisualDisk.h Normal file
View File

@ -0,0 +1,101 @@
/* Copyright (C) 2004 Bart
*
* 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 Library 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifndef VBOX_VISUALDISK
#define VBOX_VISUALDISK
#include "../include/Partition.h"
#include "../include/Device.h"
#include <gtkmm/box.h>
#include <gtkmm/frame.h>
#include <gtkmm/eventbox.h>
#include <gtkmm/tooltips.h>
#include <gtkmm/label.h>
#include <gtkmm/entry.h>
#include <gtkmm/checkbutton.h>
#include <gtkmm/drawingarea.h>
#include <sstream>
#define BORDER 8
namespace GParted
{
class VBox_VisualDisk : public Gtk::VBox
{
//struct which contains visual information about the partitions. This prevents recalculation of everything after an expose en therefore saves performance..
struct Visual_Partition
{
//2 attributes used for selection ( see Set_Selected() an drawingarea_on_expose() for more info )
Sector sector_start;
int index;
int length; //pixels
int used; //pixels
int height; //pixels
int text_y; //pixels
Gdk::Color color_fs;
Gtk::DrawingArea *drawingarea;
Glib::RefPtr<Gdk::GC> gc;
Glib::RefPtr<Pango::Layout> pango_layout;
};
public:
VBox_VisualDisk( const std::vector<Partition> & partitions, const Sector device_length );
~VBox_VisualDisk();
void Set_Selected( const Partition & );
//public signal for interclass communication
sigc::signal<void,GdkEventButton *, const Partition &> signal_mouse_click;
private:
void Build_Visual_Disk( int ) ; //i still dream of some fully resizeable visualdisk....
void Build_Legend( ) ;
void Add_Legend_Item( const Glib::ustring & filesystem, const Gdk::Color & color );
//signal handlers
void drawingarea_on_realize( Visual_Partition * );
bool drawingarea_on_expose( GdkEventExpose *, Visual_Partition* );
bool on_drawingarea_button_press( GdkEventButton *, const Partition & );
std::vector<Partition> partitions;
Sector device_length;
Gtk::Frame *frame_disk_legend ;
Gtk::HBox hbox_disk_main, *hbox_disk, *hbox_extended, hbox_legend_main, *hbox_legend;
Gtk::CheckButton checkbutton_filesystem;
Gtk::Tooltips tooltips;
Visual_Partition *visual_partition;
std::vector <Visual_Partition *> visual_partitions;
Gtk::EventBox * eventbox_extended;
Gdk::Color color_used, color_unused, color_text;
std::ostringstream os;//for int to string conversions
int temp,selected_partition;
Gtk::Entry *entry_temp;
Gtk::Label *label_temp;
};
} //GParted
#endif //VBOX_VISUALDISK

183
include/Win_GParted.h Normal file
View File

@ -0,0 +1,183 @@
/* Copyright (C) 2004 Bart
*
* 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 Library 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifndef WIN_GPARTED
#define WIN_GPARTED
#include "../include/Device.h"
#include "../include/VBox_VisualDisk.h"
#include "../include/Partition.h"
#include "../include/TreeView_Detail.h"
#include "../include/Dialog_Partition_Info.h"
#include "../include/Dialog_Partition_New.h"
#include "../include/Operation.h"
#include "../include/Dialog_Progress.h"
#include "../include/Dialog_Partition_Resize_Move.h"
#include "../include/Dialog_About.h"
#include "../include/Dialog_Partition_Copy.h"
#include <sigc++/class_slot.h>
#include <gtkmm/main.h>
#include <gtkmm/paned.h>
#include <gtkmm/toolbar.h>
#include <gtkmm/separatortoolitem.h>
#include <gtkmm/menubar.h>
#include <gtkmm/expander.h>
#include <gtkmm/statusbar.h>
#include <gtkmm/radiobutton.h>
#include <gtkmm/liststore.h>
#include <gtkmm/scrolledwindow.h>
#include <fstream>
namespace GParted
{
class Win_GParted : public Gtk::Window
{
public:
Win_GParted( );
private:
void init_menubar() ;
void init_toolbar() ;
void init_popupmenu() ;
void init_convert_menu() ;
void init_device_info() ;
void init_operationslist() ;
void init_hpaned_main() ;
void Find_Devices() ;
//Fill txtview_device_info_buffer with some information about the selected device
void Fill_Label_Device_Info( );
//overridden signalhandler
virtual bool on_delete_event(GdkEventAny* ) ;
void Add_Operation( OperationType, const Partition & );
void Refresh_Visual( );
bool Quit_Check_Operations();
void Set_Valid_Operations() ; //determines which operations are allowed on selected_partition
void Set_Valid_Convert_Filesystems() ; //determines to which filesystems a partition can be converted
//convenience functions
void allow_new( bool b ) { menu_popup.items()[0].set_sensitive( b ); toolbar_main.get_nth_item(0) ->set_sensitive( b ); }
void allow_delete( bool b ) { menu_popup.items()[1].set_sensitive( b ); toolbar_main.get_nth_item(1) ->set_sensitive( b ); }
void allow_resize( bool b ) { menu_popup.items()[3].set_sensitive( b ); toolbar_main.get_nth_item(3) ->set_sensitive( b ); }
void allow_copy( bool b ) { menu_popup.items()[5].set_sensitive( b ); toolbar_main.get_nth_item(5) ->set_sensitive( b ); }
void allow_paste( bool b ) { menu_popup.items()[6].set_sensitive( b ); toolbar_main.get_nth_item(6) ->set_sensitive( b ); }
void allow_convert( bool b ) { menu_popup.items()[8].set_sensitive( b ); }
void allow_undo( bool b ) { toolbar_main.get_nth_item(8) ->set_sensitive( b ); }
void allow_apply( bool b ) { toolbar_main.get_nth_item(9) ->set_sensitive( b ); }
//signal handlers
void close_operationslist() ;
void clear_operationslist() ;
void optionmenu_devices_changed( );
void menu_gparted_refresh_devices();
void menu_gparted_quit();
void menu_help_contents();
void menu_help_about();
void mouse_click( GdkEventButton*, const Partition & );
void activate_resize();
void activate_copy();
void activate_paste();
void activate_new();
void activate_delete();
void activate_info();
void activate_convert( const Glib::ustring & new_fs );
void activate_undo();
void activate_apply();
void apply_operations_thread();
//private variables
unsigned int current_device, source_device; //source_device is used to store the device the copied_partition is from....
Partition selected_partition, copied_partition;
std::vector <Device * > devices;
std::vector <Operation> operations;
//gui stuff
Gtk::HPaned hpaned_main;
Gtk::VPaned vpaned_main;
Gtk::VBox vbox_main,vbox_info, *vbox;
Gtk::HBox hbox_toolbar,hbox_visual, hbox_operations, *hbox;
Gtk::Toolbar toolbar_main;
Gtk::MenuBar menubar_main;
Gtk::OptionMenu optionmenu_devices;
Gtk::Menu menu_devices,menu_popup, menu_convert, *menu ;
Gtk::ToolButton *toolbutton;
Gtk::Statusbar statusbar;
Gtk::Expander expander_device_info ;
Gtk::Image *image ;
Gtk::ScrolledWindow *scrollwindow;
Gtk::Label label_device_info1, label_device_info2, *label;
Gtk::Tooltips tooltips ;
Gtk::Button *button;
Gtk::Table *table ;
Gtk::MenuItem *menu_item;
Gtk::Entry *entry;
Gdk::Color color ;
VBox_VisualDisk *vbox_visual_disk;
TreeView_Detail treeview_detail;
//operations list
Gtk::TreeView treeview_operations;
Gtk::TreeRow treerow;
Glib::RefPtr<Gtk::ListStore> liststore_operations;
struct treeview_operations_Columns : public Gtk::TreeModelColumnRecord
{
Gtk::TreeModelColumn<int> operation_number;
Gtk::TreeModelColumn<Glib::ustring> operation_description;
Gtk::TreeModelColumn< Glib::RefPtr<Gdk::Pixbuf> > operation_icon;
treeview_operations_Columns() { add( operation_number ); add( operation_description );add(operation_icon);}
};
treeview_operations_Columns treeview_operations_columns;
//usefull variables which are used by many different functions...
sigc::connection s2,s3;//usefull for disconnecting and destroying a connection ( see optionmenu_devices_changed() and activate_apply() )
std::ostringstream os;//for int to string conversions
bool any_logic,any_extended;//used in some checks (e.g. see optionmenu_devices_changed()
unsigned short highest_logic_busy,primary_count, new_count;//primary_count checks for max. of 4 pimary partitions,
//new_count keeps track of the new created partitions,
//highest_logic_busy contains the number of the highest logical which is busy ( 0 if none is busy)
GParted::Device *temp_device;
std::vector <Glib::ustring> str_devices, filesystems;
char c_buf[ 1024 ] ; //used by sprintf, which is needed for i18n
//stuff for progress overview
Dialog_Progress *dialog_progress;
Glib::Thread *thread_operations;
Glib::Dispatcher dispatcher_next_operation;
bool apply;
};
} //GParted
#endif //WIN_GPARTED

6
src/.cvsignore Normal file
View File

@ -0,0 +1,6 @@
Makefile
Makefile.in
.deps
.libs
gparted
*.o

604
src/Device.cc Normal file
View File

@ -0,0 +1,604 @@
/* Copyright (C) 2004 Bart
*
* 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 Library 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include "../include/Device.h"
/*
* This is ridiculous!, if i use this one as a member function realpath starts complaining and won't compile :-S
*/
Glib::ustring get_sym_path( const Glib::ustring & real_path )
{
int major,minor,size;
char temp[4096], device_name[4096],short_path[4096] ;
FILE* proc_part_file = fopen ("/proc/partitions", "r");
if (!proc_part_file)
return real_path;
//skip first 2 useless rules of /proc/partitions
fgets (temp, 256, proc_part_file);fgets (temp, 256, proc_part_file);
while (fgets (temp, 4096, proc_part_file) && sscanf (temp, "%d %d %d %255s", &major, &minor, &size, device_name) == 4)
{
strcpy(short_path, "/dev/"); strcat( short_path, device_name );
realpath( short_path, device_name );
if ( real_path == device_name ) {
fclose (proc_part_file);
return (Glib::ustring(short_path));
}
}
//it's very unlikely, if not impossible, the program will ever reach this, but just in case.... ;-)
fclose (proc_part_file);
return real_path;
}
//AFAIK it's not possible to use a C++ memberfunction as a callback for a C libary function (if you know otherwise, PLEASE contact me
Glib::ustring error_message;
bool show_libparted_message = true ;
PedExceptionOption PedException_Handler (PedException* ex)
{
error_message = ex -> message ;
if ( show_libparted_message )
{
Gtk::Label *label_temp;
Gtk::HBox *hbox_filler;
Glib::ustring message = "<span weight=\"bold\" size=\"larger\">" + (Glib::ustring) _( "Libparted message" ) + "</span>\n\n" ;
message += (Glib::ustring) _( "This message directly comes from libparted and has little to do with GParted. However, the message might contain useful information, so you might decide to read it.") + "\n";
message += _( "If you don't want to see these messages any longer, it's safe to disable them.") ;
Gtk::MessageDialog dialog( message,true,Gtk::MESSAGE_WARNING , Gtk::BUTTONS_OK, true);
Gtk::Frame frame_libparted_message ;
frame_libparted_message .set_size_request( 400, -1 );
label_temp = manage( new Gtk::Label("<b>" + (Glib::ustring) _( "Libparted message") + ": </b>" ) ) ;
label_temp ->set_use_markup( true ) ;
frame_libparted_message .set_label_widget( *label_temp ) ;
frame_libparted_message .set_border_width( 5 ) ;
label_temp = manage( new Gtk::Label( ) ) ;
label_temp ->set_size_request( 55, -1 ) ; //used like a simple filler ( remember this html cursus :-P )
hbox_filler = manage( new Gtk::HBox() ) ;
hbox_filler ->pack_start ( *label_temp, Gtk::PACK_SHRINK ) ;
hbox_filler ->pack_start ( frame_libparted_message, Gtk::PACK_SHRINK ) ;
dialog .get_vbox() ->pack_start( *hbox_filler, Gtk::PACK_SHRINK ) ;
Gtk::Label label_libparted_message( "<i>" + error_message + "</i>" ) ;
label_libparted_message .set_selectable( true ) ;
label_libparted_message .set_use_markup( true ) ;
label_libparted_message .set_line_wrap( true ) ;
frame_libparted_message.add ( label_libparted_message ) ;
Gtk::CheckButton checkbutton_message( _( "Hide libparted messages for this session" ) ) ;
checkbutton_message .set_border_width( 5 ) ;
label_temp = manage( new Gtk::Label( ) ) ;
label_temp ->set_size_request( 55, -1 ) ;
hbox_filler = manage( new Gtk::HBox() ) ;
hbox_filler ->pack_start ( *label_temp, Gtk::PACK_SHRINK ) ;
hbox_filler ->pack_start ( checkbutton_message, Gtk::PACK_SHRINK ) ;
dialog .get_vbox() ->pack_start( *hbox_filler, Gtk::PACK_SHRINK ) ;
dialog .show_all_children() ;
dialog .run();
show_libparted_message = ! checkbutton_message .get_active() ;
}
return PED_EXCEPTION_UNHANDLED ;
}
namespace GParted
{
Device::Device()
{
}
Device::Device( const Glib::ustring & device_path )
{
ped_exception_set_handler( PedException_Handler ) ;
this ->realpath = device_path ; //this one is used by open_device_and_disk
this ->length = 0;//lazy check.. if something goes wrong while reading the device, length will stay zero and i will know it ( see Win_GParted::Find_Devices )
if ( ! open_device_and_disk() )
return ;
this ->model = device ->model ;
this ->path = get_sym_path( device ->path ) ;
this ->disktype = disk ->type ->name ;
this ->heads = device ->bios_geom.heads ;
this ->sectors = device ->bios_geom.sectors ;
this ->cylinders = device ->bios_geom.cylinders ;
this ->length = heads * sectors * cylinders ;
//get valid flags for this device
for ( PedPartitionFlag flag = ped_partition_flag_next ( (PedPartitionFlag) 0 ) ; flag ; flag = ped_partition_flag_next ( flag ) )
flags .push_back( flag ) ;
Read_Disk_Layout() ;
}
void Device::Read_Disk_Layout()
{
//clear partitions
this ->device_partitions .clear () ;
c_partition = ped_disk_next_partition ( disk, NULL) ;
while ( c_partition )
{
os << this ->path << c_partition ->num ;
switch( c_partition ->type )
{
//NORMAL (PRIMARY)
case 0 : if ( c_partition ->fs_type )
temp = c_partition ->fs_type ->name ;
else
{temp = "unknown" ; this ->error = (Glib::ustring) _( "Unable to detect filesystem! Possible reasons are:" ) + "\n-" + (Glib::ustring) _( "The filesystem is damaged" ) + "\n-" + (Glib::ustring) _( "The filesystem is unknown to libparted" ) + "\n-" + (Glib::ustring) _( "There is no filesystem available (unformatted)" ) ; }
partition_temp.Set( os.str(),c_partition ->num , GParted::PRIMARY, temp, c_partition ->geom .start, c_partition ->geom .end, Get_Used_Sectors( c_partition , os.str() ) , false, ped_partition_is_busy( c_partition ) );
partition_temp .flags = Get_Flags( c_partition ) ;
partition_temp .error = this ->error ;
device_partitions.push_back( partition_temp );
break;
//LOGICAL
case 1: if ( c_partition ->fs_type )
temp = c_partition ->fs_type ->name ;
else
{temp = "unknown" ; this ->error = (Glib::ustring) _( "Unable to detect filesystem! Possible reasons are:" ) + "\n-" + (Glib::ustring) _( "The filesystem is damaged" ) + "\n-" + (Glib::ustring) _( "The filesystem is unknown to libparted" ) + "\n-" + (Glib::ustring) _( "There is no filesystem available (unformatted)" ) ; }
partition_temp.Set( os.str(), c_partition ->num, GParted::LOGICAL, temp, c_partition ->geom .start, c_partition ->geom .end, Get_Used_Sectors( c_partition , os.str() ) , true, ped_partition_is_busy( c_partition ) );
partition_temp .flags = Get_Flags( c_partition ) ;
partition_temp .error = this ->error ;
device_partitions.push_back( partition_temp );
break;
//EXTENDED
case 2: partition_temp.Set( os.str(), c_partition ->num, GParted::EXTENDED, "extended", c_partition ->geom .start, c_partition ->geom .end , -1, false, ped_partition_is_busy( c_partition ) );
partition_temp .flags = Get_Flags( c_partition ) ;
partition_temp .error = this ->error ;
device_partitions.push_back( partition_temp );
break;
//FREESPACE OUTSIDE EXTENDED
case 4: if ( (c_partition ->geom .end - c_partition ->geom .start) > MEGABYTE )
{
partition_temp.Set_Unallocated( c_partition ->geom .start , c_partition ->geom .end, false );
device_partitions.push_back( partition_temp );
}
break ;
//FREESPACE INSIDE EXTENDED
case 5: if ( (c_partition ->geom .end - c_partition ->geom .start) > MEGABYTE )
{
partition_temp.Set_Unallocated( c_partition ->geom .start , c_partition ->geom .end, true );
device_partitions.push_back( partition_temp );
}
break ;
//METADATA (do nothing)
default: break;
}
//reset stuff..
this ->error = ""; error_message = ""; os.str("");
//next partition (if any)
c_partition = ped_disk_next_partition ( disk, c_partition ) ;
}
}
bool Device::Delete_Partition( const Partition & partition )
{
if ( partition .type == GParted::EXTENDED )
c_partition = ped_disk_extended_partition( disk ) ;
else
c_partition = ped_disk_get_partition_by_sector( disk, (partition .sector_end + partition .sector_start) / 2 ) ;
if ( ! ped_disk_delete_partition( disk, c_partition ) )
return false;
return Commit() ;
}
int Device::Create_Empty_Partition( const Partition & new_partition, PedConstraint * constraint )
{
PedPartitionType type;
PedPartition *c_part = NULL ;
//create new partition
switch ( new_partition .type )
{
case 0 : type = PED_PARTITION_NORMAL; break;
case 1 : type = PED_PARTITION_LOGICAL; break;
case 2 : type = PED_PARTITION_EXTENDED; break;
default : break;
}
c_part = ped_partition_new ( disk, type, NULL, new_partition .sector_start, new_partition .sector_end ) ;
//create constraint
if ( ! constraint )
constraint = ped_constraint_any ( device);
//and add the whole thingy to disk..
if ( ! constraint || ! ped_disk_add_partition (disk, c_part, constraint) || ! Commit() )
return 0 ;
ped_constraint_destroy (constraint);
return c_part ->num;
}
bool Device::Create_Partition_With_Filesystem( Partition & new_part, PedTimer * timer)
{
//no need to create a filesystem on an extended partition
if ( new_part .type == GParted::EXTENDED )
return Create_Empty_Partition( new_part ) ;
else
{
new_part .partition_number = Create_Empty_Partition( new_part ) ;
return Set_Partition_Filesystem( new_part, timer ) ;
}
}
bool Device::Move_Resize_Partition( const Partition & partition_original, const Partition & partition_new , PedTimer *timer )
{
PedPartition *c_part = NULL ;
PedFileSystem *fs = NULL ;
PedConstraint *constraint = NULL ;
//since resizing extended is a bit different i handle it elsewhere..
if ( partition_new.type == GParted::EXTENDED )
return Resize_Extended( partition_new, timer ) ;
//normal partitions....
c_part = ped_disk_get_partition_by_sector( disk, (partition_original .sector_end + partition_original .sector_start) / 2 ) ;
if ( ! c_part )
return false;
fs = ped_file_system_open (& c_part->geom );
if ( ! fs )
return false ;
constraint = ped_file_system_get_resize_constraint (fs);
if ( ! constraint )
{
ped_file_system_close (fs);
return false;
}
if ( ! ped_disk_set_partition_geom (disk, c_part, constraint, partition_new .sector_start, partition_new .sector_end ) )
{
ped_constraint_destroy (constraint);
ped_file_system_close (fs);
return false ;
}
if ( ! ped_file_system_resize (fs, & c_part->geom, timer) )
{
ped_constraint_destroy (constraint);
ped_file_system_close (fs);
return false ;
}
ped_constraint_destroy (constraint);
ped_file_system_close (fs);
return Commit() ;
}
bool Device::Set_Partition_Filesystem( const Partition & new_partition, PedTimer * timer)
{
if ( new_partition .partition_number <= 0 )
return false ;
PedPartition *c_part = NULL ;
PedFileSystemType *fs_type = NULL ;
PedFileSystem *fs = NULL ;
c_part = ped_disk_get_partition_by_sector( disk, (new_partition .sector_end + new_partition .sector_start) / 2 ) ;
if ( ! c_part )
return false;
fs_type = ped_file_system_type_get ( new_partition .filesystem .c_str() ) ;
if ( ! fs_type )
return false;
fs = ped_file_system_create ( & c_part ->geom, fs_type, timer);
if ( ! fs )
return false;
ped_file_system_close (fs);
if ( ! ped_partition_set_system (c_part, fs_type ) )
return false;
return Commit() ;
}
bool Device::Copy_Partition( Device *source_device, const Partition & source_partition, PedTimer * timer)
{
PedPartition *c_part_src = NULL;
PedFileSystem *src_fs = NULL;
PedPartition *c_part = NULL;
PedFileSystem *dst_fs = NULL;
PedFileSystemType* dst_fs_type = NULL;
//prepare source for reading
if ( source_device ->Get_Path() == this ->path )
c_part_src = ped_disk_get_partition( disk, source_partition .partition_number ) ;
else
c_part_src = source_device ->Get_c_partition( source_partition .partition_number ) ;
if ( ! c_part_src )
return false;
src_fs = ped_file_system_open ( &c_part_src ->geom );
if ( ! src_fs )
return false ;
//create new empty partition
c_part = ped_disk_get_partition( disk,Create_Empty_Partition( source_partition, ped_file_system_get_copy_constraint ( src_fs, device ) ) ) ;
if ( ! c_part )
return false ;
//and do the copy
dst_fs = ped_file_system_copy (src_fs, &c_part ->geom, timer);
if ( ! dst_fs )
{
ped_file_system_close (src_fs);
return false ;
}
dst_fs_type = dst_fs ->type; // may be different to src_fs->type
ped_file_system_close (src_fs);
ped_file_system_close (dst_fs);
if ( !ped_partition_set_system (c_part, dst_fs_type) )
return false ;
return Commit() ;
}
bool Device::Resize_Extended( const Partition & partition , PedTimer *timer)
{
PedPartition *c_part = NULL ;
PedConstraint *constraint = NULL ;
c_part = ped_disk_extended_partition( disk ) ;
if ( ! c_part )
return false;
constraint = ped_constraint_any ( device );
if ( ! constraint )
return false;
if ( ! ped_disk_set_partition_geom (disk, c_part, constraint, partition.sector_start, partition.sector_end ) )
{
ped_constraint_destroy (constraint);
return false ;
}
ped_partition_set_system ( c_part, NULL);
ped_constraint_destroy (constraint);
return Commit() ;
}
bool Device::Commit()
{
bool return_value = ped_disk_commit_to_dev( disk ) ;
//i don't want this annoying "warning couldn't reread blabla" message all the time. I throw one myself if necessary )
ped_exception_fetch_all() ;
ped_disk_commit_to_os( disk ) ;
ped_exception_leave_all() ;
return return_value ;
}
PedPartition * Device::Get_c_partition( int part_num )
{
return ped_disk_get_partition( disk, part_num ) ;
}
std::vector<Partition> Device::Get_Partitions()
{
return device_partitions;
}
Sector Device::Get_Length()
{
return length ;
}
long Device::Get_Heads()
{
return heads ;
}
long Device::Get_Sectors()
{
return sectors ;
}
long Device:: Get_Cylinders()
{
return cylinders ;
}
Glib::ustring Device::Get_Model()
{
return model ;
}
Glib::ustring Device::Get_Path()
{
return path ;
}
Glib::ustring Device::Get_RealPath()
{
return realpath ;
}
Glib::ustring Device::Get_DiskType()
{
return disktype ;
}
bool Device::Get_any_busy()
{
for ( unsigned int t=0;t<device_partitions.size(); t++ )
if ( device_partitions[t].busy )
return true;
return false;
}
int Device::Get_Max_Amount_Of_Primary_Partitions()
{
return ped_disk_get_max_primary_partition_count( disk ) ;
}
Sector Device::Get_Used_Sectors( PedPartition *c_partition, const Glib::ustring & sym_path)
{
/* This is quite an unreliable process, atm i try two different methods, but since both are far from perfect the results are
* questionable.
* - first i try geometry.get_used() in libpartedpp, i implemented this function to check the minimal size when resizing a partition. Disadvantage
* of this method is the fact it won't work on mounted filesystems. Besides that, its SLOW
* - if the former method fails ( result is -1 ) i'll try to read the output from the df command ( df -k --sync <partition path> )
* - if this fails the filesystem on the partition is ( more or less ) unknown to the operating system and therefore the unused sectors cannot be calcualted
* - as soon as i have my internetconnection back i should ask people with more experience on this stuff for advice !
*/
//check if there is a (known) filesystem
if ( ! c_partition ->fs_type )
return -1;
//used sectors are not relevant for swapspace
if ( (Glib::ustring) c_partition ->fs_type ->name == "linux-swap" )
return -1;
//METHOD #1
//the getused method doesn't work on mounted partitions and for some filesystems ( i *guess* this is called check by andrew )
if ( ! ped_partition_is_busy( c_partition ) && (Glib::ustring) c_partition ->fs_type ->name != "ntfs" )
{
PedFileSystem *fs = NULL;
PedConstraint *constraint = NULL;
fs = ped_file_system_open( & c_partition ->geom ); //opening a filesystem is *SLOOOWW* :-(
if ( fs )
{
constraint = ped_file_system_get_resize_constraint (fs);
ped_file_system_close (fs);
if ( constraint && constraint->min_size != -1 ) //apperantly the compiler evaluates constraint != NULL before the min_size check. Very nice! :D
return constraint->min_size ;
}
else
this ->error = error_message ;
}
//METHOD #2
//this ony works for mounted ( and therefore known to the OS ) filesystems. My method is quite crude, keep in mind it's only temporarely ;-)
Glib::ustring buf;
system( ("df -k --sync " + sym_path + " | grep " + sym_path + " > /tmp/.tmp_gparted").c_str() );
std::ifstream file_input( "/tmp/.tmp_gparted" );
file_input >> buf; //skip first value
file_input >> buf;
if ( buf != "0" && ! buf.empty() )
{
file_input >> buf;
file_input.close(); system( "rm -f /tmp/.tmp_gparted" );
return atoi( buf.c_str() ) * 1024/512 ;
}
file_input.close(); system( "rm -f /tmp/.tmp_gparted" );
return -1 ; //all methods were unsuccesfull
}
Glib::ustring Device::Get_Flags( PedPartition *c_partition )
{
temp = "";
for ( unsigned short t = 0; t < flags.size() ; t++ )
if ( ped_partition_get_flag ( c_partition, flags[ t ] ) )
temp += (Glib::ustring) ped_partition_flag_get_name ( flags[ t ] ) + " ";
return temp ;
}
bool Device::open_device_and_disk()
{
device = ped_device_get( this->realpath .c_str() );
if ( device )
disk = ped_disk_new( device );
if ( ! device || ! disk )
{
if ( device )
{ ped_device_destroy( device ) ; device = NULL ; }
return false;
}
return true ;
}
void Device::close_device_and_disk()
{
if ( device )
{
ped_device_destroy( device ) ;
device = NULL ;
}
if ( disk )
{
ped_disk_destroy( disk ) ;
disk = NULL ;
}
}
Device::~Device()
{
close_device_and_disk() ;
}
} //GParted

87
src/Dialog_About.cc Normal file
View File

@ -0,0 +1,87 @@
/* Copyright (C) 2004 Bart
*
* 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 Library 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include "../include/Dialog_About.h"
Dialog_About::Dialog_About()
{
/*TO TRANSLATORS: this is the dialog title */
this ->set_title( _( "About GParted" ) );
this ->set_size_request( -1, 220 ) ;
this ->set_resizable( false );
this ->set_has_separator( false ) ;
label_temp = manage( new Gtk::Label() ) ;
label_temp -> set_markup( "\n<span size='small'>logo here ;)</span>\n" ) ;
this ->get_vbox()->pack_start( *label_temp ,Gtk::PACK_SHRINK );
label_temp = manage( new Gtk::Label() ) ;
label_temp -> set_markup( "<span size='xx-large'><b>" + (Glib::ustring) _( "GParted" ) + " 0.0.4</b></span>" ) ;
this ->get_vbox()->pack_start( *label_temp ,Gtk::PACK_SHRINK );
label_temp = manage( new Gtk::Label() ) ;
label_temp -> set_text( "\n" + (Glib::ustring) _( "Gnome Partition Editor based on libparted" ) + "\n" ) ;
this ->get_vbox()->pack_start( *label_temp ,Gtk::PACK_SHRINK );
label_temp = manage( new Gtk::Label() ) ;
label_temp -> set_markup( "<span size='small'>" + (Glib::ustring) _( "Copyright (c)" ) + " 2004 Bart Hakvoort</span>" ) ;
this ->get_vbox()->pack_start( *label_temp ,Gtk::PACK_SHRINK );
label_temp = manage( new Gtk::Label() ) ;
label_temp -> set_markup( "<span size='small'>http://gparted.sourceforge.net</span>" ) ;
label_temp -> set_selectable( true ) ;
this ->get_vbox()->pack_start( *label_temp ,Gtk::PACK_SHRINK );
label_temp = manage( new Gtk::Label() ) ;
label_temp -> set_text( "\t\t" ) ;
button_credits.add_pixlabel( "/usr/share/icons/hicolor/16x16/stock/generic/stock_about.png", "Credits", 0, 0.5 ) ;
button_credits.signal_clicked() .connect( sigc::mem_fun( this, &Dialog_About::Show_Credits ) ) ;
this ->get_action_area() ->pack_start( button_credits ) ;
this ->get_action_area() ->pack_start( *label_temp ) ;
this ->add_button( Gtk::Stock::CLOSE, Gtk::RESPONSE_CLOSE );
this ->show_all_children() ;
}
void Dialog_About::Show_Credits()
{
Gtk::Dialog dialog( _("Credits"), *this ) ;
Gtk::Notebook notebook_credits;
Gtk::VBox vbox_written, vbox_documented, vbox_translators ;
Gtk::Label label_writers( "Bart Hakvoort (gparted@users.sourceforge.net)");
vbox_written .set_border_width( 5 ) ;
vbox_written .pack_start( label_writers, Gtk::PACK_SHRINK ) ;
notebook_credits .set_size_request( -1, 200 ) ;
/*TO TRANSLATORS: tablabel in aboutdialog */
notebook_credits .append_page( vbox_written, _("Written by") ) ;
/*TO TRANSLATORS: tablabel in aboutdialog */
notebook_credits .append_page( vbox_documented, _("Documented by") ) ;
/*TO TRANSLATORS: tablabel in aboutdialog */
notebook_credits .append_page( vbox_translators, _("Translated by") ) ;
dialog .get_vbox()->pack_start( notebook_credits, Gtk::PACK_SHRINK );
dialog .add_button( Gtk::Stock::CLOSE, Gtk::RESPONSE_CLOSE );
dialog .set_resizable( false );
dialog .show_all_children() ;
dialog .run() ;
}

View File

@ -0,0 +1,325 @@
/* Copyright (C) 2004 Bart
*
* 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 Library 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include "../include/Dialog_Base_Partition.h"
namespace GParted
{
Dialog_Base_Partition::Dialog_Base_Partition( )
{
this ->set_has_separator( false ) ;
frame_resizer_base = NULL;
GRIP = false ;
this -> fixed_start = false ;
this -> set_resizable( false );
//pack resizer hbox
this ->get_vbox() ->pack_start( hbox_resizer, Gtk::PACK_SHRINK );
//add label_minmax
this ->get_vbox() ->pack_start( label_minmax, Gtk::PACK_SHRINK );
//pack hbox_main
this ->get_vbox() ->pack_start( hbox_main, Gtk::PACK_SHRINK );
//put the vbox with resizer stuff (cool widget and spinbuttons) in the hbox_main
hbox_main .pack_start( vbox_resize_move, Gtk::PACK_EXPAND_PADDING);
//fill table
table_resize .set_border_width( 5 ) ;
table_resize .set_row_spacings( 5 ) ;
hbox_table.pack_start( table_resize, Gtk::PACK_EXPAND_PADDING ) ;
hbox_table .set_border_width( 5 ) ;
vbox_resize_move .pack_start( hbox_table, Gtk::PACK_SHRINK );
//add spinbutton_before
label_temp = manage( new Gtk::Label( (Glib::ustring) _( "Free Space Preceding") + " (MB) :\t" ) ) ;
table_resize.attach( *label_temp, 0,1,0,1,Gtk::SHRINK);
spinbutton_before .set_numeric( true );
spinbutton_before .set_increments( 1, 100 );
table_resize.attach( spinbutton_before, 1,2,0,1,Gtk::FILL);
//add spinbutton_size
label_temp = manage( new Gtk::Label( (Glib::ustring) _( "New Size") + " (MB) :" ) ) ;
label_temp ->set_alignment( Gtk::ALIGN_LEFT );
table_resize.attach( *label_temp, 0,1,1,2 );
spinbutton_size .set_numeric( true );
spinbutton_size .set_increments( 1, 100 );
table_resize.attach( spinbutton_size, 1,2,1,2,Gtk::FILL);
//add spinbutton_after
label_temp = manage( new Gtk::Label( (Glib::ustring) _( "Free Space Following") + " (MB) :" ) ) ;
label_temp ->set_alignment( Gtk::ALIGN_LEFT );
table_resize.attach( *label_temp, 0,1,2,3 ) ;
spinbutton_after .set_numeric( true );
spinbutton_after .set_increments( 1, 100 );
table_resize.attach( spinbutton_after, 1,2,2,3,Gtk::FILL);
if ( ! fixed_start )
before_value = spinbutton_before .get_value() ;
//connect signalhandlers of the spinbuttons
if ( ! fixed_start )
spinbutton_before .signal_value_changed().connect( sigc::bind<SPINBUTTON>( sigc::mem_fun( *this, &Dialog_Base_Partition::on_spinbutton_value_changed), BEFORE) ) ;
spinbutton_size .signal_value_changed().connect( sigc::bind<SPINBUTTON>( sigc::mem_fun( *this, &Dialog_Base_Partition::on_spinbutton_value_changed), SIZE) ) ;
spinbutton_after .signal_value_changed().connect( sigc::bind<SPINBUTTON>( sigc::mem_fun( *this, &Dialog_Base_Partition::on_spinbutton_value_changed), AFTER) ) ;
//pack label which warns about small differences in values..
label_temp = manage( new Gtk::Label( ) );
label_temp ->set_markup( "\n <i>" + (Glib::ustring) _( "NOTE: values on disk may differ slightly from the values entered here.") + "</i>" );
label_temp ->set_alignment( Gtk::ALIGN_LEFT ) ;
this ->get_vbox() ->pack_start( *label_temp, Gtk::PACK_SHRINK );
this ->get_vbox() ->pack_start( *( manage( new Gtk::Label( "") ) ), Gtk::PACK_SHRINK ); //filler :-P
this->add_button( Gtk::Stock::CANCEL,Gtk::RESPONSE_CANCEL );
this ->show_all_children() ;
}
void Dialog_Base_Partition::Set_Resizer( bool extended )
{
if ( extended )
{
frame_resizer_base = new Frame_Resizer_Extended( ) ;
}
else
{
frame_resizer_base = new Frame_Resizer_Base( ) ;
frame_resizer_base ->signal_move .connect ( sigc::mem_fun( this, &Dialog_Base_Partition::on_signal_move) );
}
frame_resizer_base ->set_border_width( 5 ) ;
frame_resizer_base ->set_shadow_type(Gtk::SHADOW_ETCHED_OUT);
//connect signals
frame_resizer_base ->signal_resize .connect ( sigc::mem_fun( this, &Dialog_Base_Partition::on_signal_resize) );
hbox_resizer .pack_start( *frame_resizer_base, Gtk::PACK_SHRINK );
this ->show_all_children() ;
}
Partition Dialog_Base_Partition::Get_New_Partition()
{
//no need to set the start of a fixed_start one ;-)
if ( ! fixed_start )
selected_partition.sector_start = START + (Sector) spinbutton_before .get_value() * MEGABYTE ;
selected_partition.sector_end = selected_partition.sector_start + (Sector) spinbutton_size.get_value() * MEGABYTE ;
//due to loss of precision during calcs from Sector -> MB and back, it is possible the new partition thinks it's bigger then it can be. Here we solve this.
if ( selected_partition.sector_start < START )
selected_partition.sector_start = START ;
if ( selected_partition.sector_end > (START + total_length) )
selected_partition.sector_end = START + total_length ;
//grow a bit into small freespace ( < 1MB )
if ( (selected_partition.sector_start - START) < MEGABYTE )
selected_partition.sector_start = START ;
if ( ( START + total_length - selected_partition.sector_end ) < MEGABYTE )
selected_partition.sector_end = START + total_length ;
//set new value of unused..
if ( selected_partition .sectors_used != -1 )
selected_partition .sectors_unused = ( selected_partition .sector_end - selected_partition .sector_start) - selected_partition .sectors_used ;
return selected_partition ;
}
void Dialog_Base_Partition::Set_Confirm_Button( CONFIRMBUTTON button_type )
{
switch( button_type )
{
case NEW : this->add_button( Gtk::Stock::ADD,Gtk::RESPONSE_OK );
break ;
case RESIZE_MOVE : if ( selected_partition.filesystem == "ext2" || selected_partition.filesystem == "ext3" )
label_temp = manage( new Gtk::Label( _("Resize") ) ) ;
else
label_temp = manage( new Gtk::Label( _("Resize/Move") ) ) ;
image_temp = manage( new Gtk::Image( Gtk::Stock::GOTO_LAST, Gtk::ICON_SIZE_BUTTON ) );
hbox_resize_move .pack_start( *image_temp, Gtk::PACK_EXPAND_PADDING ) ;
hbox_resize_move .pack_start( *label_temp, Gtk::PACK_EXPAND_PADDING ) ;
button_resize_move .add( hbox_resize_move ) ;
this ->add_action_widget ( button_resize_move,Gtk::RESPONSE_OK ) ;
button_resize_move .set_sensitive( false ) ;
break ;
case PASTE : this->add_button( Gtk::Stock::PASTE,Gtk::RESPONSE_OK );
break ;
}
}
void Dialog_Base_Partition::on_signal_move( int x_start, int x_end )
{
GRIP = true ;
if ( x_start == 0 )
spinbutton_before .set_value( 0 ) ;
else
spinbutton_before .set_value( x_start * MB_PER_PIXEL ) ;
if ( x_end == 500 )
{
spinbutton_after .set_value(0 ) ;
spinbutton_before .set_value( TOTAL_MB - spinbutton_size .get_value() ) ;
}
else
spinbutton_after .set_value( TOTAL_MB - spinbutton_before .get_value() - spinbutton_size .get_value() ) ;
this ->x_start = x_start ;
this ->x_end = x_end ;
Check_Change() ;
GRIP = false ;
}
void Dialog_Base_Partition::on_signal_resize( int x_start, int x_end, Frame_Resizer_Base::ArrowType arrow)
{
GRIP = true ;
//check for upper/lower limit fat16
if ( selected_partition.filesystem == "fat16" && ( ( x_end - x_start ) * MB_PER_PIXEL > 1023 || ( x_end - x_start ) * MB_PER_PIXEL < 32 ) )
{
frame_resizer_base ->set_x_start( this ->x_start );
frame_resizer_base ->set_x_end( this ->x_end );
frame_resizer_base ->Draw_Partition() ;
GRIP = false ;
return ;
}
//check for lower limit fat32
if ( selected_partition.filesystem == "fat32" && ( x_end - x_start ) * MB_PER_PIXEL < 256 )
{
frame_resizer_base ->set_x_start( this ->x_start );
frame_resizer_base ->set_x_end( this ->x_end );
frame_resizer_base ->Draw_Partition() ;
GRIP = false ;
return ;
}
spinbutton_size .set_value( ( x_end - x_start ) * MB_PER_PIXEL ) ;
fixed_start ? before_value = 0 : before_value = spinbutton_before .get_value() ;
if ( arrow == Frame_Resizer_Base::ARROW_RIGHT ) //don't touch freespace before, leave it as it is
{
if ( x_end == 500 )
{
spinbutton_after .set_value(0 ) ;
spinbutton_size .set_value( TOTAL_MB - before_value ) ;
}
else
spinbutton_after .set_value( TOTAL_MB - before_value - spinbutton_size .get_value() ) ;
}
else if ( arrow == Frame_Resizer_Base::ARROW_LEFT ) //don't touch freespace after, leave it as it is
{
if ( x_start == 0 )
{
spinbutton_before .set_value( 0 );
spinbutton_size .set_value( TOTAL_MB - spinbutton_after.get_value() ) ;
}
else
spinbutton_before .set_value( TOTAL_MB - spinbutton_size .get_value() - spinbutton_after .get_value() ) ;
}
this ->x_start = x_start ;
this ->x_end = x_end ;
Check_Change() ;
GRIP = false ;
}
void Dialog_Base_Partition::on_spinbutton_value_changed( SPINBUTTON spinbutton )
{
if ( ! GRIP )
{
//i expect libparted soon to be able to move startpoint of ext2/3 as well, so everything is ready for it. Till then this rudimentary check
fixed_start ? before_value = 0 : before_value = spinbutton_before .get_value() ;
//Balance the spinbuttons
switch ( spinbutton )
{
case BEFORE : spinbutton_after.set_value( TOTAL_MB - spinbutton_size.get_value() - before_value) ;
spinbutton_size.set_value( TOTAL_MB - before_value - spinbutton_after.get_value( ) ) ;
break;
case SIZE : spinbutton_after.set_value( TOTAL_MB - before_value - spinbutton_size.get_value() );
if ( ! fixed_start )
spinbutton_before .set_value( TOTAL_MB - spinbutton_size.get_value() - spinbutton_after.get_value() );
break;
case AFTER : if ( ! fixed_start )
spinbutton_before .set_value( TOTAL_MB - spinbutton_size.get_value() - spinbutton_after.get_value() );
spinbutton_size.set_value( TOTAL_MB - before_value - spinbutton_after.get_value( ) ) ;
break;
}
//And apply the changes to the visual view...
if ( ! fixed_start )
frame_resizer_base ->set_x_start( (int) (spinbutton_before .get_value() / MB_PER_PIXEL + 0.5) ) ;
frame_resizer_base ->set_x_end( (int) ( 500 - ( (double) spinbutton_after .get_value() / MB_PER_PIXEL ) + 0.5 ) ) ;
this ->x_start = frame_resizer_base ->get_x_start() ;
this ->x_end = frame_resizer_base ->get_x_end() ;
frame_resizer_base ->Draw_Partition() ;
Check_Change() ;
}
}
void Dialog_Base_Partition::Check_Change()
{
if ( ORIG_BEFORE == spinbutton_before .get_value_as_int() &&
ORIG_SIZE == spinbutton_size .get_value_as_int() &&
ORIG_AFTER == spinbutton_after .get_value_as_int()
)
button_resize_move .set_sensitive( false ) ;
else
button_resize_move .set_sensitive( true ) ;
}
Dialog_Base_Partition::~Dialog_Base_Partition()
{
if ( frame_resizer_base )
delete frame_resizer_base ;
}
} //GParted

View File

@ -0,0 +1,84 @@
/* Copyright (C) 2004 Bart
*
* 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 Library 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include "../include/Dialog_Partition_Copy.h"
namespace GParted
{
Dialog_Partition_Copy::Dialog_Partition_Copy()
{
Set_Resizer( false ) ;
Set_Confirm_Button( PASTE ) ;
}
void Dialog_Partition_Copy::Set_Data( Partition & selected_partition, Partition & copied_partition )
{
GRIP = true ; //prevents on spinbutton_changed from getting activated prematurely
/*TO TRANSLATORS: dialogtitle, looks like Paste /dev/hda3 */
this ->set_title( (Glib::ustring) _( "Paste" ) + " " + copied_partition .partition ) ;
//set partition color
frame_resizer_base ->set_rgb_partition_color( copied_partition .color ) ;
//set some widely used values...
START = selected_partition.sector_start ;
total_length = selected_partition.sector_end - selected_partition.sector_start ;
TOTAL_MB = selected_partition .Get_Length_MB() ;
MB_PER_PIXEL = (double) TOTAL_MB / 500 ;
//now calculate proportional length of partition
frame_resizer_base ->set_x_start( 0 ) ;
frame_resizer_base ->set_x_end( ( Round( (double) (copied_partition.sector_end - copied_partition.sector_start) / ( (double)total_length/500) )) ) ;
frame_resizer_base ->set_used( frame_resizer_base ->get_x_end() ) ;
//set values of spinbutton_before
spinbutton_before .set_range( 0, TOTAL_MB - copied_partition .Get_Length_MB() -1 ) ;//mind the -1 !!
spinbutton_before .set_value( 0 ) ;
//set values of spinbutton_size (check for fat16 maxsize of 1023 MB)
double UPPER;
if ( copied_partition.filesystem == "fat16" && Sector_To_MB( total_length ) > 1023 )
UPPER = 1023 ;
else
UPPER = TOTAL_MB;
spinbutton_size .set_range( copied_partition .Get_Length_MB() +1, UPPER ) ;
spinbutton_size .set_value( copied_partition .Get_Length_MB() ) ;
//set values of spinbutton_after
spinbutton_after .set_range( 0, TOTAL_MB - copied_partition .Get_Length_MB() -1 ) ;
spinbutton_after .set_value( TOTAL_MB - copied_partition .Get_Length_MB() ) ;
//set contents of label_minmax
os << _("Minimum Size") << ": " << copied_partition .Get_Length_MB() +1 ;
os << " MB\t\t" << _( "Maximum Size" ) << ": " << Sector_To_MB( total_length ) << " MB" ;
label_minmax.set_text( os.str() ) ; os.str("") ;
//set global selected_partition (see Dialog_Base_Partition::Get_New_Partition )
this ->selected_partition = copied_partition ;
this ->selected_partition .inside_extended = selected_partition .inside_extended ;
selected_partition .inside_extended ? this ->selected_partition .type = GParted::LOGICAL : this ->selected_partition .type = GParted::PRIMARY ;
GRIP = false ;
}
} //GParted

View File

@ -0,0 +1,264 @@
/* Copyright (C) 2004 Bart
*
* 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 Library 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include "../include/Dialog_Partition_Info.h"
namespace GParted
{
Dialog_Partition_Info::Dialog_Partition_Info( const Partition & partition )
{
this -> partition = partition ;
this->set_resizable( false );
/*TO TRANSLATORS: dialogtitle, looks like Information about /dev/hda3 */
this->set_title( (Glib::ustring) _( "Information about") + " " + partition.partition );
init_drawingarea() ;
//add label for detail and fill with relevant info
Display_Info() ;
//display error (if any)
if ( partition .error != "" )
{
frame = manage( new Gtk::Frame() );
frame ->set_border_width( 10 );
image = manage( new Gtk::Image( Gtk::Stock::DIALOG_WARNING, Gtk::ICON_SIZE_BUTTON ) );
label = manage( new Gtk::Label( ) ) ;
label ->set_markup( "<b> " + (Glib::ustring) _( "Libparted message" ) + ": </b>" ) ;
hbox = manage( new Gtk::HBox() );
hbox ->pack_start( *image, Gtk::PACK_SHRINK ) ;
hbox ->pack_start( *label, Gtk::PACK_SHRINK ) ;
frame ->set_label_widget( *hbox ) ;
label = manage( new Gtk::Label( ) ) ;
label ->set_markup( "<i>" + partition.error + "</i>") ;
label ->set_selectable( true ) ;
label ->set_line_wrap( true ) ;
frame ->add( *label );
this ->get_vbox() ->pack_start( *frame, Gtk::PACK_SHRINK ) ;
}
this->add_button( Gtk::Stock::CLOSE, Gtk::RESPONSE_OK );
this->show_all_children();
}
void Dialog_Partition_Info::drawingarea_on_realize( )
{
gc = Gdk::GC::create( drawingarea .get_window() );
drawingarea .get_window() ->set_background( color_partition );
}
bool Dialog_Partition_Info::drawingarea_on_expose( GdkEventExpose *ev )
{
if ( partition.type != GParted::UNALLOCATED )
{
//used
gc ->set_foreground( color_used );
drawingarea .get_window() ->draw_rectangle( gc, true, BORDER, BORDER, used ,34 );
//unused
gc ->set_foreground( color_unused );
drawingarea .get_window() ->draw_rectangle( gc, true, BORDER + used, BORDER, unused,34 );
}
//text
gc ->set_foreground( color_text );
drawingarea .get_window() ->draw_layout( gc, BORDER +5, BORDER +1 , pango_layout ) ;
return true;
}
void Dialog_Partition_Info::init_drawingarea()
{
drawingarea .set_size_request( 375, 50 ) ;
drawingarea.signal_realize().connect( sigc::mem_fun(*this, &Dialog_Partition_Info::drawingarea_on_realize) ) ;
drawingarea.signal_expose_event().connect( sigc::mem_fun(*this, &Dialog_Partition_Info::drawingarea_on_expose) ) ;
frame = manage( new Gtk::Frame() );
frame ->add ( drawingarea ) ;
frame ->set_shadow_type(Gtk::SHADOW_ETCHED_OUT);
frame ->set_border_width( 10 );
hbox = manage( new Gtk::HBox() ) ;
hbox ->pack_start( *frame, Gtk::PACK_EXPAND_PADDING ) ;
this ->get_vbox() ->pack_start( *hbox, Gtk::PACK_SHRINK ) ;
//calculate proportional width of used and unused
used = unused = 0 ;
used = (int ) ( ( (375 - BORDER *2) / ( (double) (partition.sector_end - partition.sector_start) / partition.sectors_used ) )+0.5 ) ;
unused = 375 - used - (BORDER *2) ;
//allocate some colors
color_used.set( "#F8F8BA" ); this ->get_colormap() ->alloc_color( color_used ) ;
partition .type == GParted::EXTENDED ? color_unused.set( "darkgrey" ) : color_unused.set( "white" ) ;
this ->get_colormap() ->alloc_color( color_unused ) ;
color_text.set( "black" ); this ->get_colormap() ->alloc_color( color_text ) ;
color_partition = partition.color ; this ->get_colormap() ->alloc_color( color_partition ) ;
//set text of pangolayout
os << partition .partition << "\n" << this -> partition .Get_Length_MB() << " MB";
pango_layout = drawingarea .create_pango_layout ( os.str() ) ;os.str("");
}
void Dialog_Partition_Info::Display_Info()
{
table = manage( new Gtk::Table() ) ;
table ->set_border_width( 5 ) ;
table ->set_col_spacings(10 ) ;
this ->get_vbox() ->pack_start( *table , Gtk::PACK_SHRINK ) ;
label = manage( new Gtk::Label( "<b>" ) ) ;
label ->set_text( label ->get_text() + (Glib::ustring) _( "Filesystem" ) + ":\n" ) ; os << partition.filesystem << "\n";
label ->set_text( label ->get_text() + (Glib::ustring) _( "Size" ) + ":\n" ) ; os << this -> partition .Get_Length_MB() << " MB\n";
if ( partition.sectors_used != -1 )
{
label ->set_text( label ->get_text() + (Glib::ustring) _( "Used" ) + ":\n" ) ;
label ->set_text( label ->get_text() + (Glib::ustring) _( "Unused" ) + ":\n" ) ;
os << this ->partition .Get_Used_MB() << " MB\n";
os << this ->partition .Get_Unused_MB() << " MB\n" ;
int percent_used =(int) ( (double) partition.Get_Used_MB() / partition .Get_Length_MB() *100 +0.5 ) ;
os_percent << "\n\n( " << percent_used << "% )\n( " << 100 - percent_used << "% )\n\n\n";
}
label ->set_text( label ->get_text() + (Glib::ustring) _( "Flags" ) + ":\n\n" ) ; os << partition .flags << "\n\n";
if ( partition.type != GParted::UNALLOCATED && partition .partition.substr( 0, 3 ) != "New" )
{
label ->set_text( label ->get_text() + (Glib::ustring) _("Path" ) + ":\n" ) ; os << partition.partition << "\n";
//get realpath
char real_path[4096] ;
realpath( partition.partition.c_str() , real_path );
//only show realpath if it's diffent from the short path...
if ( partition.partition != real_path )
{
label ->set_text( label ->get_text() + (Glib::ustring) _("Real Path" ) + ":\n" ) ;
os << (Glib::ustring) real_path << "\n";
os_percent << "\n" ;
}
label ->set_text( label ->get_text() + (Glib::ustring) _("Status" ) + ":\n" ) ;
if ( partition.busy )
Find_Status() ;
else if ( partition.type == GParted::EXTENDED )
os << (Glib::ustring) _("Not busy (There are no mounted logical partitions)" ) + "\n";
else if ( partition.filesystem == "linux-swap" )
os << (Glib::ustring) _("Not active" ) + "\n";
else
os << (Glib::ustring) _("Not mounted" ) + "\n";
os_percent << "\n\n" ;
}
label ->set_text( label ->get_text() + "\n" ) ; os << "\n"; //splitter :P
label ->set_text( label ->get_text() + (Glib::ustring) _("First Sector" ) + ":\n" ) ; os << partition.sector_start << "\n";
label ->set_text( label ->get_text() + (Glib::ustring) _("Last Sector" ) + ":\n" ) ; os << partition.sector_end << "\n";
label ->set_text( label ->get_text() + (Glib::ustring) _("Total Sectors" ) + ":\n" ) ; os << partition.sector_end - partition.sector_start << "\n";
label ->set_text( label ->get_text() + "</b>" ) ;
label ->set_use_markup( true ) ;
table ->attach( *label, 0,1,0,1,Gtk::SHRINK);
label = manage( new Gtk::Label( ) ) ;
label ->set_markup( os.str() ) ; os.str("") ;
table ->attach( *label, 1,2,0,1,Gtk::SHRINK);
label = manage( new Gtk::Label( ) ) ;
label ->set_markup( os_percent.str() + "\n\n\n\n" ) ; os_percent.str("") ;
table ->attach( *label, 1,2,0,1,Gtk::SHRINK);
}
void Dialog_Partition_Info::Find_Status()
{
if ( partition.type == GParted::EXTENDED )
{
os << _("Busy (At least one logical partition is mounted)" ) << "\n";
return ;
}
if ( partition.filesystem == "linux-swap" )
{
os << _("Active") << "\n";
return ;
}
//try to find the mountpoint in /proc/mounts
//get realpath
char real_path[4096] ;
realpath( partition.partition.c_str() , real_path );
Glib::ustring mountpoint, partition_real_path = real_path ; //because root partition is listed as /dev/root we need te compare against te real path..
std::ifstream file_mounts( "/proc/mounts" ) ;
std::string line ;
while ( getline( file_mounts, line ) )
{
realpath( line.substr( 0, line.find( ' ' ) ) .c_str() , real_path );
if ( partition_real_path == real_path )
{
mountpoint = line.substr( line.find( ' ' ) +1, line .length() ) ;
/*TO TRANSLATORS: used as: mounted on <mountpoint>*/
os << _("Mounted on") << " " << mountpoint .substr( 0, mountpoint .find( ' ' ) ) << "\n";
break ;
}
}
file_mounts .close() ;
//sometimes rootdevices are not listed as paths. I'll take a guess and just enter / here...( we'll look into this when complaints start coming in :P )
if ( mountpoint.empty() )
os << _("Mounted on") << " /\n";
}
Dialog_Partition_Info::~Dialog_Partition_Info()
{
this ->get_colormap() ->free_colors( color_used, 1 ) ;
this ->get_colormap() ->free_colors( color_unused, 1 ) ;
this ->get_colormap() ->free_colors( color_text, 1 ) ;
this ->get_colormap() ->free_colors( color_partition, 1 ) ;
}
} //GParted

243
src/Dialog_Partition_New.cc Normal file
View File

@ -0,0 +1,243 @@
/* Copyright (C) 2004 Bart
*
* 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 Library 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include "../include/Dialog_Partition_New.h"
namespace GParted
{
Dialog_Partition_New::Dialog_Partition_New( )
{
/*TO TRANSLATORS: dialogtitle */
this ->set_title( _("Create new Partition") ) ;
Set_Resizer( false ) ;
Set_Confirm_Button( NEW ) ;
//set partition color
color_temp .set( selected_partition .Get_Color( "ext2" ) ) ;
frame_resizer_base ->set_rgb_partition_color( color_temp ) ;
//set the resizer..
frame_resizer_base ->set_x_start( 0 ) ;
frame_resizer_base ->set_x_end( 500 ) ;
frame_resizer_base ->set_used( 0 ) ;
}
void Dialog_Partition_New::Set_Data( const Partition & partition, bool any_extended, unsigned short new_count )
{
this->new_count = new_count;
this->selected_partition = partition;
//add table with selection menu;s...
table_create .set_border_width( 10 ) ;
table_create.set_row_spacings( 5 ) ;
hbox_main .pack_start( table_create, Gtk::PACK_SHRINK );
/*TO TRANSLATORS: used as label for a list of choices. Create as: <optionmenu with choices> */
label_type.set_text( (Glib::ustring) _("Create as") + ":\t" );
table_create.attach( label_type, 0,1,0,1,Gtk::SHRINK);
//fill partitiontype menu
menu_type.items().push_back(Gtk::Menu_Helpers::MenuElem( "Primary") ) ;
menu_type.items().push_back(Gtk::Menu_Helpers::MenuElem( "Logical") ) ;
menu_type.items().push_back(Gtk::Menu_Helpers::MenuElem( "Extended") ) ;
//determine which PartitionType is allowed
if ( partition.inside_extended )
{
menu_type.items()[0] . set_sensitive( false );
menu_type.items()[2] . set_sensitive( false );
menu_type.set_active( 1 );
}
else
{
menu_type.items()[1] . set_sensitive( false );
if ( any_extended ) menu_type.items()[2] . set_sensitive( false );
}
optionmenu_type.set_menu( menu_type );
optionmenu_type.set_size_request( 150, -1 ); //150 is the ideal width for this table column, (when one widget is set, the rest wil take this width as well)
optionmenu_type.signal_changed().connect( sigc::bind<bool>(sigc::mem_fun(*this, &Dialog_Partition_New::optionmenu_changed), true) );
table_create.attach( optionmenu_type, 1,2,0,1,Gtk::FILL);
//filesystems to choose from
label_filesystem.set_text( (Glib::ustring) _("Filesystem") + ":\t" );
table_create.attach( label_filesystem, 0,1,1,2,Gtk::SHRINK);
Build_Filesystems_Menu() ;
optionmenu_filesystem.set_menu( menu_filesystem );
optionmenu_filesystem.signal_changed().connect( sigc::bind<bool>(sigc::mem_fun(*this, &Dialog_Partition_New::optionmenu_changed), false) );
table_create.attach( optionmenu_filesystem, 1,2,1,2,Gtk::FILL);
//set some widely used values...
START = partition.sector_start ;
total_length = partition.sector_end - partition.sector_start ;
TOTAL_MB = this ->selected_partition .Get_Length_MB() ;
MB_PER_PIXEL = (double) TOTAL_MB / 500 ;
//set spinbuttons
GRIP = true ; //prevents on spinbutton_changed from getting activated prematurely
spinbutton_before .set_range( 0, TOTAL_MB -1 ) ;//mind the -1 !!
spinbutton_before .set_value( 0 ) ;
spinbutton_size .set_range( 1, TOTAL_MB ) ;
spinbutton_size .set_value( TOTAL_MB ) ;
spinbutton_after .set_range( 0, TOTAL_MB -1 ) ;//mind the -1 !!
spinbutton_after .set_value( 0 ) ;
GRIP = false ;
//set contents of label_minmax
os << _("Minimum Size") << ": " << 1 << " MB\t\t";
os << _("Maximum Size") << ": " << TOTAL_MB << " MB" ;
label_minmax.set_text( os.str() ) ; os.str("") ;
this ->show_all_children() ;
}
Partition Dialog_Partition_New::Get_New_Partition()
{
Partition part_temp ;
PartitionType part_type;
Sector new_start, new_end;
switch ( optionmenu_type.get_history() )
{
case 0 : part_type = GParted::PRIMARY; break;
case 1 : part_type = GParted::LOGICAL; break;
case 2 : part_type = GParted::EXTENDED; break;
}
new_start = START + (Sector) (spinbutton_before .get_value() * MEGABYTE) ;
new_end = new_start + (Sector) (spinbutton_size .get_value() * MEGABYTE) ;
//due to loss of precision during calcs from Sector -> MB and back, it is possible the new partition thinks it's bigger then it can be. Here we try to solve this.
if ( new_start < selected_partition.sector_start )
new_start = selected_partition.sector_start ;
if ( new_end > selected_partition.sector_end )
new_end = selected_partition.sector_end ;
os << "New Partition #" << new_count;
part_temp.Set( os.str(), new_count, part_type , filesystems[ optionmenu_filesystem.get_history() ], new_start, new_end, -1, selected_partition.inside_extended, false) ; os.str("") ;
//THIS SHOULD PROBABLY BE A SETTING IN USERSPACE! ( grow new partition a bit if freespaces are < 1 MB )
if ( (part_temp.sector_start - selected_partition.sector_start) < MEGABYTE )
part_temp.sector_start = selected_partition.sector_start ;
if ( (selected_partition.sector_end - part_temp.sector_end) < MEGABYTE )
part_temp.sector_end = selected_partition.sector_end ;
return part_temp;
}
void Dialog_Partition_New::optionmenu_changed( bool type )
{
//optionmenu_type
if ( type )
{
if (optionmenu_type.get_history() == GParted::EXTENDED )
{
menu_filesystem.items().push_back(Gtk::Menu_Helpers::MenuElem( "extended") ) ;
optionmenu_filesystem.set_history( 5 ) ;
optionmenu_filesystem.set_sensitive( false );
}
else if ( menu_filesystem.items() .size() > 5 )
{
menu_filesystem.items() .remove( menu_filesystem.items() .back() );
optionmenu_filesystem.set_sensitive( true );
optionmenu_filesystem.set_history( 0 ) ;
}
}
//optionmenu_filesystem
if ( ! type )
{
selected_partition .filesystem = filesystems[ optionmenu_filesystem .get_history() ] ; //needed vor upper limit check (see also Dialog_Base_Partition::on_signal_resize )
//set new spinbutton ranges
long MIN, MAX;
switch ( optionmenu_filesystem .get_history() )
{
case 1 : MIN = 32 ;
TOTAL_MB > 1023 ? MAX = 1023 : MAX = TOTAL_MB ;
break;
case 2 : MIN = 256 ;
MAX = TOTAL_MB ;
break;
default : MIN = 1 ;
MAX = TOTAL_MB ;
}
spinbutton_before .set_range( 0, TOTAL_MB - MIN ) ;
spinbutton_size .set_range( MIN, MAX ) ;
spinbutton_after .set_range( 0, TOTAL_MB - MIN ) ;
//set contents of label_minmax
os << _("Minimum Size") << ": " << MIN << " MB\t\t";
os << _("Maximum Size") << ": " << MAX << " MB" ;
label_minmax.set_text( os.str() ) ; os.str("") ;
}
//set fitting resizer colors
//backgroundcolor..
optionmenu_type.get_history() == 2 ? color_temp .set( "darkgrey" ) : color_temp .set( "white" ) ;
frame_resizer_base ->override_default_rgb_unused_color( color_temp );
//partitioncolor..
color_temp .set( selected_partition .Get_Color( filesystems[ optionmenu_filesystem.get_history() ] ) ) ;
frame_resizer_base ->set_rgb_partition_color( color_temp ) ;
frame_resizer_base ->Draw_Partition() ;
}
void Dialog_Partition_New::Build_Filesystems_Menu()
{
//those filesystems can be created by libparted (NOTE: to create reiserfs you need libreiserfs, i'll look into that later )
filesystems.push_back( "ext2" );
filesystems.push_back( "fat16" );
filesystems.push_back( "fat32" );
filesystems.push_back( "linux-swap" );
filesystems.push_back( "ReiserFS" ); //libreiserfs needed
filesystems.push_back( "extended" ); //convenient ;)
//fill the filesystem menu with those filesystems (except for extended)
for ( unsigned int t=0; t< filesystems.size() -1 ; t++ )
menu_filesystem.items().push_back(Gtk::Menu_Helpers::MenuElem( filesystems[t] ) ) ;
//check if selected unallocated is big enough for fat fs'es
if ( this ->selected_partition .Get_Length_MB() < 32 )
menu_filesystem.items()[ 1 ] .set_sensitive( false ) ;
if ( this ->selected_partition .Get_Length_MB() < 256 )
menu_filesystem.items()[ 2 ] .set_sensitive( false ) ;
//disable reiserfs for the time being...
menu_filesystem.items()[ 4 ] .set_sensitive( false ) ;
}
} //GParted

View File

@ -0,0 +1,237 @@
/* Copyright (C) 2004 Bart
*
* 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 Library 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include "../include/Dialog_Partition_Resize_Move.h"
namespace GParted
{
Dialog_Partition_Resize_Move::Dialog_Partition_Resize_Move( )
{
}
void Dialog_Partition_Resize_Move::Set_Data( const Partition & selected_partition, const std::vector <Partition> & partitions )
{
GRIP = true ; //prevents on spinbutton_changed from getting activated prematurely
this ->selected_partition = selected_partition ;
if ( selected_partition .type == GParted::EXTENDED )
{
Set_Resizer( true ) ;
Resize_Move_Extended( partitions ) ;
}
else
{
Set_Resizer( false ) ;
Resize_Move_Normal( partitions ) ;
}
//set partition color
frame_resizer_base ->set_rgb_partition_color( selected_partition .color ) ;
//set some initial values... ( i believe i only use these for fat16 checks.. *sigh* )
this ->x_start = frame_resizer_base ->get_x_start() ;
this ->x_end = frame_resizer_base ->get_x_end() ;
//store the original values
ORIG_BEFORE = spinbutton_before .get_value_as_int() ;
ORIG_SIZE = spinbutton_size .get_value_as_int() ;
ORIG_AFTER = spinbutton_after .get_value_as_int() ;
GRIP = false ;
Set_Confirm_Button( RESIZE_MOVE ) ;
this ->show_all_children() ;
}
void Dialog_Partition_Resize_Move::Resize_Move_Normal( const std::vector <Partition> & partitions )
{
//see if we need a fixed_start
if ( selected_partition.filesystem == "ext2" || selected_partition.filesystem == "ext3" )
{
/*TO TRANSLATORS: dialogtitle. used as Resize /dev/hda1 */
this ->set_title( (Glib::ustring) _("Resize") + " " + selected_partition .partition ) ;
this ->fixed_start = true;
frame_resizer_base ->set_fixed_start( true ) ;
spinbutton_before .set_sensitive( false ) ;
}
else
{
/*TO TRANSLATORS: dialogtitle. used as Resize/Move /dev/hda1 */
this ->set_title( (Glib::ustring) _("Resize/Move") + " " + selected_partition .partition ) ;
frame_resizer_base ->set_fixed_start( false ) ;
}
//calculate total size in MB's of previous, current and next partition
//first find index of partition
unsigned int t;
for ( t=0;t< partitions.size(); t++ )
if ( partitions[t].sector_start == selected_partition.sector_start && partitions[t].type != GParted::EXTENDED )
break;
Sector previous, next ;
previous = next = 0 ;
//also check the partitions filesystem ( if this is ext2/3 then previous should be 0 )
if ( t >= 1 && partitions[t -1].type == GParted::UNALLOCATED && selected_partition.filesystem != "ext2" && selected_partition.filesystem != "ext3" && partitions[t -1] .inside_extended == selected_partition.inside_extended )
{
previous = partitions[t -1].sector_end - partitions[t -1].sector_start ;
START = partitions[t -1].sector_start ;
}
else
START = selected_partition.sector_start ;
if ( t +1 < partitions.size() && partitions[t +1].type == GParted::UNALLOCATED && partitions[t +1] .inside_extended == selected_partition.inside_extended )
next = partitions[t +1].sector_end - partitions[t +1].sector_start ;
total_length = previous + (selected_partition.sector_end - selected_partition.sector_start) + next;
TOTAL_MB = Sector_To_MB( total_length ) ;
MB_PER_PIXEL = (double) TOTAL_MB / 500 ;
//now calculate proportional length of partition
frame_resizer_base ->set_x_start( Round( (double) previous / ( (double)total_length/500) ) ) ;
frame_resizer_base ->set_x_end( ( Round( (double) (selected_partition.sector_end - selected_partition.sector_start) / ( (double)total_length/500) )) + frame_resizer_base ->get_x_start() ) ;
frame_resizer_base ->set_used( Round( (double) selected_partition.sectors_used / ( (double)total_length/500) ) ) ;
//set values of spinbutton_before
if ( ! fixed_start )
{
spinbutton_before .set_range( 0, Sector_To_MB(total_length - selected_partition.sectors_used) -1 ) ;//mind the -1 !!
spinbutton_before .set_value( Sector_To_MB( previous ) ) ;
}
//set values of spinbutton_size
//since some filesystems have upper and lower limits we need to check for this
double LOWER, UPPER;
if ( selected_partition.filesystem == "fat16" && selected_partition .Get_Used_MB() < 32 )
LOWER = 32 +1 ;
else if ( selected_partition.filesystem == "fat32" && selected_partition .Get_Used_MB() < 256 )
LOWER = 256 +1; //when shrinking to 256 the filesystem converts to fat16, thats why i added the 1
else
LOWER = selected_partition .Get_Used_MB() +1;
if ( selected_partition.filesystem == "fat16" && Sector_To_MB( total_length ) > 1023 )
UPPER = 1023 ;
else
UPPER = Sector_To_MB( total_length ) ;
spinbutton_size .set_range( LOWER , UPPER ) ;
spinbutton_size .set_value( selected_partition .Get_Length_MB() ) ;
//set values of spinbutton_after
spinbutton_after .set_range( 0, Sector_To_MB( total_length ) - LOWER ) ;
spinbutton_after .set_value( Sector_To_MB( next ) ) ;
//set contents of label_minmax
os << _("Minimum Size") << ": " << LOWER << " MB\t\t";
os << _("Maximum Size") << ": " << Sector_To_MB( total_length ) << " MB" ;
label_minmax.set_text( os.str() ) ; os.str("") ;
}
void Dialog_Partition_Resize_Move::Resize_Move_Extended( const std::vector <Partition> & partitions )
{
//calculate total size in MB's of previous, current and next partition
//first find index of partition
unsigned int t;
for ( t=0;t< partitions.size(); t++ )
if ( partitions[t].type == GParted::EXTENDED )
break;
Sector previous, next ;
previous = next = 0 ;
//calculate length and start of previous
if ( t > 0 && partitions[t -1].type == GParted::UNALLOCATED )
{
previous = partitions[t -1].sector_end - partitions[t -1].sector_start ;
START = partitions[t -1].sector_start ;
}
else
START = selected_partition.sector_start ;
//calculate length of next (in this case next should be the first partition OUTSIDE the extended .. )
for ( t+=1;t<partitions.size() ; t++ )
{
if ( ! partitions[t].inside_extended )
{
if ( partitions[t].type == GParted::UNALLOCATED )
next = partitions[t].sector_end - partitions[t].sector_start ;
break ;
}
}
//now we have enough data to calculate some important values..
total_length = previous + (selected_partition.sector_end - selected_partition.sector_start) + next;
TOTAL_MB = Sector_To_MB( total_length ) ;
MB_PER_PIXEL = (double) TOTAL_MB / 500 ;
//calculate proportional length of partition ( in pixels )
frame_resizer_base ->set_x_start( Round( (double) previous / ( (double)total_length/500) ) ) ;
frame_resizer_base ->set_x_end( ( Round( (double) (selected_partition.sector_end - selected_partition.sector_start) / ( (double)total_length/500) )) + frame_resizer_base ->get_x_start() ) ;
//used is a bit different here... we consider start of first logical to end last logical as used space
Sector first =0, used =0 ;
for ( t=0;t< partitions.size(); t++ )
{
if ( partitions[t].type == GParted::LOGICAL )
{
if ( first == 0 )
first = partitions[t] .sector_start ;
used = partitions[t] .sector_end - first;
}
}
frame_resizer_base ->set_used_start( Round( (double) (first - START) / ( (double)total_length/500) ) ) ;
frame_resizer_base ->set_used( Round( (double) used / ( (double)total_length/500) ) ) ;
//set values of spinbutton_before (we assume there is no fixed start.)
if ( first == 0 ) //no logicals
spinbutton_before .set_range( 0, TOTAL_MB - 1) ;
else
spinbutton_before .set_range( 0, Sector_To_MB (first - START) ) ;
spinbutton_before .set_value( Sector_To_MB ( previous ) ) ;
//set values of spinbutton_size
if ( first == 0 ) //no logicals
spinbutton_size .set_range( 1 , TOTAL_MB ) ;
else
spinbutton_size .set_range( Sector_To_MB( used ) , TOTAL_MB ) ;
spinbutton_size .set_value( selected_partition .Get_Length_MB() ) ;
//set values of spinbutton_after
if ( first == 0 ) //no logicals
spinbutton_after .set_range( 0, TOTAL_MB -1 ) ;
else
spinbutton_after .set_range( 0, Sector_To_MB( total_length + START - first - used) ) ;
spinbutton_after .set_value( Sector_To_MB( next ) ) ;
//set contents of label_minmax
os << _("Minimum Size") << ": " << Sector_To_MB( used ) +1 << " MB\t\t";
os << _("Maximum Size") << ": " << TOTAL_MB << " MB" ;
label_minmax.set_text( os.str() ) ; os.str("") ;
}
} //GParted

92
src/Dialog_Progress.cc Normal file
View File

@ -0,0 +1,92 @@
/* Copyright (C) 2004 Bart
*
* 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 Library 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include "../include/Dialog_Progress.h"
Dialog_Progress::Dialog_Progress( int count_operations, const Glib::ustring & first_operation )
{
this ->set_size_request( 500, 275 ) ;
this ->set_resizable( false ) ;
this ->set_has_separator( false ) ;
this ->set_title( _("Applying pending operations") ) ;
this ->count_operations = count_operations ;
current_operation_number = 0;
fraction =(double) 1 / count_operations ;
fraction -= 1E-8 ; //minus 1E-8 is to prevent fraction from ever reaching >=1, it needs to be 0.0 < fraction < 1.0
label_temp = manage( new Gtk::Label() ) ;
label_temp ->set_alignment( Gtk::ALIGN_LEFT );
os << "<span weight=\"bold\" size=\"larger\">" << _( "Applying pending operations" ) << "</span>\n\n" ;
os << _("All listed operations are applied to disk.") ;
os << "\n";
os << _("Clicking Cancel will prevent the next operations from being applied.") ;
os << "\n";
label_temp ->set_markup( os.str() ) ; os.str("") ;
this->get_vbox() ->pack_start( *label_temp, Gtk::PACK_SHRINK );
progressbar_current.set_text( _("initializing...") );
this->get_vbox() ->pack_start( progressbar_current , Gtk::PACK_SHRINK);
label_current.set_alignment( Gtk::ALIGN_LEFT );
label_current.set_markup( "<i>" + first_operation + "</i>" ) ;
this->get_vbox() ->pack_start( label_current, Gtk::PACK_SHRINK );
label_all_operations.set_alignment( Gtk::ALIGN_LEFT );
label_all_operations.set_markup( "<b>\n" + (Glib::ustring) _( "Completed Operations" ) + ":</b>");
this->get_vbox() ->pack_start( label_all_operations, Gtk::PACK_SHRINK );
sprintf( c_buf, _("%d of %d operations complete"), 0, count_operations ) ;
progressbar_all.set_text( c_buf ) ;
this->get_vbox() ->pack_start( progressbar_all, Gtk::PACK_SHRINK );
this->get_vbox() ->set_spacing( 5 ) ;
this->get_vbox() ->set_border_width( 15 ) ;
this->add_button( Gtk::Stock::CANCEL,Gtk::RESPONSE_CANCEL );//doesn't work for current operation
this->show_all_children() ;
}
Dialog_Progress::~Dialog_Progress()
{
}
void Dialog_Progress::Set_Next_Operation( )
{
progressbar_all.set_fraction( progressbar_all.get_fraction() + fraction );
sprintf( c_buf, _("%d of %d operations complete"), ++current_operation_number, count_operations ) ;
progressbar_all.set_text( c_buf ) ;
label_current.set_markup( "<i>" + current_operation + "</i>" ) ;
progressbar_current.set_fraction( 0 );
progressbar_current.set_text( "initializing..." );
}
void Dialog_Progress::Set_Progress_Current_Operation( )
{
progressbar_current.set_fraction( fraction_current );
if ( time_left > 59 && time_left < 120 )
sprintf( c_buf, _("about %d minute and %d seconds left"), time_left/60, time_left % 60 ) ;
else
sprintf( c_buf, _("about %d minutes and %d seconds left"), time_left/60, time_left % 60 ) ;
progressbar_current.set_text( c_buf ) ;
}

296
src/Frame_Resizer_Base.cc Normal file
View File

@ -0,0 +1,296 @@
/* Copyright (C) 2004 Bart
*
* 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 Library 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include "../include/Frame_Resizer_Base.h"
Frame_Resizer_Base::Frame_Resizer_Base()
{
this ->fixed_start = false ;
init() ;
}
void Frame_Resizer_Base::init()
{
drawingarea.set_size_request( 536, 50 );
drawingarea.signal_realize().connect( sigc::mem_fun(*this, &Frame_Resizer_Base::drawingarea_on_realize) ) ;
drawingarea.signal_expose_event().connect( sigc::mem_fun(*this, &Frame_Resizer_Base::drawingarea_on_expose) ) ;
drawingarea.signal_motion_notify_event().connect( sigc::mem_fun(*this, &Frame_Resizer_Base::drawingarea_on_mouse_motion) ) ;
drawingarea.signal_button_press_event().connect( sigc::mem_fun(*this, &Frame_Resizer_Base::drawingarea_on_button_press_event) ) ;
drawingarea.signal_button_release_event().connect( sigc::mem_fun(*this, &Frame_Resizer_Base::drawingarea_on_button_release_event) ) ;
drawingarea.signal_leave_notify_event().connect( sigc::mem_fun(*this, &Frame_Resizer_Base::drawingarea_on_leave_notify) ) ;
this ->add( drawingarea ) ;
color_used.set( "#F8F8BA" ); this ->get_colormap() ->alloc_color( color_used ) ;
color_unused.set( "white" ); this ->get_colormap() ->alloc_color( color_unused ) ;
color_arrow.set( "black" ); this ->get_colormap() ->alloc_color( color_arrow ) ;
color_background.set( "darkgrey" ); this ->get_colormap() ->alloc_color( color_background ) ;
color_arrow_rectangle.set( "lightgrey" ); this ->get_colormap() ->alloc_color( color_arrow_rectangle ) ;
cursor_resize = new Gdk::Cursor( Gdk::SB_H_DOUBLE_ARROW ) ;
cursor_normal = new Gdk::Cursor( Gdk::LEFT_PTR ) ;
cursor_move = new Gdk::Cursor( Gdk::FLEUR ) ;
GRIP_MOVE = GRIP_LEFT = GRIP_RIGHT = false;
X_END = 0;
Gdk::Point p;
p.set_y( 15); arrow_points.push_back( p ) ;
p.set_y( 25); arrow_points.push_back( p ) ;
p.set_y( 35); arrow_points.push_back( p ) ;
this ->show_all_children();
}
void Frame_Resizer_Base::set_rgb_partition_color( const Gdk::Color & color )
{
this ->get_colormap() ->free_colors( color_partition, 1 ) ;
this->color_partition = color ;
this ->get_colormap() ->alloc_color( color_partition ) ;
}
void Frame_Resizer_Base::override_default_rgb_unused_color( const Gdk::Color & color )
{
this ->get_colormap() ->free_colors( color_unused, 1 ) ;
this->color_unused = color ;
this ->get_colormap() ->alloc_color( color_unused ) ;
}
void Frame_Resizer_Base::set_x_start( int x_start)
{
this ->X_START = x_start +10;//space for leftgripper
}
void Frame_Resizer_Base::set_x_end( int x_end )
{
this ->X_END = x_end +26 ; //space for leftgripper + 2 * BORDER
}
void Frame_Resizer_Base::set_used( int used)
{
this ->USED = used ;
}
void Frame_Resizer_Base::set_fixed_start( bool fixed_start )
{
this ->fixed_start = fixed_start ;
}
void Frame_Resizer_Base::set_used_start( int used_start )
{
if ( used_start <= 0 )
this ->USED_START = 10 ;
else
this ->USED_START = used_start +10;
}
int Frame_Resizer_Base::get_used()
{
return USED ;
}
int Frame_Resizer_Base::get_x_start()
{
return X_START -10 ;
}
int Frame_Resizer_Base::get_x_end()
{
return X_END -26 ;
}
void Frame_Resizer_Base::drawingarea_on_realize( )
{
gc = Gdk::GC::create( drawingarea .get_window() );
drawingarea .get_window() ->set_background(color_background);
drawingarea.add_events(Gdk::POINTER_MOTION_MASK );
drawingarea.add_events(Gdk::BUTTON_PRESS_MASK );
drawingarea.add_events(Gdk::BUTTON_RELEASE_MASK );
drawingarea.add_events(Gdk::LEAVE_NOTIFY_MASK );
}
bool Frame_Resizer_Base::drawingarea_on_expose( GdkEventExpose * ev )
{
Draw_Partition() ;
return true;
}
bool Frame_Resizer_Base::drawingarea_on_mouse_motion( GdkEventMotion *ev )
{
if ( ! GRIP_LEFT && ! GRIP_RIGHT && ! GRIP_MOVE ) //no need to check this while resizing or moving
{
//check if pointer is over a gripper
if ( ! fixed_start && ev ->x >= X_START -10 && ev ->x <= X_START && ev ->y >= 5 && ev ->y <= 45 ) //left grip
drawingarea .get_parent_window() ->set_cursor( *cursor_resize ) ;
else if ( ev ->x >= X_END && ev ->x <= X_END + 10 && ev ->y >= 5 && ev ->y <= 45 ) //right grip
drawingarea .get_parent_window() ->set_cursor( *cursor_resize ) ;
else if ( ! fixed_start && ev ->x >= X_START && ev ->x <= X_END ) //move grip
drawingarea .get_parent_window() ->set_cursor( *cursor_move ) ;
else //normal pointer
drawingarea .get_parent_window() ->set_cursor( *cursor_normal ) ;
}
//here's where the real work is done ;-)
if ( GRIP_LEFT || GRIP_RIGHT || GRIP_MOVE)
{
if ( GRIP_LEFT && ev ->x >= 10 && ev ->x <= X_END - USED - BORDER * 2 )
{
X_START =(int) ev -> x ;
signal_resize.emit( X_START -10, X_END -26, ARROW_LEFT) ; //-10/-26 to get the real value ( this way gripper calculations are invisible outside this class )
}
else if ( GRIP_RIGHT && ev ->x >= X_START + USED + BORDER *2 && ev ->x <= 526 )
{
X_END = (int) ev ->x ;
signal_resize.emit( X_START -10, X_END -26, ARROW_RIGHT) ; //-10/-26 to get the real value ( this way gripper calculations are invisible outside this class )
}
else if ( GRIP_MOVE )
{
temp_x = X_START + ((int) ev ->x - X_START_MOVE);
temp_y = X_END + ( (int) ev ->x - X_START_MOVE);
if ( temp_x >= 10 && temp_y <= 526 )
{
X_START = temp_x ;
X_END = temp_y ;
}
X_START_MOVE = (int) ev ->x ;
signal_move.emit( X_START -10, X_END -26) ; //-10/-26 to get the real value ( this way gripper calculations are invisible outside this class )
}
Draw_Partition() ;
}
return true;
}
bool Frame_Resizer_Base::drawingarea_on_button_press_event( GdkEventButton *ev )
{
GRIP_MOVE = false; GRIP_RIGHT = false; GRIP_LEFT = false ;
if ( ! fixed_start && ev ->x >= X_START -10 && ev ->x <= X_START && ev ->y >= 5 && ev ->y <= 45 ) //left grip
GRIP_LEFT = true ;
else if ( ev ->x >= X_END && ev ->x <= X_END + 10 && ev ->y >= 5 && ev ->y <= 45 ) //right grip
GRIP_RIGHT = true ;
else if ( ! fixed_start && ev ->x >= X_START && ev ->x <= X_END ) //move grip
{ GRIP_MOVE = true ; X_START_MOVE = (int)ev ->x; }
return true;
}
bool Frame_Resizer_Base::drawingarea_on_button_release_event( GdkEventButton *ev )
{
GRIP_LEFT = false ; GRIP_RIGHT = false ; GRIP_MOVE = false;
return true;
}
bool Frame_Resizer_Base::drawingarea_on_leave_notify( GdkEventCrossing *ev )
{
if ( ! GRIP_LEFT && ! GRIP_RIGHT && ! GRIP_MOVE && (ev ->y > 50 - BORDER || ev ->y < BORDER) )
drawingarea .get_parent_window() ->set_cursor( *cursor_normal ) ;
return true;
}
void Frame_Resizer_Base::Draw_Partition( )
{
UNUSED = X_END - X_START - BORDER * 2 - USED ;
if ( UNUSED < 0 )
UNUSED = 0 ;
drawingarea .get_window() ->clear () ;
//the two rectangles on each side of the partition
gc ->set_foreground( color_arrow_rectangle );
drawingarea .get_window() ->draw_rectangle( gc, true, 0,0,10,50 );
drawingarea .get_window() ->draw_rectangle( gc, true, 526,0,10,50 );
//partition
gc ->set_foreground( color_partition );
drawingarea .get_window() ->draw_rectangle( gc, true, X_START,0,X_END - X_START,50 );
//used
gc ->set_foreground( color_used );
drawingarea .get_window() ->draw_rectangle( gc, true, X_START + BORDER, BORDER, USED ,34 );
//unused
gc ->set_foreground( color_unused );
drawingarea .get_window() ->draw_rectangle( gc, true, X_START + BORDER +USED, BORDER, UNUSED,34 );
//resize grips
if ( ! fixed_start )
Draw_Resize_Grip( ARROW_LEFT ) ;
Draw_Resize_Grip( ARROW_RIGHT ) ;
}
void Frame_Resizer_Base::Draw_Resize_Grip( ArrowType arrow_type )
{
if ( arrow_type == ARROW_LEFT )
{
arrow_points[0] .set_x( X_START) ;
arrow_points[1] .set_x( X_START -10) ;
arrow_points[2] .set_x( X_START) ;
}
else
{
arrow_points[0] .set_x( X_END) ;
arrow_points[1] .set_x( X_END +10) ;
arrow_points[2] .set_x( X_END) ;
}
//attach resize arrows to the partition
gc ->set_foreground( color_arrow_rectangle );
if ( arrow_type == ARROW_LEFT )
drawingarea .get_window() ->draw_rectangle( gc, false, X_START -10 , 5, 9 , 40 );
else
drawingarea .get_window() ->draw_rectangle( gc, false, X_END +1, 5, 9 , 40 );
gc ->set_foreground( color_arrow );
drawingarea .get_window() ->draw_polygon( gc , true, arrow_points );
}
Frame_Resizer_Base::~Frame_Resizer_Base()
{
this ->get_colormap() ->free_colors( color_used, 1 ) ;
this ->get_colormap() ->free_colors( color_unused, 1 ) ;
this ->get_colormap() ->free_colors( color_arrow, 1 ) ;
this ->get_colormap() ->free_colors( color_background, 1 ) ;
this ->get_colormap() ->free_colors( color_partition, 1 ) ;
this ->get_colormap() ->free_colors( color_arrow_rectangle, 1 ) ;
if ( cursor_resize )
delete cursor_resize ;
if ( cursor_normal )
delete cursor_normal ;
if ( cursor_move )
delete cursor_move ;
}

View File

@ -0,0 +1,79 @@
/* Copyright (C) 2004 Bart
*
* 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 Library 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include "../include/Frame_Resizer_Extended.h"
Frame_Resizer_Extended::Frame_Resizer_Extended( )
{
}
bool Frame_Resizer_Extended::drawingarea_on_mouse_motion( GdkEventMotion *ev )
{
if ( ! GRIP_LEFT && ! GRIP_RIGHT ) //no need to check this while resizing
{
//check if pointer is over a gripper
if ( ! fixed_start && ev ->x >= X_START -10 && ev ->x <= X_START && ev ->y >= 5 && ev ->y <= 45 ) //left grip
drawingarea .get_parent_window() ->set_cursor( *cursor_resize ) ;
else if ( ev ->x >= X_END && ev ->x <= X_END + 10 && ev ->y >= 5 && ev ->y <= 45 ) //right grip
drawingarea .get_parent_window() ->set_cursor( *cursor_resize ) ;
else //normal pointer
drawingarea .get_parent_window() ->set_cursor( *cursor_normal ) ;
}
if ( GRIP_LEFT || GRIP_RIGHT )
{
if ( GRIP_LEFT && ev ->x >= 10 && ev ->x <= 510 && ev->x <= X_END - BORDER *2 && ( ev ->x <= USED_START || USED == 0 ) )
{
X_START =(int) ev -> x ;
signal_resize.emit( X_START -10, X_END -26, ARROW_LEFT) ; //-10/-26 to get the real value ( this way gripper calculations are invisible outside this class )
}
else if ( GRIP_RIGHT && ev ->x <= 526 && ev->x >= X_START + BORDER *2 && ev ->x >= USED_START + USED + BORDER *2 )
{
X_END = (int) ev ->x ;
signal_resize.emit( X_START -10, X_END -26, ARROW_RIGHT) ; //-10/-26 to get the real value ( this way gripper calculations are invisible outside this class )
}
Draw_Partition() ;
}
return true ;
}
void Frame_Resizer_Extended::Draw_Partition()
{
drawingarea .get_window() ->clear () ;
//the two rectangles on each side of the partition
gc ->set_foreground( color_arrow_rectangle );
drawingarea .get_window() ->draw_rectangle( gc, true, 0,0,10,50 );
drawingarea .get_window() ->draw_rectangle( gc, true, 526,0,10,50 );
//used
gc ->set_foreground( color_used );
drawingarea .get_window() ->draw_rectangle( gc, true, USED_START + BORDER, BORDER, USED ,34 );
//partition
gc ->set_foreground( color_partition );
for( short t=0; t<9 ;t++ )
drawingarea .get_window() ->draw_rectangle( gc, false, X_START +t,t,X_END - X_START -t*2,50 - t*2 );
//resize grips
Draw_Resize_Grip( ARROW_LEFT ) ;
Draw_Resize_Grip( ARROW_RIGHT ) ;
}

36
src/Makefile.am Normal file
View File

@ -0,0 +1,36 @@
INCLUDES =\
$(GTKMM_CFLAGS)
AM_CFLAGS =\
-Wall\
-g
AM_CXXFLAGS =\
-Wall\
-g
sbin_PROGRAMS = gparted
gparted_SOURCES = \
main.cc\
Win_GParted.cc\
TreeView_Detail.cc\
Dialog_Partition_Copy.cc\
Dialog_Partition_Info.cc\
Dialog_Partition_New.cc\
Operation.cc\
Partition.cc\
Dialog_Progress.cc\
Device.cc\
VBox_VisualDisk.cc\
Dialog_Partition_Resize_Move.cc\
Dialog_About.cc\
Frame_Resizer_Base.cc\
Frame_Resizer_Extended.cc\
Dialog_Base_Partition.cc
gparted_LDFLAGS = -lparted -lgthread-2.0
gparted_LDADD = \
$(GTKMM_LIBS)

441
src/Operation.cc Normal file
View File

@ -0,0 +1,441 @@
/* Copyright (C) 2004 Bart
*
* 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 Library 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include "../include/Operation.h"
namespace GParted
{
Operation::Operation( Device *device, Device *source_device, const Partition & partition_original , const Partition & partition_new , OperationType operationtype)
{
this->device = device;
this->device_path = device ->Get_Path() ;
//this is only used when operationtype == COPY
this->source_device = source_device;
this->source_device_path = source_device ->Get_Path() ;
this->partition_original = partition_original;
this->partition_new = partition_new;
this->operationtype = operationtype;
}
Glib::ustring Operation::Get_String()
{
std::ostringstream os;
Glib::ustring temp ;
Sector diff ;
switch ( operationtype )
{
case DELETE :
if (partition_original.type == GParted::LOGICAL)
/*TO TRANSLATORS: looks like Delete /dev/hda2 (ntfs, 2345 MB) from /dev/hda */
sprintf( c_buf, _("Delete %s (%s, %ld MB) from %s"), "Logical Partition", partition_original.filesystem.c_str(), partition_original .Get_Length_MB(), device ->Get_Path().c_str() ) ;
else
sprintf( c_buf, _("Delete %s (%s, %ld MB) from %s"), partition_original.partition .c_str(), partition_original.filesystem.c_str(), partition_original .Get_Length_MB(), device ->Get_Path().c_str() ) ;
os << c_buf ;
break;
case CREATE : switch( partition_new.type )
{
case GParted::PRIMARY : temp = "Primary"; break;
case GParted::LOGICAL : temp = "Logical"; break;
case GParted::EXTENDED : temp = "Extended"; break;
default : break;
}
/*TO TRANSLATORS: looks like Create Logical Partition #1 (ntfs, 2345 MB) on /dev/hda */
sprintf( c_buf, _("Create %s Partition #%d (%s, %ld MB) on %s"), temp .c_str(), partition_new.partition_number, partition_new.filesystem .c_str() , partition_new .Get_Length_MB(), device ->Get_Path() .c_str() ) ;
os << c_buf ;
break;
case RESIZE_MOVE : //if startsector has changed >= 1 MB we consider it a move
diff = Abs( partition_new .sector_start - partition_original .sector_start ) ;
if ( diff >= MEGABYTE )
{
if ( partition_new .sector_start > partition_original .sector_start )
sprintf( c_buf, _("Move %s up by %ld MB "), partition_new.partition .c_str(), Sector_To_MB( diff ) ) ;
else
sprintf( c_buf, _("Move %s down by %ld MB "), partition_new.partition .c_str(), Sector_To_MB( diff ) ) ;
os << c_buf ;
}
//check if size has changed ( we only consider changes >= 1 MB )
diff = Abs( (partition_original .sector_end - partition_original .sector_start) - (partition_new .sector_end - partition_new .sector_start) ) ;
if ( diff >= MEGABYTE )
{
if ( os.str() == "" )
sprintf( c_buf, _("Resize %s from %ld MB to %ld MB"), partition_new.partition .c_str(), partition_original .Get_Length_MB(), partition_new .Get_Length_MB() ) ;
else
sprintf( c_buf, _("and Resize from %ld MB to %ld MB"), partition_original .Get_Length_MB(), partition_new .Get_Length_MB() ) ;
os << c_buf ;
}
if ( os.str() == "" )
os << _("Sorry, changes are too small to make sense");
break;
case CONVERT : /*TO TRANSLATORS: looks like Convert /dev/hda4 from ntfs to linux-swap */
sprintf( c_buf, _("Convert %s from %s to %s"), partition_original .partition .c_str(), partition_original .filesystem .c_str() , partition_new .filesystem .c_str() ) ;
os << c_buf ;
break;
case COPY : /*TO TRANSLATORS: looks like Copy /dev/hda4 from /dev/hda to /dev/hdd (start at 2500 MB) */
sprintf( c_buf, _("Copy %s to %s (start at %ld MB)"), partition_new .partition .c_str(), device ->Get_Path() .c_str(), Sector_To_MB( partition_new .sector_start ) ) ;
os << c_buf ;
break ;
}
return os.str();
}
std::vector<Partition> Operation::Apply_Operation_To_Visual( std::vector<Partition> & partitions )
{
switch ( operationtype )
{
case DELETE : return Apply_Delete_To_Visual( partitions );
case CREATE : return Apply_Create_To_Visual( partitions );
case RESIZE_MOVE : return Apply_Resize_Move_To_Visual( partitions );
case CONVERT : return Apply_Convert_To_Visual( partitions ) ;
case COPY : return Apply_Create_To_Visual( partitions );
}
return partitions;
}
void Operation::Apply_To_Disk( PedTimer * timer )
{
Glib::ustring buf;
bool result; //for some weird reason it won't work otherwise .. ( this one really beats me :-S )
switch ( operationtype )
{
case DELETE : result = device ->Delete_Partition( partition_original ) ;
if ( ! result )
Show_Error( (Glib::ustring) _("Error while deleting") + " " + partition_original.partition ) ;
break;
case CREATE : result = device ->Create_Partition_With_Filesystem( partition_new, timer ) ;
if ( ! result )
Show_Error( (Glib::ustring) _("Error while creating") + " " + partition_new.partition ) ;
break;
case RESIZE_MOVE : result = device ->Move_Resize_Partition( partition_original, partition_new, timer ) ;
if ( ! result )
Show_Error( (Glib::ustring) _("Error while resizing/moving") + " " + partition_new.partition ) ;
break;
case CONVERT : result = device ->Set_Partition_Filesystem( partition_new, timer ) ;
if ( ! result )
Show_Error( (Glib::ustring) _("Error while converting filesystem of") + " " + partition_new.partition ) ;
break;
case COPY : result = device ->Copy_Partition( source_device, partition_new, timer ) ;
if ( ! result )
Show_Error( (Glib::ustring) _("Error while copying") + " " + partition_new .partition ) ;
break;
}
}
std::vector<Partition> Operation::Apply_Delete_To_Visual( std::vector<Partition> & partitions )
{
unsigned int t ;
for ( t=0;t<partitions.size();t++)
{
//since extended can only be deleted if there are no logicals left, we know for sure the next element in partitions is unallocated space
//we simply remove the extended one and set the inside_extended flag from the unallocated space to false
if (this ->partition_original.type == GParted::EXTENDED && partitions[t].type == GParted::EXTENDED )
{
partitions[t+1].inside_extended = false;
partitions.erase( partitions.begin() + t );
break;//we're done here ;-)
}
else if ( partitions[t].sector_start == this-> partition_original.sector_start )
{
partitions[t].Set_Unallocated( partition_original.sector_start , partition_original.sector_end, partition_original.inside_extended );
break;//we're done here ;-)
}
}
//if deleted partition was logical we have to decrease the partitionnumbers of the logicals with higher numbers by one (only if its a real partition)
if ( partition_original.type == GParted::LOGICAL && partition_original.partition.substr( 0, 3 ) != "New" )
for ( t=0;t<partitions.size() ;t++)
if ( partitions[t].type == GParted::LOGICAL && partitions[t].partition_number > partition_original.partition_number )
partitions[t].Update_Number( partitions[t].partition_number -1 );
//now we merge separate unallocated spaces next to each other together FIXME: more performance if we only check t -1 and t +1
for ( t=0;t<partitions.size() -1;t++)
{
if ( partitions[t].type == GParted::UNALLOCATED && partitions[t +1].type == GParted::UNALLOCATED && partitions[t].inside_extended == partitions[t +1].inside_extended )
{
partitions[t].sector_end = partitions[t+1].sector_end;
partitions.erase( partitions.begin() + t + 1 );
t--;
}
}
return partitions;
}
std::vector<Partition> Operation::Apply_Create_To_Visual( std::vector<Partition> & partitions )
{
Partition partition_temp;
//find the original partition and replace it with the new one (original "partition" is unallocated space of course)
unsigned int t;
for ( t=0;t<partitions.size() ;t++)
{
//since the stored partition_original might have been changed (e.g. deletion of virtual partition) we look for the partition which contains the
//startsector of te new one and set this partition as the original one.
if ( partition_new.sector_start >= partitions[t].sector_start && partition_new.sector_start <= partitions[t].sector_end && partitions[t].type != GParted::EXTENDED )
{
partition_original = partitions[t] ;
partitions.erase( partitions.begin() + t );
partitions.insert( partitions.begin() + t, partition_new );
break;
}
}
//check borders and create new elements if necessary
//BEFORE new partition
if ( (partition_new.sector_start - partition_original.sector_start) >= MEGABYTE ) //at least 1 MB between begin new partition and begin original one
{
partition_temp.Set_Unallocated( partition_original.sector_start, partition_new.sector_start -1 , partition_new.inside_extended );
partitions.insert( partitions.begin() + t, partition_temp );
t++;
}
//AFTER new partition
if ( ( partition_original.sector_end - partition_new.sector_end) >= MEGABYTE ) //at least 1 MB between end new partition and end original one
{
partition_temp.Set_Unallocated( partition_new.sector_end +1, partition_original.sector_end ,partition_new.inside_extended );
partitions.insert( partitions.begin() + t +1, partition_temp );
}
//if new created partition is an extended partition, we need to add unallocated space of the same size to the list
if ( partition_new.type == GParted::EXTENDED )
{
partition_temp.Set_Unallocated( partition_new.sector_start, partition_new.sector_end , true );
partitions.insert( partitions.begin() + t +1, partition_temp );
}
//set proper name for partition if COPY
if ( operationtype == GParted::COPY )
partitions[ t ] .partition = "copy from " + partitions[ t ] .partition ;
return partitions;
}
std::vector<Partition> Operation::Apply_Resize_Move_To_Visual( std::vector<Partition> & partitions)
{
//extended handling is so different i decided to take it apart from normal handling
if ( partition_original.type == GParted::EXTENDED )
return Apply_Resize_Move_Extended_To_Visual( partitions ) ;
//normal partitions ( Primary and Logical )
Partition partition_temp;
unsigned int t;
for ( t=0;t<partitions.size() ;t++)
{
//since the stored partition_original might have been changed (e.g. deletion of virtual partition) we look for the partition which contains the
//startsector of the original one
if ( partition_original.sector_start >= partitions[t].sector_start && partition_original.sector_start <= partitions[t].sector_end && partitions[t].type != GParted::EXTENDED )
{
partition_original = partitions[t] ;
partitions[t].sector_start = partition_new.sector_start ;
partitions[t].sector_end = partition_new.sector_end ;
partitions[t].sectors_unused = partition_new.sectors_unused ;
break;
}
}
//determine correct perimeters of moving/resizing space
Sector START = partition_original.sector_start ;
Sector END = partition_original.sector_end ;
//now we have the index of the original partition we can remove the surrounding partitions ( if UNALLOCATED and inside_extended is the same )
if ( t > 0 && partitions[t -1].type == GParted::UNALLOCATED && partitions[t -1].inside_extended == partition_new.inside_extended )
{
START = partitions[t -1] .sector_start ;
partitions.erase( partitions.begin() + t -1 );
t-- ;
}
if ( t +1 < partitions.size() && partitions[t +1].type == GParted::UNALLOCATED && partitions[t +1].inside_extended == partition_new.inside_extended)
{
END = partitions[t +1] .sector_end ;
partitions.erase( partitions.begin() + t +1 );
}
//now look for unallocated space > 1 MB and add to the list
if ( (partition_new.sector_start - START) >= MEGABYTE )
{
partition_temp.Set_Unallocated( START, partition_new.sector_start -1 , partition_new.inside_extended );
partitions.insert( partitions.begin() + t , partition_temp );
t++;
}
if ( (END - partition_new.sector_end) >= MEGABYTE )
{
partition_temp.Set_Unallocated( partition_new.sector_end +1, END , partition_new.inside_extended );
partitions.insert( partitions.begin() + t +1, partition_temp );
}
return partitions;
}
std::vector<Partition> Operation::Apply_Resize_Move_Extended_To_Visual( std::vector<Partition> & partitions )
{//WOW! look at this crap! there has to be an easier way to accomplish the same. When it's a bit cooler ( its over 30 C here ) i'll look into it :^)
unsigned int t;
Partition partition_temp;
//look for index of partition
for ( t=0;t<partitions.size() ;t++)
{
if ( partitions[t].type == GParted::EXTENDED )
{
partition_original = partitions[t] ;
partitions[t].sector_start = partition_new.sector_start ;
partitions[t].sector_end = partition_new.sector_end ;
break;
}
}
//now check t -1
//remove if unallocated
if ( t > 0 && partitions[ t -1 ].type == GParted::UNALLOCATED )
{
partitions.erase( partitions.begin() + t -1 );
t-- ;
}
//make spaces >= 1 MB unallocated
if ( t > 0 && ( partitions[ t ] .sector_start - partitions[ t -1 ] .sector_end ) >= MEGABYTE )
{
partition_temp.Set_Unallocated( partitions[ t -1 ] .sector_end +1, partitions[ t ] .sector_start -1 ,false );
partitions.insert( partitions.begin() + t , partition_temp );
t++ ;
}
else if ( t == 0 && partitions[ t ] .sector_start >= MEGABYTE )
{
partition_temp.Set_Unallocated( 0, partitions[ t ] .sector_start -1 ,false );
partitions.insert( partitions.begin() + t , partition_temp );
t++ ;
}
//now check t +1
if ( t +1 < partitions.size() && partitions[ t +1 ].type == GParted::UNALLOCATED )
partitions.erase( partitions.begin() + t +1 );
//make spaces >= 1 MB unallocated
if ( t+1 < partitions.size() && partitions[ t +1 ].inside_extended && (partitions[ t +1 ] .sector_start - partitions[ t ] .sector_start) >= MEGABYTE )
{
partition_temp.Set_Unallocated( partitions[ t ] .sector_start, partitions[ t +1 ] .sector_start -1 , true );
partitions.insert( partitions.begin() + t +1 , partition_temp );
}
//nothing inside extended, so we can add an unallocated with the size of extended( which is always >= 1 MB )
else if ( t +1 >= partitions.size() || ! partitions[ t +1 ].inside_extended )
{
partition_temp.Set_Unallocated( partitions[ t ] .sector_start, partitions[ t ] .sector_end , true );
partitions.insert( partitions.begin() + t +1 , partition_temp );
}
// now we look to the other side of the extended partition..
//find index of last partition that is still inside extended
t++ ; //set index to first logical
while ( t +1 < partitions.size() && partitions[ t +1 ].inside_extended )
t++ ;
//if this is unallocated space we remove it
if ( partitions[ t ].type == GParted::UNALLOCATED && partitions[ t -1 ].type != GParted::EXTENDED ) //in case there is only unallocated inside extended
{
partitions.erase( partitions.begin() + t );
t-- ;
}
//decide if we have to insert new unallocated space
if ( (partition_new .sector_end - partitions[ t ] .sector_end) >= MEGABYTE )
{
partition_temp.Set_Unallocated( partitions[ t ] .sector_end +1, partition_new .sector_end , true );
partitions.insert( partitions.begin() + t +1 , partition_temp );
t++ ;
}
//and the last step ( pfieuw ;) ) checks on first partition outside extended
if ( t +1 < partitions.size() && partitions[ t +1 ].type == GParted::UNALLOCATED )
partitions.erase( partitions.begin() + t +1 );
if ( t +1 < partitions.size() && (partitions[ t +1 ] .sector_start - partition_new.sector_end) >= MEGABYTE )
{
partition_temp.Set_Unallocated( partition_new .sector_end +1, partitions[ t +1 ] .sector_start -1 , false );
partitions.insert( partitions.begin() + t +1 , partition_temp );
}
//nothing after extended
else if ( t +1 >= partitions.size() && ( device ->Get_Length() - partition_new .sector_end) >= MEGABYTE )
{
partition_temp.Set_Unallocated( partition_new .sector_end +1, device ->Get_Length() -1 , false );
partitions.insert( partitions.begin() + t +1 , partition_temp );
}
return partitions ;
}
std::vector<Partition> Operation::Apply_Convert_To_Visual( std::vector<Partition> & partitions )
{
for ( unsigned int t=0;t<partitions.size() ;t++)
{
//since the stored partition_original might have been changed (e.g. deletion of virtual partition) we look for the partition which contains the
//startsector of the original one
if ( partition_original.sector_start >= partitions[t].sector_start && partition_original.sector_start <= partitions[t].sector_end && partitions[t].type != GParted::EXTENDED )
{
partitions[ t ] = partition_new ;
break;
}
}
return partitions;
}
void Operation::Show_Error( const Glib::ustring & message )
{
Gtk::MessageDialog dialog( "<span weight=\"bold\" size=\"larger\">" + message + "</span>\n\n" + _( "Be aware that the failure to apply this operation could affect other operations on the list." ) ,true, Gtk::MESSAGE_ERROR, Gtk::BUTTONS_OK, true);
gdk_threads_enter();
dialog .run();
gdk_threads_leave();
}
} //GParted

118
src/Partition.cc Normal file
View File

@ -0,0 +1,118 @@
/* Copyright (C) 2004 Bart
*
* 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 Library 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include "../include/Partition.h"
namespace GParted
{
Partition::Partition( )
{
this ->error = ""; //just to be sure...
}
void Partition::Set( const Glib::ustring & partition,
const int partition_number,
const PartitionType type,
const Glib::ustring & filesystem,
const Sector & sector_start,
const Sector & sector_end,
const Sector & sectors_used,
const bool inside_extended,
const bool busy )
{
this->partition = partition;
this->partition_number = partition_number;
this->type = type;
this->filesystem = filesystem;
this->sector_start = sector_start;
this->sector_end = sector_end;
this->sectors_used = sectors_used;
sectors_used != -1 ? this->sectors_unused = ( sector_end - sector_start) - sectors_used : this->sectors_unused = -1 ;
this->color.set( Get_Color( filesystem ) );
this->color_string = Get_Color( filesystem );
this->inside_extended = inside_extended;
this->busy = busy;
}
void Partition::Set_Unallocated( Sector sector_start, Sector sector_end, bool inside_extended )
{
this ->Set( "Unallocated", -1, GParted::UNALLOCATED, "unallocated", sector_start, sector_end , -1, inside_extended, false);
this ->error = "" ;this ->flags = "" ;
}
Glib::ustring Partition::Get_Color( const Glib::ustring & filesystem )
{ // very ugly, but somehow i can't figure out a more efficient way. must be lack of sleep or so... :-)
//purple teints
if ( filesystem == "ext2" ) return "purple" ;
else if ( filesystem == "ext3" ) return "#C994EB";
//brown
else if ( filesystem == "linux-swap" ) return "brown" ;
//greenisch stuff..
else if ( filesystem == "fat16" ) return "green" ;
else if ( filesystem == "fat32" ) return "#18D918";
else if ( filesystem == "ntfs" ) return "#42E5AC";
//blue
else if ( filesystem == "reiserfs" ) return "blue" ;
//libparted can only detect these, i decided to "yellow them" :^)
else if ( filesystem == "HFS" ) return "yellow" ;
else if ( filesystem == "JFS" ) return "yellow" ;
else if ( filesystem == "UFS" ) return "yellow" ;
else if ( filesystem == "XFS" ) return "yellow" ;
//darkgrey and ligthblue
else if ( filesystem == "unallocated" ) return "darkgrey" ;
else if ( filesystem == "extended" ) return "#7DFCFE" ;
//unknown filesystem ( damaged, or simply unknown )
else return "black";
}
void Partition::Update_Number( int new_number )
{ //of course this fails when we have devicenames with numbers over 99
partition_number >= 10 ? partition = partition.substr( 0, partition.length() - 2 ) : partition = partition.substr( 0, partition.length() - 1 ) ;
partition_number = new_number;
std::ostringstream os;
os << new_number;
partition += os.str();
}
long Partition::Get_Length_MB( )
{
return Sector_To_MB( this ->sector_end - this ->sector_start) ;
}
long Partition::Get_Used_MB( )
{
return Sector_To_MB( this ->sectors_used) ;
}
long Partition::Get_Unused_MB( )
{
return Get_Length_MB( ) - Get_Used_MB( ) ;
}
Partition::~Partition( )
{
}
} //GParted

162
src/TreeView_Detail.cc Normal file
View File

@ -0,0 +1,162 @@
/* Copyright (C) 2004 Bart
*
* 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 Library 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include "../include/TreeView_Detail.h"
namespace GParted
{
TreeView_Detail::TreeView_Detail( )
{
//set locale for this stream to standard. this prevent weird locals from f*ucking up my conversions :^)
os.imbue(std::locale(""));
treestore_detail = Gtk::TreeStore::create( treeview_detail_columns );
this->set_model( treestore_detail );
this->set_rules_hint(true);
this->treeselection = this->get_selection();
//append columns
this->append_column( _("Partition"), treeview_detail_columns.partition );
this->append_column( _("Type"), treeview_detail_columns.type );
this->append_column( (Glib::ustring) _("Size") + "(MB)", treeview_detail_columns.size );
this->append_column( (Glib::ustring) _("Used") + "(MB)", treeview_detail_columns.used );
this->append_column( (Glib::ustring) _("Unused") + "(MB)", treeview_detail_columns.unused );
this->append_column( _("Flags"), treeview_detail_columns.flags );
//status_icon
this->get_column( 0 ) ->pack_start( treeview_detail_columns.status_icon,false );
//colored text in Partition column (used for darkgrey unallocated)
Gtk::CellRendererText *cell_renderer_text = dynamic_cast<Gtk::CellRendererText*>( this->get_column( 0 ) ->get_first_cell_renderer() );
this->get_column( 0 ) ->add_attribute(cell_renderer_text->property_foreground(), treeview_detail_columns.text_color);
//colored text in Type column
cell_renderer_text = dynamic_cast<Gtk::CellRendererText*>( this->get_column( 1 ) ->get_first_cell_renderer() );
this->get_column( 1 ) ->add_attribute(cell_renderer_text->property_foreground(), treeview_detail_columns.color);
//set alignment of numeric columns to right
for( short t=2;t<5;t++)
{
cell_renderer_text = dynamic_cast<Gtk::CellRendererText*>( this->get_column( t ) ->get_first_cell_renderer() );
cell_renderer_text->property_xalign () = 1;
}
}
void TreeView_Detail::Load_Partitions( std::vector<Partition> & partitions )
{
treestore_detail ->clear() ;
for ( unsigned int i=0;i<partitions.size();i++ )
{
if ( ! partitions[ i ] .inside_extended )
{
row = *(treestore_detail->append());
Create_Row( row, partitions[i] );
}
else if ( partitions[ i ] .inside_extended )
{
childrow = *(treestore_detail->append( row.children() ));
Create_Row( childrow, partitions[i] );
}
}
//show logical partitions ( if any )
this->expand_all();
}
void TreeView_Detail::Set_Selected( const Partition & partition )
{
//look for appropiate row
for(iter = treestore_detail->children().begin();iter!=treestore_detail->children().end();iter++ )
{
row = *iter;
partition_temp = row[treeview_detail_columns.partition_struct] ;
//primary's
if ( partition .sector_start >= partition_temp .sector_start && partition .sector_end <=partition_temp .sector_end && partition.inside_extended == partition_temp.inside_extended )
{ this->set_cursor( (Gtk::TreePath) row); return; }
//logicals
if ( row.children().size() > 0 ) //this is the row with the extended partition, search it's childrows...
{
for(iter_child = row.children().begin();iter_child != row.children().end();iter_child++ )
{
childrow = *iter_child;
partition_temp = childrow[treeview_detail_columns.partition_struct] ;
if ( partition .sector_start >= partition_temp .sector_start && partition .sector_end <= partition_temp.sector_end )
{
this->expand_all();
this->set_cursor( (Gtk::TreePath) childrow);
return;
}
}
}
}
}
void TreeView_Detail::Create_Row( const Gtk::TreeRow & treerow, Partition & partition )
{
//hereby i assume these 2 are mutual exclusive. is this wise?? Time (and bugreports) will tell :)
if ( partition.busy )
treerow[treeview_detail_columns.status_icon] = render_icon(Gtk::Stock::DIALOG_AUTHENTICATION, Gtk::ICON_SIZE_BUTTON);
else if ( partition.filesystem == "unknown" || partition .error != "" )
treerow[treeview_detail_columns.status_icon] = render_icon(Gtk::Stock::DIALOG_WARNING, Gtk::ICON_SIZE_BUTTON);
treerow[treeview_detail_columns.partition] = partition.partition;
treerow[treeview_detail_columns.color] = partition.color_string;
partition .type == GParted::UNALLOCATED ? treerow[treeview_detail_columns.text_color] = "darkgrey" : treerow[treeview_detail_columns.text_color] = "black" ;
treerow[treeview_detail_columns.type] = partition.filesystem;
os << partition .Get_Length_MB() ;
treerow[treeview_detail_columns.size] = os.str() ; os.str("");
partition.sectors_used != -1 ? os << partition .Get_Used_MB() : os << "---" ;
treerow[treeview_detail_columns.used] = os.str() ; os.str("") ;
partition.sectors_unused != -1 ? os << partition .Get_Unused_MB() : os << "---" ;
treerow[treeview_detail_columns.unused] = os.str() ; os.str("") ;
treerow[treeview_detail_columns.flags] = " " + partition .flags ;
treerow[treeview_detail_columns.partition_struct] = partition;
}
bool TreeView_Detail::on_button_press_event(GdkEventButton* event)
{
//Call base class, to allow normal handling,
//such as allowing the row to be selected by the right-click:
bool return_value = TreeView::on_button_press_event(event);
iter = treeselection->get_selected();
if ( *iter != 0 )
{
row = *iter;
signal_mouse_click.emit( event, row[treeview_detail_columns.partition_struct] );
}
return return_value;
}
} //GParted

318
src/VBox_VisualDisk.cc Normal file
View File

@ -0,0 +1,318 @@
/* Copyright (C) 2004 Bart
*
* 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 Library 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include "../include/VBox_VisualDisk.h"
namespace GParted
{
VBox_VisualDisk::VBox_VisualDisk( const std::vector<Partition> & partitions, const Sector device_length)
{
this ->partitions = partitions ;
this ->device_length = device_length ;
selected_partition = -1;
//set locale for this stream to standard. this prevent weird locals from f*cking up my conversions :^)
os.imbue(std::locale(""));
//create frame which contains the visual disk
frame_disk_legend = manage( new Gtk::Frame() ) ;
frame_disk_legend ->set_shadow_type(Gtk::SHADOW_ETCHED_OUT);
frame_disk_legend ->set_border_width( 5 );
hbox_disk_main.pack_start( *frame_disk_legend, Gtk::PACK_EXPAND_PADDING );
hbox_disk = NULL ;
hbox_extended = NULL ;
this->set_border_width( 10 );
this->set_spacing( 8 );
this->pack_start( hbox_disk_main, Gtk::PACK_SHRINK );
//set and allocated some standard colors
color_used.set( "#F8F8BA" ); this ->get_colormap() ->alloc_color( color_used ) ;//bleach yellow ;)
color_unused.set( "white" ); this ->get_colormap() ->alloc_color( color_unused ) ;
color_text.set( "black" ); this ->get_colormap() ->alloc_color( color_text ) ;
//since disksegments have minimal sizes ( unallocated 15 and partitions 20 pixels ) i do some checking to prevent the visual disk from growing to much
Sector sectors_per_pixel = Round( (double) device_length / 750 ) ;
double width, extra_pixels = 0 ;
for ( unsigned int t=0; t<partitions.size() ; t++ )
{
width = (double) (partitions[ t ].sector_end - partitions[ t ].sector_start) / sectors_per_pixel ;
if ( (partitions[ t ] .type == GParted::PRIMARY || partitions[ t ] .type == GParted::LOGICAL) && width < 20 )
extra_pixels += (20 - width) ;
else if ( partitions[ t ] .type == GParted::UNALLOCATED && width < 15 )
extra_pixels += (15 - width) ;
}
//draw visual disk and its legend
Build_Visual_Disk( 750 - Round( extra_pixels ) ) ;
Build_Legend( ) ;
}
void VBox_VisualDisk::Build_Visual_Disk( int SCREEN_WIDTH )
{
//since there is a 5 pixel space between every partition.... ( extended adds 2 *5 more, but that doesn't matter that much.
//NOTE that a part < 20 will also grow to 20, so length in pixels may vary across different devices..
SCREEN_WIDTH -= ( (partitions.size() -1) *5 ) ;
//create hbox_disk and add to frame
hbox_disk = manage( new Gtk::HBox() ) ;
hbox_disk ->set_spacing( 5 );
frame_disk_legend ->add ( *hbox_disk );
//walk through all partitions....
int x,y;//for pango_layout check
for ( unsigned int i=0;i<partitions.size();i++ )
{
visual_partition = new Visual_Partition() ;
visual_partitions.push_back( visual_partition ) ;
visual_partitions.back() ->index = i ;
visual_partitions.back() ->sector_start = partitions[i].sector_start ;
if ( partitions[i].type == GParted::EXTENDED )
{
visual_partitions.back() ->drawingarea = NULL ;//it's just a dummy ;-) ( see Set_Selected() )
visual_partitions.back() ->length = 0 ; //keeps total_length clean
eventbox_extended = manage( new Gtk::EventBox() ) ;
eventbox_extended ->set_size_request( -1 , 60 );
eventbox_extended ->modify_bg( eventbox_extended ->get_state(), partitions[i].color );
hbox_disk ->pack_start( *eventbox_extended, Gtk::PACK_SHRINK ) ;
hbox_extended = manage( new Gtk::HBox() ) ;
hbox_extended ->set_border_width( 5 );
hbox_extended ->set_spacing( 5 );
eventbox_extended ->add( *hbox_extended ) ;
continue;
}
visual_partitions.back() ->length = (int) (SCREEN_WIDTH / (double) ( device_length / (double) ( partitions[i].sector_end - partitions[i].sector_start) ) );
if ( visual_partitions.back() ->length < 20 )//we need a min. size. Otherwise some small partitions wouldn't be visible
partitions[i].type == GParted::UNALLOCATED ? visual_partitions.back() ->length = 15 : visual_partitions.back() ->length = 20 ;
if ( partitions[i].inside_extended )
{ visual_partitions.back() ->height = 34 ; visual_partitions.back() ->text_y = 10 ; }
else
{ visual_partitions.back() ->height = 44 ;visual_partitions.back() ->text_y = 15 ; }
if ( partitions[i].type == GParted::UNALLOCATED )
visual_partitions.back() ->used = -1;
else
visual_partitions.back() ->used = (int) ( (visual_partitions.back() ->length - (BORDER *2)) / (double) ( ( partitions[i].sector_end - partitions[i].sector_start) / (double)partitions[i].sectors_used ) ) ;
visual_partitions.back() ->color_fs = partitions[i].color;
this ->get_colormap() ->alloc_color(visual_partitions.back() ->color_fs);
visual_partitions.back() ->drawingarea = manage( new Gtk::DrawingArea() ) ;
visual_partitions.back() ->drawingarea ->set_size_request( visual_partitions.back() ->length+1 ,60 );
visual_partitions.back() ->drawingarea ->set_events(Gdk::BUTTON_PRESS_MASK);
//connect signal handlers
visual_partitions.back() ->drawingarea ->signal_button_press_event().connect( sigc::bind<Partition>(sigc::mem_fun(*this, &VBox_VisualDisk::on_drawingarea_button_press), partitions[i] ) );
visual_partitions.back() ->drawingarea->signal_realize().connect( sigc::bind<Visual_Partition *>(sigc::mem_fun(*this, &VBox_VisualDisk::drawingarea_on_realize), visual_partitions.back() ) );
visual_partitions.back() ->drawingarea ->signal_expose_event().connect( sigc::bind<Visual_Partition *>(sigc::mem_fun(*this, &VBox_VisualDisk::drawingarea_on_expose), visual_partitions.back() ));
//create pangolayout and see if it fits in the visual partition
os << partitions[i].partition << "\n" << partitions[ i ] .Get_Length_MB() << " MB";
visual_partitions.back() ->pango_layout = visual_partitions.back() ->drawingarea ->create_pango_layout ( os.str() ) ;os.str("");
visual_partitions.back() ->pango_layout ->get_pixel_size( x, y ) ;
if ( visual_partitions.back() ->length - BORDER * 2 -2 < x )
visual_partitions.back() ->pango_layout ->set_text( "" ) ;
//tooltip
if ( partitions[i].type != GParted::UNALLOCATED )
os << partitions[i].filesystem << "\n" ;
os << partitions[ i ] .Get_Length_MB() ;
tooltips.set_tip( *(visual_partitions.back() ->drawingarea) ,partitions[i].partition + "\n" + os.str() + " MB" );os.str("");
partitions[i].inside_extended ? hbox_extended ->pack_start( *(visual_partitions.back() ->drawingarea) , Gtk::PACK_SHRINK ) : hbox_disk ->pack_start( *(visual_partitions.back() ->drawingarea) , Gtk::PACK_SHRINK ) ;
}
this ->show_all_children() ;
}
void VBox_VisualDisk::Build_Legend( )
{
//add the hboxes and frame_legenda
frame_disk_legend = manage( new Gtk::Frame() ) ;
hbox_legend_main.pack_start( *frame_disk_legend, Gtk::PACK_EXPAND_PADDING );
hbox_legend = manage( new Gtk::HBox() );
frame_disk_legend ->add( *hbox_legend ) ;
this->pack_start( hbox_legend_main );
std::vector<Glib::ustring> legende;
bool legende_allow = true, only_unallocated = true;
for ( unsigned int i=0;i<partitions.size();i++ )
{
if ( partitions[i].type != GParted::UNALLOCATED && partitions[i].type != GParted::EXTENDED )
only_unallocated = false;
//check if filesystem is already in legende
for ( unsigned int t=0;t<legende.size();t++) //not very nice, but very effective :P
if ( partitions[i].filesystem == legende[t] )
{ legende_allow = false; break; }
if ( legende_allow )
{
Add_Legend_Item( partitions[ i ] .filesystem + " " , partitions[ i ] .color ) ;
//make sure this color isn't added to the legende again.
legende.push_back( partitions[i].filesystem );
}
legende_allow = true;
}
//remove trailing whitespaces of last label_temp...
if ( label_temp )
label_temp ->set_text( label_temp ->get_text() .substr( 0, label_temp ->get_text() .length() -3) ) ;
//if there are any partitions add used/unused
if ( ! only_unallocated )
{
frame_disk_legend = manage( new Gtk::Frame() ) ;
hbox_legend_main.pack_start( *frame_disk_legend, Gtk::PACK_EXPAND_PADDING );
hbox_legend = manage( new Gtk::HBox() );
frame_disk_legend ->add( *hbox_legend );
Add_Legend_Item( " " + (Glib::ustring) _( "used" ) + "\t", color_used ) ;
Add_Legend_Item( " " + (Glib::ustring) _( "unused") + " ", color_unused ) ;
}
}
void VBox_VisualDisk::Add_Legend_Item( const Glib::ustring & filesystem, const Gdk::Color & color )
{
//the colored square
entry_temp = manage ( new Gtk::Entry() );
entry_temp->set_sensitive( false );
entry_temp->set_size_request( 15,15);
entry_temp->modify_base( entry_temp->get_state(), color );
hbox_legend ->pack_start( *entry_temp, Gtk::PACK_SHRINK );
//and the label
label_temp = manage( new Gtk::Label( " " + filesystem ) );
hbox_legend ->pack_start( *label_temp, Gtk::PACK_SHRINK );
}
void VBox_VisualDisk::Set_Selected( const Partition & partition )
{
//clean previously selected one
temp = selected_partition ;
selected_partition = -1;
if ( temp >= 0 ) //prevent segfault at firsttime selection
drawingarea_on_expose( NULL, visual_partitions[ temp ] ) ;
if ( partition.type == GParted::EXTENDED )
return; //extended can not be selected in visualdisk (yet )
//now set new selected one
for ( unsigned int t=0;t< visual_partitions.size() ; t++ )
{
if ( visual_partitions[t] ->sector_start == partition.sector_start && visual_partitions[t] ->drawingarea != NULL )
{
selected_partition = t;
drawingarea_on_expose( NULL, visual_partitions[ t ] ) ;
return;
}
}
}
void VBox_VisualDisk::drawingarea_on_realize( Visual_Partition* vp )
{
vp ->gc = Gdk::GC::create( vp ->drawingarea ->get_window() );
vp ->drawingarea ->get_window() ->set_background( vp ->color_fs );
//eventmasks necessary for tooltips
vp ->drawingarea ->add_events(Gdk::ENTER_NOTIFY_MASK );
vp ->drawingarea ->add_events(Gdk::LEAVE_NOTIFY_MASK );
}
bool VBox_VisualDisk::drawingarea_on_expose( GdkEventExpose * ev, Visual_Partition* vp )
{
vp ->drawingarea ->get_window() ->clear() ;
if ( vp ->used != -1 ) //if not unknown or unallocated
{
vp ->gc ->set_foreground( color_used );
vp ->drawingarea ->get_window() ->draw_rectangle( vp ->gc, true, BORDER,BORDER,vp ->used , vp ->height );
vp ->gc ->set_foreground( color_unused );
vp ->drawingarea ->get_window() ->draw_rectangle( vp ->gc, true, BORDER + vp ->used, BORDER, vp ->length - vp ->used - BORDER *2 , vp ->height );
}
vp ->gc ->set_foreground( color_text );
vp ->drawingarea ->get_window() ->draw_layout( vp ->gc, BORDER +2, vp ->text_y, vp ->pango_layout ) ;
//if partition is selected one..
if ( vp ->index == selected_partition )
{
vp ->gc ->set_foreground( color_used );
vp ->drawingarea ->get_window() ->draw_rectangle( vp ->gc, false, 4,4,vp ->length-8, vp ->height +8 );
}
return true;
}
bool VBox_VisualDisk::on_drawingarea_button_press( GdkEventButton *event, const Partition & partition )
{
signal_mouse_click.emit( event, partition );
return true;
}
VBox_VisualDisk::~VBox_VisualDisk()
{
for ( unsigned int t=0;t< visual_partitions.size() ; t++ )
{
this ->get_colormap() ->free_colors( visual_partitions[t] ->color_fs , 1 ) ;
delete visual_partitions[t] ;
}
visual_partitions.clear() ;
//free the allocated colors
this ->get_colormap() ->free_colors( color_used, 1 ) ;
this ->get_colormap() ->free_colors( color_unused, 1 ) ;
this ->get_colormap() ->free_colors( color_text, 1 ) ;
}
} //GParted

1064
src/Win_GParted.cc Normal file

File diff suppressed because it is too large Load Diff

39
src/main.cc Normal file
View File

@ -0,0 +1,39 @@
/* Copyright (C) 2004 Bart
*
* 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 Library 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include "../include/Win_GParted.h"
int main( int argc, char *argv[] )
{
//initialize thread system
Glib::thread_init();
Gtk::Main kit(argc, argv);
//check UID
if ( getuid() != 0 )
{
Gtk::MessageDialog dialog( "<span weight=\"bold\" size=\"larger\">" + (Glib::ustring) _( "Root privileges are required for running GParted" ) + "</span>\n\n" + (Glib::ustring) _( "Since GParted can be a weapon of mass destruction only root may run it.") ,true, Gtk::MESSAGE_ERROR, Gtk::BUTTONS_OK, true);
dialog.run();
exit( 0 );
}
GParted::Win_GParted win_gparted;
Gtk::Main::run( win_gparted );
return 0;
}