"Fossies" - the Fresh Open Source Software Archive

Member "google-gadgets-for-linux-0.11.2/hosts/gtk/standalone_gtk_host.cc" (28 Dec 2009, 12998 Bytes) of package /linux/misc/old/google-gadgets-for-linux-0.11.2.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file.

    1 /*
    2   Copyright 2008 Google Inc.
    3 
    4   Licensed under the Apache License, Version 2.0 (the "License");
    5   you may not use this file except in compliance with the License.
    6   You may obtain a copy of the License at
    7 
    8        http://www.apache.org/licenses/LICENSE-2.0
    9 
   10   Unless required by applicable law or agreed to in writing, software
   11   distributed under the License is distributed on an "AS IS" BASIS,
   12   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   13   See the License for the specific language governing permissions and
   14   limitations under the License.
   15 */
   16 
   17 #include <gtk/gtk.h>
   18 #include <string>
   19 
   20 #include "standalone_gtk_host.h"
   21 
   22 #include <ggadget/common.h>
   23 #include <ggadget/decorated_view_host.h>
   24 #include <ggadget/floating_main_view_decorator.h>
   25 #include <ggadget/popout_main_view_decorator.h>
   26 #include <ggadget/details_view_decorator.h>
   27 #include <ggadget/gadget.h>
   28 #include <ggadget/gadget_consts.h>
   29 #include <ggadget/gadget_manager_interface.h>
   30 #include <ggadget/gtk/menu_builder.h>
   31 #include <ggadget/gtk/single_view_host.h>
   32 #include <ggadget/gtk/utilities.h>
   33 #include <ggadget/gtk/hotkey.h>
   34 #include <ggadget/locales.h>
   35 #include <ggadget/messages.h>
   36 #include <ggadget/logger.h>
   37 #include <ggadget/script_runtime_manager.h>
   38 #include <ggadget/view.h>
   39 #include <ggadget/main_loop_interface.h>
   40 #include <ggadget/file_manager_factory.h>
   41 #include <ggadget/options_interface.h>
   42 #include <ggadget/string_utils.h>
   43 #include <ggadget/permissions.h>
   44 #include <ggadget/digest_utils.h>
   45 
   46 using namespace ggadget;
   47 using namespace ggadget::gtk;
   48 
   49 namespace hosts {
   50 namespace gtk {
   51 
   52 static const char kPermissionConfirmedOption[] = "permission_confirmed";
   53 
   54 class StandaloneGtkHost::Impl {
   55  public:
   56   Impl(StandaloneGtkHost *owner, int flags, int view_debug_mode,
   57        Gadget::DebugConsoleConfig debug_console_config)
   58     : owner_(owner),
   59       gadget_(NULL),
   60       main_view_host_(NULL),
   61       details_view_host_(NULL),
   62       debug_console_(NULL),
   63       details_on_right_(false),
   64       safe_to_exit_(true),
   65       flags_(flags),
   66       view_debug_mode_(view_debug_mode),
   67       debug_console_config_(debug_console_config) {
   68   }
   69 
   70   ~Impl() {
   71     if (debug_console_)
   72       gtk_widget_destroy(debug_console_);
   73     delete gadget_;
   74   }
   75 
   76   bool InitFailed(const std::string &gadget_path) {
   77     safe_to_exit_ = false;
   78     ShowAlertDialog(GM_("GOOGLE_GADGETS"),
   79                     StringPrintf(GM_("GADGET_LOAD_FAILURE"),
   80                                  gadget_path.c_str()).c_str());
   81     safe_to_exit_ = true;
   82     owner_->Exit();
   83     return false;
   84   }
   85 
   86   bool Init(const std::string &gadget_path) {
   87     StringMap manifest;
   88     if (!Gadget::GetGadgetManifest(gadget_path.c_str(), &manifest)) {
   89       return InitFailed(gadget_path);
   90     }
   91 
   92     StringMap::const_iterator id_it = manifest.find(kManifestId);
   93     if (id_it == manifest.end() || id_it->second.empty()) {
   94       return InitFailed(gadget_path);
   95     }
   96 
   97     std::string options_name, options_name_sha1;
   98     GenerateSHA1(gadget_path + "-" + id_it->second, &options_name_sha1);
   99     WebSafeEncodeBase64(options_name_sha1, false, &options_name);
  100     options_name = "standalone-" + options_name;
  101 
  102     Permissions permissions;
  103     Gadget::GetGadgetRequiredPermissions(&manifest, &permissions);
  104 
  105     if (flags_ & GRANT_PERMISSIONS)
  106       permissions.GrantAllRequired();
  107 
  108     safe_to_exit_ = false;
  109     if (!owner_->ConfirmGadget(gadget_path, options_name, gadget_path,
  110                                manifest[kManifestName],
  111                                manifest[kManifestDescription], &permissions)) {
  112       safe_to_exit_ = true;
  113       return false;
  114     }
  115     safe_to_exit_ = true;
  116 
  117     if (!LoadGadget(gadget_path.c_str(), options_name.c_str(), 0, false)) {
  118       return InitFailed(gadget_path);
  119     }
  120     return true;
  121   }
  122 
  123   Gadget *LoadGadget(const char *path, const char *options_name,
  124                      int instance_id, bool show_debug_console) {
  125     if (gadget_) {
  126       DLOG("Standalone gadget has been loaded. "
  127            "Load gadget %s in managed host.", path);
  128       return on_load_gadget_signal_(path, options_name, instance_id,
  129                                     show_debug_console);
  130     }
  131 
  132     Permissions global_permissions;
  133     global_permissions.SetGranted(Permissions::ALL_ACCESS, true);
  134 
  135     Gadget::DebugConsoleConfig dcc = show_debug_console ?
  136         Gadget::DEBUG_CONSOLE_INITIAL : debug_console_config_;
  137 
  138     safe_to_exit_ = false;
  139     gadget_ = new Gadget(owner_, path, options_name, instance_id,
  140                          global_permissions, dcc);
  141     safe_to_exit_ = true;
  142 
  143     if (!gadget_->IsValid()) {
  144       LOG("Failed to load standalone gadget %s", path);
  145       if (debug_console_)
  146         gtk_widget_destroy(debug_console_);
  147       delete gadget_;
  148       gadget_ = NULL;
  149       main_view_host_ = NULL;
  150       details_view_host_ = NULL;
  151       debug_console_ = NULL;
  152       return NULL;
  153     }
  154 
  155     gadget_->SetDisplayTarget(Gadget::TARGET_FLOATING_VIEW);
  156     gadget_->GetMainView()->OnOtherEvent(SimpleEvent(Event::EVENT_UNDOCK));
  157     gadget_->ShowMainView();
  158 
  159     // If debug console is opened during view host creation, the title is
  160     // not set then because main view is not available. Set the title now.
  161     if (debug_console_) {
  162       gtk_window_set_title(GTK_WINDOW(debug_console_),
  163                            gadget_->GetMainView()->GetCaption().c_str());
  164     }
  165     return gadget_;
  166   }
  167 
  168   ViewHostInterface *NewViewHost(Gadget *gadget,
  169                                  ViewHostInterface::Type type) {
  170     GGL_UNUSED(gadget);
  171     int vh_flags = GtkHostBase::FlagsToViewHostFlags(flags_);
  172     if (type == ViewHostInterface::VIEW_HOST_OPTIONS) {
  173       vh_flags |= (SingleViewHost::DECORATED | SingleViewHost::WM_MANAGEABLE);
  174     } else if (type == ViewHostInterface::VIEW_HOST_DETAILS) {
  175       vh_flags &= ~SingleViewHost::DECORATED;
  176     } else if (type == ViewHostInterface::VIEW_HOST_MAIN) {
  177       // Standalone gadget will always be removed if the window is closed.
  178       vh_flags |= SingleViewHost::REMOVE_ON_CLOSE;
  179       // Standalone gadget will always be managed by window manager.
  180       vh_flags |= SingleViewHost::WM_MANAGEABLE;
  181       vh_flags |= SingleViewHost::RECORD_STATES;
  182     }
  183 
  184     SingleViewHost *svh =
  185         new SingleViewHost(type, 1.0, vh_flags, view_debug_mode_);
  186 
  187     if (type == ViewHostInterface::VIEW_HOST_OPTIONS)
  188       return svh;
  189 
  190     ViewHostInterface *view_host = NULL;
  191     if (type == ViewHostInterface::VIEW_HOST_MAIN) {
  192       main_view_host_ = svh;
  193       svh->ConnectOnResized(
  194           NewSlot(this, &Impl::OnMainViewResizedHandler));
  195       svh->ConnectOnMoved(
  196           NewSlot(this, &Impl::OnMainViewMovedHandler));
  197 
  198       if (flags_ & NO_MAIN_VIEW_DECORATOR) {
  199         view_host = svh;
  200       } else {
  201         FloatingMainViewDecorator *view_decorator =
  202             new FloatingMainViewDecorator(svh, !(flags_ & NO_TRANSPARENT));
  203         view_host = new DecoratedViewHost(view_decorator);
  204         view_decorator->SetButtonVisible(
  205             MainViewDecoratorBase::POP_IN_OUT_BUTTON, false);
  206         view_decorator->ConnectOnClose(
  207             NewSlot(this, &Impl::OnMainViewCloseHandler));
  208       }
  209     } else {
  210       details_view_host_ = svh;
  211       svh->ConnectOnShowHide(
  212           NewSlot(this, &Impl::OnDetailsViewShowHideHandler));
  213       svh->ConnectOnBeginResizeDrag(
  214           NewSlot(this, &Impl::OnDetailsViewBeginResizeHandler));
  215       svh->ConnectOnResized(
  216           NewSlot(this, &Impl::OnDetailsViewResizedHandler));
  217       svh->ConnectOnBeginMoveDrag(
  218           NewSlot(this, &Impl::OnDetailsViewBeginMoveHandler));
  219 
  220       DetailsViewDecorator *view_decorator = new DetailsViewDecorator(svh);
  221       view_host = new DecoratedViewHost(view_decorator);
  222       view_decorator->ConnectOnClose(
  223           NewSlot(this, &Impl::OnDetailsViewCloseHandler));
  224     }
  225 
  226     return view_host;
  227   }
  228 
  229   void RemoveGadget(Gadget *gadget, bool save_data) {
  230     GGL_UNUSED(save_data);
  231     ASSERT(gadget && gadget == gadget_);
  232     owner_->Exit();
  233   }
  234 
  235   void OnMainViewCloseHandler() {
  236     ASSERT(gadget_);
  237     gadget_->RemoveMe(true);
  238   }
  239 
  240   void OnDetailsViewCloseHandler() {
  241     ASSERT(gadget_);
  242     gadget_->CloseDetailsView();
  243   }
  244 
  245   void AdjustViewHostPosition() {
  246     ASSERT(gadget_ && main_view_host_);
  247 
  248     int x, y;
  249     int width, height;
  250     main_view_host_->GetWindowPosition(&x, &y);
  251     main_view_host_->GetWindowSize(&width, &height);
  252 
  253     int screen_width = gdk_screen_get_width(
  254         gtk_widget_get_screen(main_view_host_->GetWindow()));
  255     int screen_height = gdk_screen_get_height(
  256         gtk_widget_get_screen(main_view_host_->GetWindow()));
  257 
  258     if (details_view_host_ && details_view_host_->IsVisible()) {
  259       int details_width, details_height;
  260       details_view_host_->GetWindowSize(&details_width, &details_height);
  261       if (details_on_right_ && details_width < x &&
  262           x + width + details_width > screen_width)
  263         details_on_right_ = false;
  264       else if (!details_on_right_ && details_width > x &&
  265                x + width + details_width < screen_width)
  266         details_on_right_ = true;
  267 
  268       if (y + details_height > screen_height)
  269         y = screen_height - details_height;
  270 
  271       if (details_on_right_) {
  272         details_view_host_->SetWindowPosition(x + width, y);
  273       } else {
  274         details_view_host_->SetWindowPosition(x - details_width, y);
  275       }
  276     }
  277   }
  278 
  279   void OnMainViewResizedHandler(int width, int height) {
  280     GGL_UNUSED(width);
  281     GGL_UNUSED(height);
  282     AdjustViewHostPosition();
  283   }
  284 
  285   void OnMainViewMovedHandler(int x, int y) {
  286     GGL_UNUSED(x);
  287     GGL_UNUSED(y);
  288     AdjustViewHostPosition();
  289   }
  290 
  291   void OnDetailsViewShowHideHandler(bool show) {
  292     if (show)
  293       AdjustViewHostPosition();
  294     else
  295       details_view_host_ = NULL;
  296   }
  297 
  298   bool OnDetailsViewBeginResizeHandler(int button, int hittest) {
  299     GGL_UNUSED(button);
  300     if (details_on_right_) {
  301       return hittest == ViewInterface::HT_LEFT ||
  302              hittest == ViewInterface::HT_TOPLEFT ||
  303              hittest == ViewInterface::HT_BOTTOMLEFT ||
  304              hittest == ViewInterface::HT_TOP ||
  305              hittest == ViewInterface::HT_TOPRIGHT;
  306     } else {
  307       return hittest == ViewInterface::HT_RIGHT ||
  308              hittest == ViewInterface::HT_TOPRIGHT ||
  309              hittest == ViewInterface::HT_BOTTOMRIGHT ||
  310              hittest == ViewInterface::HT_TOP ||
  311              hittest == ViewInterface::HT_TOPLEFT;
  312     }
  313   }
  314 
  315   void OnDetailsViewResizedHandler(int width, int height) {
  316     GGL_UNUSED(width);
  317     GGL_UNUSED(height);
  318     AdjustViewHostPosition();
  319   }
  320 
  321   bool OnDetailsViewBeginMoveHandler(int button) {
  322     GGL_UNUSED(button);
  323     // User can't move popout view window.
  324     return true;
  325   }
  326 
  327   void ShowGadgetDebugConsole(Gadget *gadget) {
  328     ASSERT(gadget && (!gadget_ || gadget == gadget_));
  329 
  330     if (!debug_console_) {
  331       debug_console_ = NewGadgetDebugConsole(gadget);
  332       g_signal_connect(debug_console_, "destroy",
  333                        G_CALLBACK(gtk_widget_destroyed), &debug_console_);
  334     }
  335   }
  336 
  337   StandaloneGtkHost *owner_;
  338   Gadget *gadget_;
  339   SingleViewHost *main_view_host_;
  340   SingleViewHost *details_view_host_;
  341   GtkWidget *debug_console_;
  342 
  343   bool details_on_right_;
  344   bool safe_to_exit_;
  345   int flags_;
  346   int view_debug_mode_;
  347   Gadget::DebugConsoleConfig debug_console_config_;
  348   std::string options_name_;
  349 
  350   Signal4<Gadget *, const char *, const char *, int, bool>
  351       on_load_gadget_signal_;
  352 };
  353 
  354 StandaloneGtkHost::StandaloneGtkHost(
  355     int flags, int view_debug_mode,
  356     Gadget::DebugConsoleConfig debug_console_config)
  357   : impl_(new Impl(this, flags, view_debug_mode, debug_console_config)) {
  358 }
  359 
  360 StandaloneGtkHost::~StandaloneGtkHost() {
  361   delete impl_;
  362   impl_ = NULL;
  363 }
  364 
  365 ViewHostInterface *StandaloneGtkHost::NewViewHost(
  366     Gadget *gadget, ViewHostInterface::Type type) {
  367   return impl_->NewViewHost(gadget, type);
  368 }
  369 
  370 Gadget *StandaloneGtkHost::LoadGadget(
  371     const char *path, const char *options_name,
  372     int instance_id, bool show_debug_console) {
  373   return impl_->LoadGadget(path, options_name, instance_id, show_debug_console);
  374 }
  375 
  376 void StandaloneGtkHost::RemoveGadget(Gadget *gadget, bool save_data) {
  377   return impl_->RemoveGadget(gadget, save_data);
  378 }
  379 
  380 void StandaloneGtkHost::ShowGadgetDebugConsole(Gadget *gadget) {
  381   impl_->ShowGadgetDebugConsole(gadget);
  382 }
  383 
  384 int StandaloneGtkHost::GetDefaultFontSize() {
  385   return kDefaultFontSize;
  386 }
  387 
  388 bool StandaloneGtkHost::Init(const std::string &gadget_path) {
  389   return impl_->Init(gadget_path);
  390 }
  391 
  392 void StandaloneGtkHost::Present() {
  393   if (impl_->main_view_host_)
  394     gtk_window_present(GTK_WINDOW(impl_->main_view_host_->GetWindow()));
  395 }
  396 
  397 Connection *StandaloneGtkHost::ConnectOnLoadGadget(
  398       ggadget::Slot4<Gadget *, const char *, const char *, int, bool> *slot) {
  399   return impl_->on_load_gadget_signal_.Connect(slot);
  400 }
  401 
  402 bool StandaloneGtkHost::IsSafeToExit() const {
  403   return impl_->safe_to_exit_ &&
  404       (!impl_->gadget_ || impl_->gadget_->IsSafeToRemove());
  405 }
  406 
  407 } // namespace gtk
  408 } // namespace hosts