Initial import.
authorHong Jen Yee (PCMan) <pcman.tw@gmail.com>
Thu, 24 Dec 2009 17:05:56 +0000 (01:05 +0800)
committerHong Jen Yee (PCMan) <pcman.tw@gmail.com>
Thu, 24 Dec 2009 17:05:56 +0000 (01:05 +0800)
15 files changed:
AUTHORS [new file with mode: 0644]
COPYING [new file with mode: 0755]
ChangeLog [new file with mode: 0644]
INSTALL [new file with mode: 0644]
Makefile.am [new file with mode: 0644]
NEWS [new file with mode: 0644]
README [new file with mode: 0644]
autogen.sh [new file with mode: 0755]
configure.ac [new file with mode: 0644]
po/POTFILES.in [new file with mode: 0644]
src/Makefile.am [new file with mode: 0644]
src/main-win-ui.c [new file with mode: 0644]
src/main-win.c [new file with mode: 0644]
src/main-win.h [new file with mode: 0644]
src/pcmanfm.c [new file with mode: 0644]

diff --git a/AUTHORS b/AUTHORS
new file mode 100644 (file)
index 0000000..6004f28
--- /dev/null
+++ b/AUTHORS
@@ -0,0 +1,5 @@
+洪任諭 (Hong Jen Yee, aka PCMan) <pcman.tw@gmail.com>
+
+External source code taken from other projects:
+ * ExoIconView, ExoTreeView, along with the source code in src/exo:
+       os-cillation e.K, Anders Carlsson, & Benedikt Meurer
diff --git a/COPYING b/COPYING
new file mode 100755 (executable)
index 0000000..623b625
--- /dev/null
+++ b/COPYING
@@ -0,0 +1,340 @@
+                   GNU GENERAL PUBLIC LICENSE
+                      Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+     51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+                           Preamble
+
+  The licenses for most software are designed to take away your
+freedom to share and change it.  By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users.  This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it.  (Some other Free Software Foundation software is covered by
+the GNU Library General Public License instead.)  You can apply it to
+your programs, too.
+
+  When we speak of free software, we are referring to freedom, not
+price.  Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+  To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+  For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have.  You must make sure that they, too, receive or can get the
+source code.  And you must show them these terms so they know their
+rights.
+
+  We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+  Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software.  If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+  Finally, any free program is threatened constantly by software
+patents.  We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary.  To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.
+\f
+                   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.)
+\f
+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.
+\f
+  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.
+\f
+  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
+\f
+           How to Apply These Terms to Your New Programs
+
+  If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+  To do so, attach the following notices to the program.  It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the program's name and a brief idea of what it does.>
+    Copyright (C) <year>  <name of author>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+    Gnomovision version 69, Copyright (C) year  name of author
+    Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+    This is free software, and you are welcome to redistribute it
+    under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License.  Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary.  Here is a sample; alter the names:
+
+  Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+  `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+  <signature of Ty Coon>, 1 April 1989
+  Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs.  If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library.  If this is what you want to do, use the GNU Library General
+Public License instead of this License.
diff --git a/ChangeLog b/ChangeLog
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/INSTALL b/INSTALL
new file mode 100644 (file)
index 0000000..2550dab
--- /dev/null
+++ b/INSTALL
@@ -0,0 +1,302 @@
+Installation Instructions
+*************************
+
+Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002, 2004, 2005,
+2006, 2007, 2008, 2009 Free Software Foundation, Inc.
+
+   This file is free documentation; the Free Software Foundation gives
+unlimited permission to copy, distribute and modify it.
+
+Basic Installation
+==================
+
+   Briefly, the shell commands `./configure; make; make install' should
+configure, build, and install this package.  The following
+more-detailed instructions are generic; see the `README' file for
+instructions specific to this package.
+
+   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, and a
+file `config.log' containing compiler output (useful mainly for
+debugging `configure').
+
+   It can also use an optional file (typically called `config.cache'
+and enabled with `--cache-file=config.cache' or simply `-C') that saves
+the results of its tests to speed up reconfiguring.  Caching is
+disabled by default to prevent problems with accidental use of stale
+cache files.
+
+   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 you are using the cache, and at
+some point `config.cache' contains results you don't want to keep, you
+may remove or edit it.
+
+   The file `configure.ac' (or `configure.in') is used to create
+`configure' by a program called `autoconf'.  You need `configure.ac' 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.
+
+     Running `configure' might take a while.  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.
+
+  6. Often, you can also type `make uninstall' to remove the installed
+     files again.
+
+Compilers and Options
+=====================
+
+   Some systems require unusual options for compilation or linking that
+the `configure' script does not know about.  Run `./configure --help'
+for details on some of the pertinent environment variables.
+
+   You can give `configure' initial values for configuration parameters
+by setting variables in the command line or in the environment.  Here
+is an example:
+
+     ./configure CC=c99 CFLAGS=-g LIBS=-lposix
+
+   *Note Defining Variables::, for more details.
+
+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 can use 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 `..'.
+
+   With a non-GNU `make', it is safer 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.
+
+   On MacOS X 10.5 and later systems, you can create libraries and
+executables that work on multiple system types--known as "fat" or
+"universal" binaries--by specifying multiple `-arch' options to the
+compiler but only a single `-arch' option to the preprocessor.  Like
+this:
+
+     ./configure CC="gcc -arch i386 -arch x86_64 -arch ppc -arch ppc64" \
+                 CXX="g++ -arch i386 -arch x86_64 -arch ppc -arch ppc64" \
+                 CPP="gcc -E" CXXCPP="g++ -E"
+
+   This is not guaranteed to produce working output in all cases, you
+may have to build one architecture at a time and combine the results
+using the `lipo' tool if you have problems.
+
+Installation Names
+==================
+
+   By default, `make install' installs the package's commands under
+`/usr/local/bin', include files under `/usr/local/include', etc.  You
+can specify an installation prefix other than `/usr/local' by giving
+`configure' the option `--prefix=PREFIX'.
+
+   You can specify separate installation prefixes for
+architecture-specific files and architecture-independent files.  If you
+pass the option `--exec-prefix=PREFIX' to `configure', the package uses
+PREFIX as the prefix for installing programs and libraries.
+Documentation and other data files still use the regular prefix.
+
+   In addition, if you use an unusual directory layout you can give
+options like `--bindir=DIR' 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.
+
+Particular systems
+==================
+
+   On HP-UX, the default C compiler is not ANSI C compatible.  If GNU
+CC is not installed, it is recommended to use the following options in
+order to use an ANSI C compiler:
+
+     ./configure CC="cc -Ae -D_XOPEN_SOURCE=500"
+
+and if that doesn't work, install pre-built binaries of GCC for HP-UX.
+
+   On OSF/1 a.k.a. Tru64, some versions of the default C compiler cannot
+parse its `<wchar.h>' header file.  The option `-nodtk' can be used as
+a workaround.  If GNU CC is not installed, it is therefore recommended
+to try
+
+     ./configure CC="cc"
+
+and if that doesn't work, try
+
+     ./configure CC="cc -nodtk"
+
+   On Solaris, don't put `/usr/ucb' early in your `PATH'.  This
+directory contains several dysfunctional programs; working variants of
+these programs are available in `/usr/bin'.  So, if you need `/usr/ucb'
+in your `PATH', put it _after_ `/usr/bin'.
+
+   On Haiku, software installed for all users goes in `/boot/common',
+not `/usr/local'.  It is recommended to use the following options:
+
+     ./configure --prefix=/boot/common
+
+Specifying the System Type
+==========================
+
+   There may be some features `configure' cannot figure out
+automatically, but needs to determine by the type of machine the package
+will run on.  Usually, assuming the package is built to be run on the
+_same_ architectures, `configure' can figure that out, but if it prints
+a message saying it cannot guess the machine type, give it the
+`--build=TYPE' option.  TYPE can either be a short name for the system
+type, such as `sun4', or a canonical name which has the form:
+
+     CPU-COMPANY-SYSTEM
+
+where SYSTEM can have one of these forms:
+
+     OS
+     KERNEL-OS
+
+   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 machine type.
+
+   If you are _building_ compiler tools for cross-compiling, you should
+use the option `--target=TYPE' to select the type of system they will
+produce code for.
+
+   If you want to _use_ a cross compiler, that generates code for a
+platform different from the build platform, you should specify the
+"host" platform (i.e., that on which the generated programs will
+eventually be run) with `--host=TYPE'.
+
+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.
+
+Defining Variables
+==================
+
+   Variables not defined in a site shell script can be set in the
+environment passed to `configure'.  However, some packages may run
+configure again during the build, and the customized values of these
+variables may be lost.  In order to avoid this problem, you should set
+them in the `configure' command line, using `VAR=value'.  For example:
+
+     ./configure CC=/usr/local2/bin/gcc
+
+causes the specified `gcc' to be used as the C compiler (unless it is
+overridden in the site shell script).
+
+Unfortunately, this technique does not work for `CONFIG_SHELL' due to
+an Autoconf bug.  Until the bug is fixed you can use this workaround:
+
+     CONFIG_SHELL=/bin/bash /bin/bash ./configure CONFIG_SHELL=/bin/bash
+
+`configure' Invocation
+======================
+
+   `configure' recognizes the following options to control how it
+operates.
+
+`--help'
+`-h'
+     Print a summary of all of the options to `configure', and exit.
+
+`--help=short'
+`--help=recursive'
+     Print a summary of the options unique to this package's
+     `configure', and exit.  The `short' variant lists options used
+     only in the top level, while the `recursive' variant lists options
+     also present in any nested packages.
+
+`--version'
+`-V'
+     Print the version of Autoconf used to generate the `configure'
+     script, and exit.
+
+`--cache-file=FILE'
+     Enable the cache: use and save the results of the tests in FILE,
+     traditionally `config.cache'.  FILE defaults to `/dev/null' to
+     disable caching.
+
+`--config-cache'
+`-C'
+     Alias for `--cache-file=config.cache'.
+
+`--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.
+
+`--prefix=DIR'
+     Use DIR as the installation prefix.  *Note Installation Names::
+     for more details, including other options available for fine-tuning
+     the installation locations.
+
+`--no-create'
+`-n'
+     Run the configure checks, but stop before creating any output
+     files.
+
+`configure' also accepts some other, not widely useful, options.  Run
+`configure --help' for more details.
+
diff --git a/Makefile.am b/Makefile.am
new file mode 100644 (file)
index 0000000..4278560
--- /dev/null
@@ -0,0 +1,6 @@
+NULL=
+
+SUBDIRS=src po
+
+EXTRA_DIST = \
+       $(NULL)
diff --git a/NEWS b/NEWS
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/README b/README
new file mode 100644 (file)
index 0000000..6c96637
--- /dev/null
+++ b/README
@@ -0,0 +1,2 @@
+Compile the program with configure option --sysconfdir=/etc
+
diff --git a/autogen.sh b/autogen.sh
new file mode 100755 (executable)
index 0000000..56a2d3e
--- /dev/null
@@ -0,0 +1,29 @@
+#! /bin/sh
+AC_VERSION=
+
+AUTOMAKE=${AUTOMAKE:-automake}
+AM_INSTALLED_VERSION=$($AUTOMAKE --version | sed -e '2,$ d' -e 's/.* \([0-9]*\.[0-9]*\).*/\1/')
+
+if [ "$AM_INSTALLED_VERSION" != "1.10" \
+    -a "$AM_INSTALLED_VERSION" != "1.11" ];then
+       echo
+       echo "You must have automake > 1.10 or 1.11 installed to compile gpicview."
+       echo "Install the appropriate package for your distribution,"
+       echo "or get the source tarball at http://ftp.gnu.org/gnu/automake/"
+       exit 1
+fi
+
+set -x
+
+if [ "x${ACLOCAL_DIR}" != "x" ]; then
+  ACLOCAL_ARG=-I ${ACLOCAL_DIR}
+fi
+
+${ACLOCAL:-aclocal$AM_VERSION} ${ACLOCAL_ARG}
+${AUTOHEADER:-autoheader$AC_VERSION} --force
+AUTOMAKE=$AUTOMAKE libtoolize -c --automake --force
+AUTOMAKE=$AUTOMAKE intltoolize -c --automake --force
+$AUTOMAKE --add-missing --copy --include-deps
+${AUTOCONF:-autoconf$AC_VERSION}
+
+rm -rf autom4te.cache
diff --git a/configure.ac b/configure.ac
new file mode 100644 (file)
index 0000000..46bdf2d
--- /dev/null
@@ -0,0 +1,89 @@
+#                                               -*- Autoconf -*-
+# Process this file with autoconf to produce a configure script.
+
+AC_PREREQ([2.63])
+AC_INIT([pcmanfm], [0.7], [http://pcmanfm.sf.net/])
+AM_INIT_AUTOMAKE([-Wall -Werror foreign])
+
+AC_CONFIG_HEADERS([config.h])
+
+# Checks for programs.
+AC_ISC_POSIX
+AC_PROG_CC
+AM_PROG_LIBTOOL
+AM_PROG_CC_STDC
+AC_HEADER_STDC
+
+# Checks for header files.
+AC_HEADER_STDC
+
+# Checks for typedefs, structures, and compiler characteristics.
+
+# Checks for library functions.
+
+# Large file support
+AC_ARG_ENABLE([largefile],
+    AS_HELP_STRING([--enable-largefile],
+        [enable Large file support (default: yes)]),
+    largefile=$enableval, largefile="yes")
+
+if test x"$largefile" = x"yes"; then
+  CPPFLAGS="$CPPFLAGS -D_LARGEFILE_SOURCE -D_REENTRANT -D_FILE_OFFSET_BITS=64"
+  AC_DEFINE(_LARGEFILE64_SOURCE, 1, [Whether to enable large file support])
+  AC_DEFINE(_FILE_OFFSET_BITS, 64, [File offset bits])
+fi
+
+AC_ARG_ENABLE(
+    [cast-checks],
+    AS_HELP_STRING([--enable-cast-checks],
+                   [enable Glib casting checks (default: disable)]),
+    cast_checks=$enableval, cast_checks="no")
+G_CAST_CHECKS=""
+if test x"$cast_checks" = "xno"; then
+    G_CAST_CHECKS="-DG_DISABLE_CAST_CHECKS"
+fi
+AC_SUBST(G_CAST_CHECKS)
+
+# intltool
+IT_PROG_INTLTOOL([0.40.0])
+
+# Checks for libraries.
+gtk_modules="gtk+-2.0 >= 2.16.0"
+PKG_CHECK_MODULES(GTK, [$gtk_modules])
+AC_SUBST(GTK_CFLAGS)
+AC_SUBST(GTK_LIBS)
+
+gio_modules="gthread-2.0 gio-unix-2.0"
+PKG_CHECK_MODULES(GIO, [$gio_modules])
+AC_SUBST(GIO_CFLAGS)
+AC_SUBST(GIO_LIBS)
+
+gmodule_modules="gmodule-2.0"
+PKG_CHECK_MODULES(GMODULE, [$gmodule_modules])
+AC_SUBST(GMODULE_CFLAGS)
+AC_SUBST(GMODULE_LIBS)
+
+fm_modules="libfm"
+PKG_CHECK_MODULES(FM, [$fm_modules])
+AC_SUBST(FM_CFLAGS)
+AC_SUBST(FM_LIBS)
+
+menu_modules="libmenu-cache"
+PKG_CHECK_MODULES(MENU_CACHE, [$menu_modules])
+AC_SUBST(MENU_CACHE_CFLAGS)
+AC_SUBST(MENU_CACHE_LIBS)
+
+GETTEXT_PACKAGE=pcmanfm
+AC_SUBST(GETTEXT_PACKAGE)
+AC_DEFINE_UNQUOTED(GETTEXT_PACKAGE,"$GETTEXT_PACKAGE", [Gettext package.])
+
+AC_CONFIG_FILES([
+    Makefile
+    src/Makefile
+    po/Makefile.in
+])
+
+AC_OUTPUT
+
+echo Ready to make pcmanfm
+
diff --git a/po/POTFILES.in b/po/POTFILES.in
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/src/Makefile.am b/src/Makefile.am
new file mode 100644 (file)
index 0000000..7320e6f
--- /dev/null
@@ -0,0 +1,31 @@
+NULL=
+
+AM_CPPFLAGS = \
+       -DPACKAGE_DATA_DIR=\""$(datadir)/pcmanfm2"\" \
+       -DPACKAGE_UI_DIR=\""$(datadir)/pcmanfm2/ui"\" \
+       -DPACKAGE_LOCALE_DIR=\""$(prefix)/$(DATADIRNAME)/locale"\"
+
+bin_PROGRAMS = pcmanfm2
+
+pcmanfm2_SOURCES = \
+       pcmanfm.c \
+       main-win.c main-win.h \
+       $(NULL)
+
+pcmanfm2_CFLAGS = \
+       $(GTK_CFLAGS) \
+       $(GIO_CFLAGS) \
+       $(GMODULE_CFLAGS) \
+       $(FM_CFLAGS) \
+       $(MENU_CACHE_CFLAGS) \
+       $(G_CAST_CHECKS) \
+       -Werror-implicit-function-declaration \
+       $(NULL)
+
+pcmanfm2_LDADD = \
+       $(GTK_LIBS) \
+       $(GIO_LIBS) \
+       $(GMODULE_LIBS) \
+       $(FM_LIBS) \
+       $(MENU_CACHE_LIBS) \
+       $(NULL)
diff --git a/src/main-win-ui.c b/src/main-win-ui.c
new file mode 100644 (file)
index 0000000..2997590
--- /dev/null
@@ -0,0 +1,195 @@
+/*
+ *      main-win-ui.c
+ *      
+ *      Copyright 2009 PCMan <pcman.tw@gmail.com>
+ *      
+ *      This program is free software; you can redistribute it and/or modify
+ *      it under the terms of the GNU General Public License as published by
+ *      the Free Software Foundation; either version 2 of the License, or
+ *      (at your option) any later version.
+ *      
+ *      This program is distributed in the hope that it will be useful,
+ *      but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *      GNU General Public License for more details.
+ *      
+ *      You should have received a copy of the GNU General Public License
+ *      along with this program; if not, write to the Free Software
+ *      Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ *      MA 02110-1301, USA.
+ */
+
+/* this file is included by main-win.c */
+
+static const char main_menu_xml[] = 
+"<menubar>"
+  "<menu action='FileMenu'>"
+    "<menuitem action='New'/>"
+    "<menuitem action='NewTab'/>"
+    "<menuitem action='Close'/>"
+  "</menu>"
+  "<menu action='EditMenu'>"
+    "<menuitem action='Cut'/>"
+    "<menuitem action='Copy'/>"
+    "<menuitem action='Paste'/>"
+    "<menuitem action='Del'/>"
+    "<separator/>"
+    "<menuitem action='Rename'/>"
+    "<menuitem action='Link'/>"
+    "<menuitem action='MoveTo'/>"
+    "<menuitem action='CopyTo'/>"
+    "<separator/>"
+    "<menuitem action='SelAll'/>"
+    "<menuitem action='InvSel'/>"
+    "<separator/>"
+    "<menuitem action='Pref'/>"
+  "</menu>"
+  "<menu action='GoMenu'>"
+    "<menuitem action='Prev'/>"
+    "<menuitem action='Next'/>"
+    "<menuitem action='Up'/>"
+    "<separator/>"
+    "<menuitem action='Home'/>"
+    "<menuitem action='Desktop'/>"
+    "<menuitem action='Computer'/>"
+    "<menuitem action='Trash'/>"
+    "<menuitem action='Network'/>"
+    "<menuitem action='Apps'/>"
+  "</menu>"
+  "<menu action='BookmarksMenu'>"
+    "<menuitem action='AddBookmark'/>"
+  "</menu>"
+  "<menu action='ViewMenu'>"
+    "<menuitem action='ShowHidden'/>"
+    "<separator/>"
+    "<menuitem action='IconView'/>"
+    "<menuitem action='CompactView'/>"
+    "<menuitem action='ListView'/>"
+    "<separator/>"
+    "<menu action='Sort'>"
+      "<menuitem action='Desc'/>"
+      "<menuitem action='Asc'/>"
+      "<separator/>"
+      "<menuitem action='ByName'/>"
+      "<menuitem action='ByMTime'/>"
+    "</menu>"
+  "</menu>"
+  "<menu action='HelpMenu'>"
+    "<menuitem action='About'/>"
+  "</menu>"
+"</menubar>"
+"<toolbar>"
+    "<toolitem action='NewTab'/>"
+    "<toolitem action='Prev'/>"
+    "<toolitem action='Up'/>"
+    "<toolitem action='Home'/>"
+    "<toolitem action='Go'/>"
+"</toolbar>"
+"<popup>"
+  "<menu action='CreateNew'>"
+    "<menuitem action='NewFolder'/>"
+    "<menuitem action='NewBlank'/>"
+  "</menu>"
+  "<separator/>"
+  "<menuitem action='Paste'/>"
+  "<menu action='Sort'>"
+    "<menuitem action='Desc'/>"
+    "<menuitem action='Asc'/>"
+    "<separator/>"
+    "<menuitem action='ByName'/>"
+    "<menuitem action='ByMTime'/>"
+  "</menu>"
+  "<menuitem action='ShowHidden'/>"
+  "<separator/>"
+  "<menuitem action='Prop'/>"
+"</popup>"
+"<accelerator action='Location'/>"
+"<accelerator action='Location2'/>";
+
+static GtkActionEntry main_win_actions[]=
+{
+    {"FileMenu", NULL, N_("_File"), NULL, NULL, NULL},
+        {"New", GTK_STOCK_NEW, N_("_New Window"), "<Ctrl>N", NULL, G_CALLBACK(on_new_win)},
+        {"NewTab", GTK_STOCK_NEW, N_("New _Tab"), "<Ctrl>T", NULL, G_CALLBACK(on_new_tab)},
+        {"Close", GTK_STOCK_CLOSE, N_("_Close Window"), "<Ctrl>W", NULL, G_CALLBACK(on_close_win)},
+    {"EditMenu", NULL, N_("_Edit"), NULL, NULL, NULL},
+        {"Cut", GTK_STOCK_CUT, NULL, NULL, NULL, G_CALLBACK(on_cut)},
+        {"Copy", GTK_STOCK_COPY, NULL, NULL, NULL, G_CALLBACK(on_copy)},
+        {"Paste", GTK_STOCK_PASTE, NULL, NULL, NULL, G_CALLBACK(on_paste)},
+        {"Del", GTK_STOCK_DELETE, NULL, NULL, NULL, G_CALLBACK(on_del)},
+        {"Rename", NULL, N_("Rename"), "F2", NULL, G_CALLBACK(on_rename)},
+        {"Link", NULL, N_("Create Symlink"), NULL, NULL, NULL},
+        {"MoveTo", NULL, N_("Move To..."), NULL, NULL, G_CALLBACK(on_move_to)},
+        {"CopyTo", NULL, N_("Copy To..."), NULL, NULL, G_CALLBACK(on_copy_to)},
+        {"SelAll", GTK_STOCK_SELECT_ALL, NULL, NULL, NULL, G_CALLBACK(on_select_all)},
+        {"InvSel", NULL, N_("Invert Selection"), NULL, NULL, G_CALLBACK(on_invert_select)},
+        {"Pref", GTK_STOCK_PREFERENCES, NULL, NULL, NULL, NULL},
+    {"ViewMenu", NULL, N_("_View"), NULL, NULL, NULL},
+        {"Sort", NULL, N_("_Sort Files"), NULL, NULL, NULL},
+    {"HelpMenu", NULL, N_("_Help"), NULL, NULL, NULL},
+        {"About", GTK_STOCK_ABOUT, NULL, NULL, NULL, G_CALLBACK(on_about)},
+    {"GoMenu", NULL, N_("_Go"), NULL, NULL, NULL},
+        {"Prev", GTK_STOCK_GO_BACK, N_("Previous Folder"), "<Alt>Right", N_("Previous Folder"), G_CALLBACK(on_go_back)},
+        {"Next", GTK_STOCK_GO_FORWARD, N_("Next Folder"), "<Alt>Left", N_("Next Folder"), G_CALLBACK(on_go_forward)},
+        {"Up", GTK_STOCK_GO_UP, N_("Parent Folder"), "<Alt>Up", N_("Go to parent Folder"), G_CALLBACK(on_go_up)},
+        {"Home", "user-home", N_("Home Folder"), "<Alt>Home", N_("Home Folder"), G_CALLBACK(on_go_home)},
+        {"Desktop", "user-desktop", N_("Desktop"), NULL, N_("Desktop Folder"), G_CALLBACK(on_go_desktop)},
+        {"Computer", "computer", N_("My Computer"), NULL, NULL, G_CALLBACK(on_go_computer)},
+        {"Trash", "user-trash", N_("Trash Can"), NULL, NULL, G_CALLBACK(on_go_trash)},
+        {"Network", GTK_STOCK_NETWORK, N_("Network Drives"), NULL, NULL, G_CALLBACK(on_go_network)},
+        {"Apps", "system-software-install", N_("Applications"), NULL, N_("Installed Applications"), G_CALLBACK(on_go_apps)},
+        {"Go", GTK_STOCK_JUMP_TO, NULL, NULL, NULL, G_CALLBACK(on_go)},
+    {"BookmarksMenu", NULL, N_("_Bookmarks"), NULL, NULL, NULL},
+        {"AddBookmark", GTK_STOCK_ADD, N_("Add To Bookmarks"), NULL, N_("Add To Bookmarks"), NULL},
+    /* for accelerators */
+    {"Location", NULL, NULL, "<Alt>d", NULL, G_CALLBACK(on_location)},
+    {"Location2", NULL, NULL, "<Ctrl>L", NULL, G_CALLBACK(on_location)},
+    /* for popup menu */
+    {"CreateNew", GTK_STOCK_NEW, NULL, NULL, NULL, NULL},
+    {"NewFolder", "folder", N_("Folder"), NULL, NULL, G_CALLBACK(on_create_new)},
+    {"NewBlank", "text-x-generic", N_("Blank FIle"), NULL, NULL, G_CALLBACK(on_create_new)},
+    {"Prop", GTK_STOCK_PROPERTIES, NULL, NULL, NULL, G_CALLBACK(on_prop)}
+};
+
+static GtkToggleActionEntry main_win_toggle_actions[]=
+{
+    {"ShowHidden", NULL, N_("Show _Hidden"), "<Ctrl>H", NULL, G_CALLBACK(on_show_hidden), FALSE}
+};
+
+static GtkRadioActionEntry main_win_mode_actions[]=
+{
+    {"IconView", NULL, N_("_Icon View"), NULL, NULL, FM_FV_ICON_VIEW},
+    {"CompactView", NULL, N_("_Compact View"), NULL, NULL, FM_FV_COMPACT_VIEW},
+    {"ListView", NULL, N_("Detailed _List View"), NULL, NULL, FM_FV_LIST_VIEW},
+};
+
+static GtkRadioActionEntry main_win_sort_type_actions[]=
+{
+    {"Asc", GTK_STOCK_SORT_ASCENDING, NULL, NULL, NULL, GTK_SORT_ASCENDING},
+    {"Desc", GTK_STOCK_SORT_DESCENDING, NULL, NULL, NULL, GTK_SORT_DESCENDING},
+};
+
+static GtkRadioActionEntry main_win_sort_by_actions[]=
+{
+    {"ByName", NULL, N_("By _Name"), NULL, NULL, COL_FILE_NAME},
+    {"ByMTime", NULL, N_("By _Modification Time"), NULL, NULL, COL_FILE_MTIME}
+};
+
+
+const char folder_menu_xml[]=
+"<popup>"
+  "<placeholder name='ph1'>"
+    "<menuitem action='NewTab'/>"
+    "<menuitem action='NewWin'/>"
+    /* "<menuitem action='Search'/>" */
+  "</placeholder>"
+"</popup>";
+
+/* Action entries for pupup menus */
+static GtkActionEntry folder_menu_actions[]=
+{
+    {"NewTab", GTK_STOCK_NEW, N_("Open in New Tab"), NULL, NULL, G_CALLBACK(on_open_in_new_tab)},
+    {"NewWin", GTK_STOCK_NEW, N_("Open in New Window"), NULL, NULL, G_CALLBACK(on_open_in_new_win)},
+    {"Search", GTK_STOCK_FIND, NULL, NULL, NULL, NULL}
+};
+
diff --git a/src/main-win.c b/src/main-win.c
new file mode 100644 (file)
index 0000000..889351d
--- /dev/null
@@ -0,0 +1,934 @@
+/*
+ *      main-win.c
+ *      
+ *      Copyright 2009 PCMan <pcman.tw@gmail.com>
+ *      
+ *      This program is free software; you can redistribute it and/or modify
+ *      it under the terms of the GNU General Public License as published by
+ *      the Free Software Foundation; either version 2 of the License, or
+ *      (at your option) any later version.
+ *      
+ *      This program is distributed in the hope that it will be useful,
+ *      but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *      GNU General Public License for more details.
+ *      
+ *      You should have received a copy of the GNU General Public License
+ *      along with this program; if not, write to the Free Software
+ *      Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ *      MA 02110-1301, USA.
+ */
+
+#include <glib/gi18n.h>
+
+#include "main-win.h"
+#include <fm-gtk.h>
+
+static void fm_main_win_finalize              (GObject *object);
+G_DEFINE_TYPE(FmMainWin, fm_main_win, GTK_TYPE_WINDOW);
+
+static GtkWidget* create_tab_label(FmMainWin* win, FmPath* path, FmFolderView* view);
+static void update_tab_label(FmMainWin* win, FmFolderView* fv, const char* title);
+
+static void on_new_win(GtkAction* act, FmMainWin* win);
+static void on_new_tab(GtkAction* act, FmMainWin* win);
+static void on_close_win(GtkAction* act, FmMainWin* win);
+
+static void on_open_in_new_tab(GtkAction* act, FmMainWin* win);
+static void on_open_in_new_win(GtkAction* act, FmMainWin* win);
+
+static void on_cut(GtkAction* act, FmMainWin* win);
+static void on_copy(GtkAction* act, FmMainWin* win);
+static void on_copy_to(GtkAction* act, FmMainWin* win);
+static void on_move_to(GtkAction* act, FmMainWin* win);
+static void on_paste(GtkAction* act, FmMainWin* win);
+static void on_del(GtkAction* act, FmMainWin* win);
+static void on_rename(GtkAction* act, FmMainWin* win);
+
+static void on_select_all(GtkAction* act, FmMainWin* win);
+static void on_invert_select(GtkAction* act, FmMainWin* win);
+
+static void on_go(GtkAction* act, FmMainWin* win);
+static void on_go_back(GtkAction* act, FmMainWin* win);
+static void on_go_forward(GtkAction* act, FmMainWin* win);
+static void on_go_up(GtkAction* act, FmMainWin* win);
+static void on_go_home(GtkAction* act, FmMainWin* win);
+static void on_go_desktop(GtkAction* act, FmMainWin* win);
+static void on_go_trash(GtkAction* act, FmMainWin* win);
+static void on_go_computer(GtkAction* act, FmMainWin* win);
+static void on_go_network(GtkAction* act, FmMainWin* win);
+static void on_go_apps(GtkAction* act, FmMainWin* win);
+static void on_show_hidden(GtkToggleAction* act, FmMainWin* win);
+static void on_change_mode(GtkRadioAction* act, GtkRadioAction *cur, FmMainWin* win);
+static void on_sort_by(GtkRadioAction* act, GtkRadioAction *cur, FmMainWin* win);
+static void on_sort_type(GtkRadioAction* act, GtkRadioAction *cur, FmMainWin* win);
+static void on_about(GtkAction* act, FmMainWin* win);
+
+static void on_location(GtkAction* act, FmMainWin* win);
+
+static void on_create_new(GtkAction* action, FmMainWin* win);
+static void on_prop(GtkAction* action, FmMainWin* win);
+
+static void on_switch_page(GtkNotebook* nb, GtkNotebookPage* page, guint num, FmMainWin* win);
+
+#include "main-win-ui.c" /* ui xml definitions and actions */
+
+static guint n_wins = 0;
+
+static void fm_main_win_class_init(FmMainWinClass *klass)
+{
+    GObjectClass *g_object_class;
+    g_object_class = G_OBJECT_CLASS(klass);
+    g_object_class->finalize = fm_main_win_finalize;
+    fm_main_win_parent_class = (GtkWindowClass*)g_type_class_peek(GTK_TYPE_WINDOW);
+
+    /* special style used by close button */
+       gtk_rc_parse_string(
+               "style \"close-btn-style\" {\n"
+            "GtkWidget::focus-padding = 0\n"
+            "GtkWidget::focus-line-width = 0\n"
+            "xthickness = 0\n"
+            "ythickness = 0\n"
+               "}\n"
+               "widget \"*.close-btn\" style \"close-btn-style\""
+       );
+}
+
+static void on_entry_activate(GtkEntry* entry, FmMainWin* self)
+{
+    fm_folder_view_chdir_by_name(self->folder_view, gtk_entry_get_text(entry));
+}
+
+static void on_view_loaded( FmFolderView* view, FmPath* path, gpointer user_data) 
+{
+    FmMainWin* win = FM_MAIN_WIN(user_data);
+    fm_path_entry_set_model( win->location, view->model );
+}
+
+static void open_folder_hook(FmFileInfo* fi, gpointer user_data)
+{
+    FmMainWin* win = FM_MAIN_WIN(user_data);
+    fm_main_win_chdir(win, fi->path);
+}
+
+static void on_file_clicked(FmFolderView* fv, FmFolderViewClickType type, FmFileInfo* fi, FmMainWin* win)
+{
+    char* fpath, *uri;
+    GAppLaunchContext* ctx;
+    switch(type)
+    {
+    case FM_FV_ACTIVATED: /* file activated */
+        if(fm_file_info_is_dir(fi))
+        {
+            fm_main_win_chdir( win, fi->path);
+        }
+        else if(fi->target) /* FIXME: use accessor functions. */
+        {
+                       /* FIXME: use FmPath here. */
+            fm_main_win_chdir_by_name( win, fi->target);
+        }
+        else
+        {
+            fm_launch_file(win, NULL, fi);
+        }
+        break;
+    case FM_FV_CONTEXT_MENU:
+        if(fi)
+        {
+            FmFileMenu* menu;
+            GtkMenu* popup;
+            FmFileInfoList* files = fm_folder_view_get_selected_files(fv);
+            menu = fm_file_menu_new_for_files(files, TRUE);
+            fm_file_menu_set_folder_hook(menu, open_folder_hook, win);
+            fm_list_unref(files);
+
+            /* merge some specific menu items for folders */
+            if(fm_file_menu_is_single_file_type(menu) && fm_file_info_is_dir(fi))
+            {
+                GtkUIManager* ui = fm_file_menu_get_ui(menu);
+                GtkActionGroup* act_grp = fm_file_menu_get_action_group(menu);
+                gtk_action_group_add_actions(act_grp, folder_menu_actions, G_N_ELEMENTS(folder_menu_actions), win);
+                gtk_ui_manager_add_ui_from_string(ui, folder_menu_xml, -1, NULL);
+            }
+
+            popup = fm_file_menu_get_menu(menu);
+            gtk_menu_popup(popup, NULL, NULL, NULL, fi, 3, gtk_get_current_event_time());
+        }
+        else /* no files are selected. Show context menu of current folder. */
+        {
+            gtk_menu_popup(win->popup, NULL, NULL, NULL, NULL, 3, gtk_get_current_event_time());
+        }
+        break;
+    case FM_FV_MIDDLE_CLICK:
+        g_debug("middle click!");
+        break;
+    }
+}
+
+static void on_sel_changed(FmFolderView* fv, FmFileInfoList* files, FmMainWin* win)
+{
+       /* popup previous message if there is any */
+       gtk_statusbar_pop(win->statusbar, win->statusbar_ctx2);
+    if(files)
+    {
+        char* msg;
+        /* FIXME: display total size of all selected files. */
+        if(fm_list_get_length(files) == 1) /* only one file is selected */
+        {
+            FmFileInfo* fi = fm_list_peek_head(files);
+            const char* size_str = fm_file_info_get_disp_size(fi);
+            if(size_str)
+            {
+                msg = g_strdup_printf("\"%s\" (%s) %s", 
+                            fm_file_info_get_disp_name(fi),
+                            size_str ? size_str : "",
+                            fm_file_info_get_desc(fi));
+            }
+            else
+            {
+                msg = g_strdup_printf("\"%s\" %s", 
+                            fm_file_info_get_disp_name(fi),
+                            fm_file_info_get_desc(fi));
+            }
+        }
+        else
+            msg = g_strdup_printf("%d items selected", fm_list_get_length(files));
+        gtk_statusbar_push(win->statusbar, win->statusbar_ctx2, msg);
+        g_free(msg);
+    }
+}
+
+static void on_status(FmFolderView* fv, const char* msg, FmMainWin* win)
+{
+    gtk_statusbar_pop(win->statusbar, win->statusbar_ctx);
+    gtk_statusbar_push(win->statusbar, win->statusbar_ctx, msg);
+}
+
+static void on_bookmark(GtkMenuItem* mi, FmMainWin* win)
+{
+    FmPath* path = (FmPath*)g_object_get_data(mi, "path");
+    fm_main_win_chdir(win, path);
+}
+
+static void create_bookmarks_menu(FmMainWin* win)
+{
+    GList* l;
+    int i = 0;
+    /* FIXME: direct access to data member is not allowed */
+    for(l=win->bookmarks->items;l;l=l->next)
+    {
+        FmBookmarkItem* item = (FmBookmarkItem*)l->data;
+        GtkWidget* mi = gtk_image_menu_item_new_with_label(item->name);
+        gtk_widget_show(mi);
+        // gtk_image_menu_item_set_image(); // FIXME: set icons for menu items
+        g_object_set_data_full(mi, "path", fm_path_ref(item->path), (GDestroyNotify)fm_path_unref);
+        g_signal_connect(mi, "activate", G_CALLBACK(on_bookmark), win);
+        gtk_menu_shell_insert(win->bookmarks_menu, mi, i);
+        ++i;
+    }
+    if(i > 0)
+        gtk_menu_shell_insert(win->bookmarks_menu, gtk_separator_menu_item_new(), i);
+}
+
+static void on_bookmarks_changed(FmBookmarks* bm, FmMainWin* win)
+{
+    /* delete old items first. */
+    GList* mis = gtk_container_get_children(win->bookmarks_menu);
+    GList* l;
+    for(l = mis;l;l=l->next)
+    {
+        GtkWidget* item = (GtkWidget*)l->data;
+        if( GTK_IS_SEPARATOR_MENU_ITEM(item) )
+            break;
+        gtk_widget_destroy(item);
+    }
+    g_list_free(mis);
+
+    create_bookmarks_menu(win);
+}
+
+static void load_bookmarks(FmMainWin* win, GtkUIManager* ui)
+{
+    GtkWidget* mi = gtk_ui_manager_get_widget(ui, "/menubar/BookmarksMenu");
+    win->bookmarks_menu = gtk_menu_item_get_submenu(mi);
+    win->bookmarks = fm_bookmarks_get();
+    g_signal_connect(win->bookmarks, "changed", G_CALLBACK(on_bookmarks_changed), win);
+
+    create_bookmarks_menu(win);
+}
+
+static void on_history_item(GtkMenuItem* mi, FmMainWin* win)
+{
+    GList* l = g_object_get_data(mi, "path");
+    FmPath* path = (FmPath*)l->data;
+    fm_nav_history_jump(win->nav_history, l);
+    /* FIXME: should this be driven by signal emitted on FmNavHistory? */
+    fm_main_win_chdir_without_history(win, path);
+}
+
+static void on_show_history_menu(GtkMenuToolButton* btn, FmMainWin* win)
+{
+    GtkMenuShell* menu = (GtkMenuShell*)gtk_menu_tool_button_get_menu(btn);
+    GList *l;
+    FmPathList* nh = fm_nav_history_list(win->nav_history);
+    GList* cur = fm_nav_history_get_cur_link(win->nav_history);
+
+    /* delete old items */
+    gtk_container_foreach(menu, (GtkCallback)gtk_widget_destroy, NULL);
+
+    for(l = fm_list_peek_head_link(nh); l; l=l->next)
+    {
+        FmPath* path = (FmPath*)l->data;
+        char* str = fm_path_to_str(path);
+        GtkMenuItem* mi;
+        if( l == cur )
+        {
+            mi = gtk_check_menu_item_new_with_label(str);
+            gtk_check_menu_item_set_draw_as_radio(mi, TRUE);
+            gtk_check_menu_item_set_active(mi, TRUE);
+        }
+        else
+            mi = gtk_menu_item_new_with_label(str);
+
+        g_object_set_data_full(mi, "path", l, NULL);
+        g_signal_connect(mi, "activate", G_CALLBACK(on_history_item), win);
+        gtk_menu_shell_append(menu, mi);
+    }
+    fm_list_unref(nh);
+
+    gtk_widget_show_all( GTK_WIDGET(menu) );
+}
+
+static void fm_main_win_init(FmMainWin *self)
+{
+    GtkWidget *vbox, *menubar, *toolitem, *next_btn, *scroll;
+    GtkUIManager* ui;
+    GtkActionGroup* act_grp;
+    GtkAction* act;
+    GtkAccelGroup* accel_grp;
+
+    ++n_wins;
+
+    vbox = gtk_vbox_new(FALSE, 0);
+
+    self->hpaned = gtk_hpaned_new();
+    gtk_paned_set_position(self->hpaned, 150);
+
+    /* places left pane */
+    self->places_view = fm_places_view_new();
+    scroll = gtk_scrolled_window_new(NULL, NULL);
+    gtk_scrolled_window_set_policy(scroll, GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
+    gtk_container_add(scroll, self->places_view);
+    gtk_paned_add1(self->hpaned, scroll);
+    g_signal_connect_swapped(self->places_view, "chdir", G_CALLBACK(fm_main_win_chdir), self);
+
+    /* notebook right pane */
+    self->notebook = gtk_notebook_new();
+    gtk_notebook_set_scrollable(self->notebook, TRUE);
+    g_signal_connect(self->notebook, "switch-page", G_CALLBACK(on_switch_page), self);
+    gtk_paned_add2(self->hpaned, self->notebook);
+
+    /* create menu bar and toolbar */
+    ui = gtk_ui_manager_new();
+    act_grp = gtk_action_group_new("Main");
+    gtk_action_group_add_actions(act_grp, main_win_actions, G_N_ELEMENTS(main_win_actions), self);
+    gtk_action_group_add_toggle_actions(act_grp, main_win_toggle_actions, G_N_ELEMENTS(main_win_toggle_actions), self);
+    gtk_action_group_add_radio_actions(act_grp, main_win_mode_actions, G_N_ELEMENTS(main_win_mode_actions), FM_FV_ICON_VIEW, on_change_mode, self);
+    gtk_action_group_add_radio_actions(act_grp, main_win_sort_type_actions, G_N_ELEMENTS(main_win_sort_type_actions), GTK_SORT_ASCENDING, on_sort_type, self);
+    gtk_action_group_add_radio_actions(act_grp, main_win_sort_by_actions, G_N_ELEMENTS(main_win_sort_by_actions), 0, on_sort_by, self);
+
+    accel_grp = gtk_ui_manager_get_accel_group(ui);
+    gtk_window_add_accel_group(self, accel_grp);
+
+    gtk_ui_manager_insert_action_group(ui, act_grp, 0);
+    gtk_ui_manager_add_ui_from_string(ui, main_menu_xml, -1, NULL);
+
+    menubar = gtk_ui_manager_get_widget(ui, "/menubar");
+
+    self->toolbar = gtk_ui_manager_get_widget(ui, "/toolbar");
+    /* FIXME: should make these optional */
+    gtk_toolbar_set_icon_size(self->toolbar, GTK_ICON_SIZE_SMALL_TOOLBAR);
+    gtk_toolbar_set_style(self->toolbar, GTK_TOOLBAR_ICONS);
+
+    /* create 'Next' button manually and add a popup menu to it */
+    toolitem = g_object_new(GTK_TYPE_MENU_TOOL_BUTTON, NULL);
+    gtk_toolbar_insert(GTK_TOOLBAR(self->toolbar), toolitem, 2);
+    gtk_widget_show(GTK_WIDGET(toolitem));
+    act = gtk_ui_manager_get_action(ui, "/menubar/GoMenu/Next");
+    gtk_activatable_set_related_action(toolitem, act);
+
+    /* set up history menu */
+    self->nav_history = fm_nav_history_new();
+    self->history_menu = gtk_menu_new();
+    gtk_menu_tool_button_set_menu(toolitem, self->history_menu);
+    g_signal_connect(toolitem, "show-menu", G_CALLBACK(on_show_history_menu), self);
+
+    self->popup = gtk_ui_manager_get_widget(ui, "/popup");
+
+    gtk_box_pack_start( (GtkBox*)vbox, menubar, FALSE, TRUE, 0 );
+    gtk_box_pack_start( (GtkBox*)vbox, self->toolbar, FALSE, TRUE, 0 );
+
+    /* load bookmarks menu */
+    load_bookmarks(self, ui);
+
+    /* the location bar */
+    self->location = fm_path_entry_new();
+    g_signal_connect(self->location, "activate", on_entry_activate, self);
+
+    toolitem = gtk_tool_item_new();
+    gtk_container_add( toolitem, self->location );
+    gtk_tool_item_set_expand(toolitem, TRUE);
+    gtk_toolbar_insert((GtkToolbar*)self->toolbar, toolitem, gtk_toolbar_get_n_items(self->toolbar) - 1 );
+
+    gtk_box_pack_start( (GtkBox*)vbox, self->hpaned, TRUE, TRUE, 0 );
+
+    /* status bar */
+    self->statusbar = gtk_statusbar_new();
+    gtk_box_pack_start( (GtkBox*)vbox, self->statusbar, FALSE, TRUE, 0 );
+    self->statusbar_ctx = gtk_statusbar_get_context_id(self->statusbar, "status");
+    self->statusbar_ctx2 = gtk_statusbar_get_context_id(self->statusbar, "status2");
+
+    g_object_unref(act_grp);
+    self->ui = ui;
+
+    gtk_container_add( (GtkContainer*)self, vbox );
+    gtk_widget_show_all(vbox);
+
+    /* create new tab */
+    fm_main_win_add_tab(self, fm_path_get_home());
+    gtk_widget_grab_focus(self->folder_view);
+}
+
+
+GtkWidget* fm_main_win_new(void)
+{
+    return (GtkWidget*)g_object_new(FM_MAIN_WIN_TYPE, NULL);
+}
+
+
+static void fm_main_win_finalize(GObject *object)
+{
+    FmMainWin *self;
+
+    g_return_if_fail(object != NULL);
+    g_return_if_fail(IS_FM_MAIN_WIN(object));
+
+    --n_wins;
+
+    self = FM_MAIN_WIN(object);
+
+    g_object_unref(self->nav_history);
+    g_object_unref(self->ui);
+    g_object_unref(self->bookmarks);
+
+    if (G_OBJECT_CLASS(fm_main_win_parent_class)->finalize)
+        (* G_OBJECT_CLASS(fm_main_win_parent_class)->finalize)(object);
+
+    if(n_wins == 0)
+        gtk_main_quit();
+}
+
+void on_about(GtkAction* act, FmMainWin* win)
+{
+    const char* authors[]={"Hong Jen Yee <pcman.tw@gmail.com>", NULL};
+    GtkWidget* dlg = gtk_about_dialog_new();
+    gtk_about_dialog_set_program_name(dlg, "libfm-demo");
+    gtk_about_dialog_set_authors(dlg, authors);
+    gtk_about_dialog_set_comments(dlg, "A demo program for libfm");
+    gtk_about_dialog_set_website(dlg, "http://pcmanfm.sf.net/");
+    gtk_dialog_run(dlg);
+    gtk_widget_destroy(dlg);
+}
+
+void on_show_hidden(GtkToggleAction* act, FmMainWin* win)
+{
+    gboolean active = gtk_toggle_action_get_active(act);
+    fm_folder_view_set_show_hidden( win->folder_view, active );
+}
+
+void on_change_mode(GtkRadioAction* act, GtkRadioAction *cur, FmMainWin* win)
+{
+    int mode = gtk_radio_action_get_current_value(cur);
+    fm_folder_view_set_mode( win->folder_view, mode );
+}
+
+void on_sort_by(GtkRadioAction* act, GtkRadioAction *cur, FmMainWin* win)
+{
+    int val = gtk_radio_action_get_current_value(cur);
+    fm_folder_view_sort(win->folder_view, -1, val);
+}
+
+void on_sort_type(GtkRadioAction* act, GtkRadioAction *cur, FmMainWin* win)
+{
+    int val = gtk_radio_action_get_current_value(cur);
+    fm_folder_view_sort(win->folder_view, val, -1);
+}
+
+void on_new_win(GtkAction* act, FmMainWin* win)
+{
+    win = fm_main_win_new();
+    gtk_window_set_default_size(win, 640, 480);
+    fm_main_win_chdir(win, fm_path_get_home());
+    gtk_window_present(win);
+}
+
+void on_new_tab(GtkAction* act, FmMainWin* win)
+{
+    FmPath* path = fm_folder_view_get_cwd(win->folder_view);
+    fm_main_win_add_tab(win, path);
+}
+
+void on_close_win(GtkAction* act, FmMainWin* win)
+{
+    gtk_widget_destroy(win);
+}
+
+void on_open_in_new_tab(GtkAction* act, FmMainWin* win)
+{
+}
+
+
+void on_open_in_new_win(GtkAction* act, FmMainWin* win)
+{
+    FmPathList* sels = fm_folder_view_get_selected_file_paths(win->folder_view);
+    GList* l;
+    for( l = fm_list_peek_head_link(sels); l; l=l->next )
+    {
+        FmPath* path = (FmPath*)l->data;
+        win = fm_main_win_new();
+        gtk_window_set_default_size(win, 640, 480);
+        fm_main_win_chdir(win, path);
+        gtk_window_present(win);
+    }
+    fm_list_unref(sels);
+}
+
+
+void on_go(GtkAction* act, FmMainWin* win)
+{
+    fm_main_win_chdir_by_name( win, gtk_entry_get_text(win->location));
+}
+
+void on_go_back(GtkAction* act, FmMainWin* win)
+{
+    if(fm_nav_history_get_can_back(win->nav_history))
+    {
+        fm_nav_history_back(win->nav_history);
+        /* FIXME: should this be driven by a signal emitted on FmNavHistory? */
+        fm_main_win_chdir_without_history(win, fm_nav_history_get_cur(win->nav_history));
+    }
+}
+
+void on_go_forward(GtkAction* act, FmMainWin* win)
+{
+    if(fm_nav_history_get_can_forward(win->nav_history))
+    {
+        fm_nav_history_forward(win->nav_history);
+        /* FIXME: should this be driven by a signal emitted on FmNavHistory? */
+        fm_main_win_chdir_without_history(win, fm_nav_history_get_cur(win->nav_history));
+    }
+}
+
+void on_go_up(GtkAction* act, FmMainWin* win)
+{
+    FmPath* parent = fm_path_get_parent(fm_folder_view_get_cwd(win->folder_view));
+    if(parent)
+    {
+        fm_main_win_chdir( win, parent);
+        fm_path_unref(parent);
+    }
+}
+
+void on_go_home(GtkAction* act, FmMainWin* win)
+{
+    fm_main_win_chdir_by_name( win, g_get_home_dir());
+}
+
+void on_go_desktop(GtkAction* act, FmMainWin* win)
+{
+    fm_main_win_chdir_by_name( win, g_get_user_special_dir(G_USER_DIRECTORY_DESKTOP));
+}
+
+void on_go_trash(GtkAction* act, FmMainWin* win)
+{
+    fm_main_win_chdir_by_name( win, "trash:///");
+}
+
+void on_go_computer(GtkAction* act, FmMainWin* win)
+{
+    fm_main_win_chdir_by_name( win, "computer:///");
+}
+
+void on_go_network(GtkAction* act, FmMainWin* win)
+{
+    fm_main_win_chdir_by_name( win, "network:///");
+}
+
+void on_go_apps(GtkAction* act, FmMainWin* win)
+{
+    fm_main_win_chdir_by_name( win, "applications:///");
+}
+
+void fm_main_win_chdir_by_name(FmMainWin* win, const char* path_str)
+{
+    FmPath* path = fm_path_new(path_str);
+    fm_main_win_chdir_without_history(win, path);
+    fm_path_unref(path);
+}
+
+void fm_main_win_chdir_without_history(FmMainWin* win, FmPath* path)
+{
+    char* disp_path = fm_path_display_name(path);
+    const char* disp_name = g_utf8_strrchr(disp_path, -1, G_DIR_SEPARATOR);
+    gtk_entry_set_text(win->location, disp_path);
+
+    if(disp_name && disp_name[1])
+        ++disp_name;
+
+    update_tab_label(win, win->folder_view, disp_name);
+    gtk_window_set_title(win, disp_name);
+    g_free(disp_path);
+
+    fm_folder_view_chdir(win->folder_view, path);
+    /* fm_nav_history_set_cur(); */
+}
+
+void fm_main_win_chdir(FmMainWin* win, FmPath* path)
+{
+    fm_main_win_chdir_without_history(win, path);
+    fm_nav_history_chdir(win->nav_history, path);
+}
+
+static void close_btn_style_set(GtkWidget *btn, GtkRcStyle *prev, gpointer data)
+{
+       gint w, h;
+       gtk_icon_size_lookup_for_settings(gtk_widget_get_settings(btn), GTK_ICON_SIZE_MENU, &w, &h);
+       gtk_widget_set_size_request(btn, w + 2, h + 2);
+}
+
+static void on_close_tab(GtkButton* btn, GtkWidget* view)
+{
+    GtkNotebook* nb = GTK_NOTEBOOK(gtk_widget_get_parent(view));
+    gtk_widget_destroy(view);
+    if(gtk_notebook_get_n_pages(nb) == 0)
+    {
+        GtkWidget* main_win = gtk_widget_get_toplevel(nb);
+        gtk_widget_destroy(main_win);
+    }
+}
+
+GtkWidget* create_tab_label(FmMainWin* win, FmPath* path, FmFolderView* view)
+{
+    GtkWidget * evt_box;
+    GtkWidget* tab_label;
+    GtkWidget* tab_text;
+    GtkWidget* close_btn;
+    char* disp_name;
+    int w, h;
+
+    /* Create tab label */
+    evt_box = gtk_event_box_new();
+    gtk_event_box_set_visible_window(GTK_EVENT_BOX(evt_box), FALSE);
+
+    tab_label = gtk_hbox_new( FALSE, 0 );
+
+    disp_name = g_filename_display_name(path->name);
+    tab_text = gtk_label_new(disp_name);
+    g_free(disp_name);
+    gtk_box_pack_start(GTK_BOX(tab_label), tab_text, FALSE, FALSE, 4 );
+
+    close_btn = gtk_button_new ();
+    gtk_button_set_focus_on_click ( GTK_BUTTON ( close_btn ), FALSE );
+    gtk_button_set_relief( GTK_BUTTON ( close_btn ), GTK_RELIEF_NONE );
+    gtk_container_add ( GTK_CONTAINER ( close_btn ),
+                        gtk_image_new_from_stock(GTK_STOCK_CLOSE, GTK_ICON_SIZE_MENU));
+    gtk_container_set_border_width(close_btn, 0);
+    gtk_widget_set_name(close_btn, "close-btn");
+    g_signal_connect(close_btn, "style-set", G_CALLBACK(close_btn_style_set), NULL);
+
+    gtk_box_pack_end( GTK_BOX( tab_label ), close_btn, FALSE, FALSE, 0 );
+
+    g_signal_connect(close_btn, "clicked", G_CALLBACK(on_close_tab), view);
+
+    gtk_container_add(GTK_CONTAINER(evt_box), tab_label);
+    gtk_widget_set_events( GTK_WIDGET(evt_box), GDK_ALL_EVENTS_MASK);
+/*
+    gtk_drag_dest_set ( GTK_WIDGET( evt_box ), GTK_DEST_DEFAULT_ALL,
+                        drag_targets,
+                        sizeof( drag_targets ) / sizeof( GtkTargetEntry ),
+                        GDK_ACTION_DEFAULT | GDK_ACTION_COPY | GDK_ACTION_MOVE | GDK_ACTION_LINK );
+    g_signal_connect ( ( gpointer ) evt_box, "drag-motion",
+                       G_CALLBACK ( on_tab_drag_motion ),
+                       file_browser );
+*/
+    gtk_widget_show_all(GTK_WIDGET(evt_box));
+    return GTK_WIDGET(evt_box);
+}
+
+void update_tab_label(FmMainWin* win, FmFolderView* fv, const char* title)
+{
+    GtkWidget* tab = gtk_notebook_get_tab_label((GtkNotebook*)win->notebook, win->folder_view);
+    GtkWidget* hbox = gtk_bin_get_child((GtkBin*)tab);
+    GList* children = gtk_container_get_children(hbox);
+    GtkWidget* label = (GtkWidget*)children->data;
+    g_list_free(children);
+    gtk_label_set_text((GtkLabel*)label, title);
+}
+
+gint fm_main_win_add_tab(FmMainWin* win, FmPath* path)
+{
+    /* create label for the tab */
+    GtkWidget* label;
+    GtkWidget* folder_view;
+    gint ret;
+
+    /* create folder view */
+    folder_view = fm_folder_view_new( FM_FV_ICON_VIEW );
+    fm_folder_view_set_show_hidden(folder_view, FALSE);
+    fm_folder_view_sort(folder_view, GTK_SORT_DESCENDING, COL_FILE_NAME);
+    fm_folder_view_set_selection_mode(folder_view, GTK_SELECTION_MULTIPLE);
+    g_signal_connect(folder_view, "clicked", on_file_clicked, win);
+    g_signal_connect(folder_view, "status", on_status, win);
+    g_signal_connect(folder_view, "sel-changed", on_sel_changed, win);
+
+    fm_folder_view_chdir(folder_view, path);
+    gtk_widget_show(folder_view);
+
+    label = create_tab_label(win, path, folder_view);
+
+    ret = gtk_notebook_append_page(win->notebook, folder_view, label);
+    gtk_notebook_set_tab_reorderable(win->notebook, folder_view, TRUE);
+    gtk_notebook_set_current_page(win->notebook, ret);
+
+    /* set current folder view */
+    win->folder_view = folder_view;
+    return ret;
+}
+
+
+void on_cut(GtkAction* act, FmMainWin* win)
+{
+    GtkWidget* focus = gtk_window_get_focus((GtkWindow*)win);
+    if(GTK_IS_EDITABLE(focus) &&
+       gtk_editable_get_selection_bounds((GtkEditable*)focus, NULL, NULL) )
+    {
+        gtk_editable_cut_clipboard((GtkEditable*)focus);
+    }
+    else
+    {
+        FmPathList* files = fm_folder_view_get_selected_file_paths(win->folder_view);
+        if(files)
+        {
+            fm_clipboard_cut_files(win, files);
+            fm_list_unref(files);
+        }
+    }
+}
+
+void on_copy(GtkAction* act, FmMainWin* win)
+{
+    GtkWidget* focus = gtk_window_get_focus((GtkWindow*)win);
+    if(GTK_IS_EDITABLE(focus) &&
+       gtk_editable_get_selection_bounds((GtkEditable*)focus, NULL, NULL) )
+    {
+        gtk_editable_copy_clipboard((GtkEditable*)focus);
+    }
+    else
+    {
+        FmPathList* files = fm_folder_view_get_selected_file_paths(win->folder_view);
+        if(files)
+        {
+            fm_clipboard_copy_files(win, files);
+            fm_list_unref(files);
+        }
+    }
+}
+
+void on_copy_to(GtkAction* act, FmMainWin* win)
+{
+    FmPathList* files = fm_folder_view_get_selected_file_paths(win->folder_view);
+    if(files)
+    {
+        fm_copy_files_to(files);
+        fm_list_unref(files);
+    }
+}
+
+void on_move_to(GtkAction* act, FmMainWin* win)
+{
+    FmPathList* files = fm_folder_view_get_selected_file_paths(win->folder_view);
+    if(files)
+    {
+        fm_move_files_to(files);
+        fm_list_unref(files);
+    }
+}
+
+void on_paste(GtkAction* act, FmMainWin* win)
+{
+    GtkWidget* focus = gtk_window_get_focus((GtkWindow*)win);
+    if(GTK_IS_EDITABLE(focus) )
+    {
+        gtk_editable_paste_clipboard((GtkEditable*)focus);
+    }
+    else
+    {
+        FmPath* path = fm_folder_view_get_cwd(win->folder_view);
+        fm_clipboard_paste_files(win->folder_view, path);
+    }
+}
+
+void on_del(GtkAction* act, FmMainWin* win)
+{
+    FmPathList* files = fm_folder_view_get_selected_file_paths(win->folder_view);
+    fm_trash_or_delete_files(files);
+    fm_list_unref(files);
+}
+
+void on_rename(GtkAction* act, FmMainWin* win)
+{
+    FmPathList* files = fm_folder_view_get_selected_file_paths(win->folder_view);
+    if( !fm_list_is_empty(files) )
+    {
+        fm_rename_file(fm_list_peek_head(files));
+        /* FIXME: is it ok to only rename the first selected file here. */
+    }
+    fm_list_unref(files);
+}
+
+void on_select_all(GtkAction* act, FmMainWin* win)
+{
+    fm_folder_view_select_all(win->folder_view);
+}
+
+void on_invert_select(GtkAction* act, FmMainWin* win)
+{
+    fm_folder_view_select_invert(win->folder_view);
+}
+
+void on_location(GtkAction* act, FmMainWin* win)
+{
+    gtk_widget_grab_focus(win->location);
+}
+
+void on_prop(GtkAction* action, FmMainWin* win)
+{
+    FmFolderView* fv = FM_FOLDER_VIEW(win->folder_view);
+    /* FIXME: should prevent directly accessing data members */
+    FmFileInfo* fi = FM_FOLDER_MODEL(fv->model)->dir->dir_fi;
+    FmFileInfoList* files = fm_file_info_list_new();
+    fm_list_push_tail(files, fi);
+    fm_show_file_properties(files);
+    fm_list_unref(files);
+}
+
+void on_switch_page(GtkNotebook* nb, GtkNotebookPage* page, guint num, FmMainWin* win)
+{
+    FmFolderView* fv = FM_FOLDER_VIEW(gtk_notebook_get_nth_page(nb, num));
+
+    if(win->folder_view)
+        g_signal_handlers_disconnect_by_func(win->folder_view, on_view_loaded, win);
+    win->folder_view = fv;
+
+    if(fv)
+    {
+        FmPath* cwd = fm_folder_view_get_cwd(fv);
+
+        if(fv->model) /* FIXME: we shouldn't access private data member. */
+            fm_path_entry_set_model( win->location, fv->model );
+        g_signal_connect(fv, "loaded", G_CALLBACK(on_view_loaded), win);
+
+        if(cwd)
+        {
+            char* disp_name;
+            disp_name = g_filename_display_name(cwd->name);
+            gtk_window_set_title((GtkWindow*)win, disp_name);
+            g_free(disp_name);
+        }
+    }
+}
+
+void on_create_new(GtkAction* action, FmMainWin* win)
+{
+    FmFolderView* fv = FM_FOLDER_VIEW(win->folder_view);
+    const char* name = gtk_action_get_name(action);
+    GError* err = NULL;
+    FmPath* cwd = fm_folder_view_get_cwd(fv);
+    FmPath* dest;
+    char* basename;
+_retry:
+    basename = fm_get_user_input(win, _("Create New..."), _("Enter a name for the newly created file:"), _("New"));
+    if(!basename)
+        return;
+
+    dest = fm_path_new_child(cwd, basename);
+    g_free(basename);
+
+    if( strcmp(name, "NewFolder") == 0 )
+    {
+        GFile* gf = fm_path_to_gfile(dest);
+        if(!g_file_make_directory(gf, NULL, &err))
+        {
+            if(err->domain = G_IO_ERROR && err->code == G_IO_ERROR_EXISTS)
+            {
+                fm_path_unref(dest);
+                g_error_free(err);
+                g_object_unref(gf);
+                err = NULL;
+                goto _retry;
+            }
+            fm_show_error(win, err->message);
+            g_error_free(err);
+        }
+
+        if(!err) /* select the newly created file */
+        {
+            /*FIXME: this doesn't work since the newly created file will
+             * only be shown after file-created event was fired on its 
+             * folder's monitor and after FmFolder handles it in idle 
+             * handler. So, we cannot select it since it's not yet in 
+             * the folder model now. */
+            /* fm_folder_view_select_file_path(fv, dest); */
+        }
+        g_object_unref(gf);
+    }
+    else if( strcmp(name, "NewBlank") == 0 )
+    {
+        GFile* gf = fm_path_to_gfile(dest);
+        GFileOutputStream* f = g_file_create(gf, G_FILE_CREATE_NONE, NULL, &err);
+        if(f)
+        {
+            g_output_stream_close(f, NULL, NULL);
+            g_object_unref(f);
+        }
+        else
+        {
+            if(err->domain = G_IO_ERROR && err->code == G_IO_ERROR_EXISTS)
+            {
+                fm_path_unref(dest);
+                g_error_free(err);
+                g_object_unref(gf);
+                err = NULL;
+                goto _retry;
+            }
+            fm_show_error(win, err->message);
+            g_error_free(err);
+        }
+
+        if(!err) /* select the newly created file */
+        {
+            /*FIXME: this doesn't work since the newly created file will
+             * only be shown after file-created event was fired on its 
+             * folder's monitor and after FmFolder handles it in idle 
+             * handler. So, we cannot select it since it's not yet in 
+             * the folder model now. */
+            /* fm_folder_view_select_file_path(fv, dest); */
+        }
+        g_object_unref(gf);
+    }
+    else /* templates */
+    {
+        
+    }
+    fm_path_unref(dest);
+}
diff --git a/src/main-win.h b/src/main-win.h
new file mode 100644 (file)
index 0000000..f427300
--- /dev/null
@@ -0,0 +1,80 @@
+/*
+ *      main-win.h
+ *      
+ *      Copyright 2009 PCMan <pcman@thinkpad>
+ *      
+ *      This program is free software; you can redistribute it and/or modify
+ *      it under the terms of the GNU General Public License as published by
+ *      the Free Software Foundation; either version 2 of the License, or
+ *      (at your option) any later version.
+ *      
+ *      This program is distributed in the hope that it will be useful,
+ *      but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *      GNU General Public License for more details.
+ *      
+ *      You should have received a copy of the GNU General Public License
+ *      along with this program; if not, write to the Free Software
+ *      Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ *      MA 02110-1301, USA.
+ */
+
+
+#ifndef __MAIN_WIN_H__
+#define __MAIN_WIN_H__
+
+#include <gtk/gtk.h>
+#include <fm-gtk.h>
+
+G_BEGIN_DECLS
+
+#define FM_MAIN_WIN_TYPE                               (fm_main_win_get_type())
+#define FM_MAIN_WIN(obj)                               (G_TYPE_CHECK_INSTANCE_CAST((obj),\
+                       FM_MAIN_WIN_TYPE, FmMainWin))
+#define FM_MAIN_WIN_CLASS(klass)               (G_TYPE_CHECK_CLASS_CAST((klass),\
+                       FM_MAIN_WIN_TYPE, FmMainWinClass))
+#define IS_FM_MAIN_WIN(obj)                    (G_TYPE_CHECK_INSTANCE_TYPE((obj),\
+                       FM_MAIN_WIN_TYPE))
+#define IS_FM_MAIN_WIN_CLASS(klass)    (G_TYPE_CHECK_CLASS_TYPE((klass),\
+                       FM_MAIN_WIN_TYPE))
+
+typedef struct _FmMainWin                      FmMainWin;
+typedef struct _FmMainWinClass         FmMainWinClass;
+
+struct _FmMainWin
+{
+       GtkWindow parent;
+
+    GtkUIManager* ui;
+       GtkWidget* toolbar;
+       GtkWidget* location;
+    GtkWidget* hpaned;
+    GtkWidget* notebook;
+    GtkWidget* places_view;
+       GtkWidget* folder_view;
+       GtkWidget* statusbar;
+    GtkWidget* bookmarks_menu;
+    GtkWidget* history_menu;
+    GtkWidget* popup;
+    /* <private> */
+    FmNavHistory* nav_history;
+    guint statusbar_ctx;
+    guint statusbar_ctx2;
+    FmBookmarks* bookmarks;
+};
+
+struct _FmMainWinClass
+{
+       GtkWindowClass parent_class;
+};
+
+GType          fm_main_win_get_type            (void);
+GtkWidget*     fm_main_win_new                 (void);
+void fm_main_win_chdir(FmMainWin* win, FmPath* path);
+void fm_main_win_chdir_by_name(FmMainWin* win, const char* path_str);
+void fm_main_win_chdir_without_history(FmMainWin* win, FmPath* path);
+gint fm_main_win_add_tab(FmMainWin* win, FmPath* path);
+
+G_END_DECLS
+
+#endif /* __MAIN-WIN_H__ */
diff --git a/src/pcmanfm.c b/src/pcmanfm.c
new file mode 100644 (file)
index 0000000..69a7763
--- /dev/null
@@ -0,0 +1,52 @@
+/*
+ *      pcmanfm.c
+ *      
+ *      Copyright 2009 PCMan <pcman@thinkpad>
+ *      
+ *      This program is free software; you can redistribute it and/or modify
+ *      it under the terms of the GNU General Public License as published by
+ *      the Free Software Foundation; either version 2 of the License, or
+ *      (at your option) any later version.
+ *      
+ *      This program is distributed in the hope that it will be useful,
+ *      but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *      GNU General Public License for more details.
+ *      
+ *      You should have received a copy of the GNU General Public License
+ *      along with this program; if not, write to the Free Software
+ *      Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ *      MA 02110-1301, USA.
+ */
+
+#include <config.h>
+#include <gtk/gtk.h>
+#include <stdio.h>
+
+#include <fm-gtk.h>
+#include "main-win.h"
+
+int main(int argc, char** argv)
+{
+       GtkWidget* w;
+       gtk_init(&argc, &argv);
+
+       fm_gtk_init(NULL);
+
+       w = fm_main_win_new();
+       gtk_window_set_default_size(w, 640, 480);
+       gtk_widget_show(w);
+
+    if(argc > 1)
+    {
+        FmPath* path = fm_path_new(argv[1]);
+        fm_main_win_chdir(w, path);
+        fm_path_unref(path);
+    }
+       
+       gtk_main();
+
+    fm_finalize();
+
+       return 0;
+}