Back to index

unity  6.0.0
LauncherModel.cpp
Go to the documentation of this file.
00001 // -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*-
00002 /*
00003  * Copyright (C) 2010 Canonical Ltd
00004  *
00005  * This program is free software: you can redistribute it and/or modify
00006  * it under the terms of the GNU General Public License version 3 as
00007  * published by the Free Software Foundation.
00008  *
00009  * This program is distributed in the hope that it will be useful,
00010  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012  * GNU General Public License for more details.
00013  *
00014  * You should have received a copy of the GNU General Public License
00015  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
00016  *
00017  * Authored by: Jason Smith <jason.smith@canonical.com>
00018  */
00019 
00020 #include "LauncherModel.h"
00021 #include "AbstractLauncherIcon.h"
00022 
00023 #include <UnityCore/GLibWrapper.h>
00024 #include <UnityCore/Variant.h>
00025 
00026 namespace unity
00027 {
00028 namespace launcher
00029 {
00030 
00031 LauncherModel::LauncherModel()
00032   : selection_(0)
00033 {
00034 }
00035 
00036 std::string LauncherModel::GetName() const
00037 {
00038   return "LauncherModel";
00039 }
00040 
00041 void LauncherModel::AddProperties(GVariantBuilder* builder)
00042 {
00043   unity::variant::BuilderWrapper(builder)
00044   .add("selection", selection_);
00045 }
00046 
00047 unity::debug::Introspectable::IntrospectableList LauncherModel::GetIntrospectableChildren()
00048 {
00049   introspection_results_.clear();
00050 
00051   for (auto icon : _inner)
00052     introspection_results_.push_back(icon.GetPointer());
00053 
00054   return introspection_results_;
00055 }
00056 
00057 bool LauncherModel::IconShouldShelf(AbstractLauncherIcon::Ptr icon) const
00058 {
00059   return icon->GetIconType() == AbstractLauncherIcon::TYPE_TRASH;
00060 }
00061 
00062 bool LauncherModel::CompareIcons(AbstractLauncherIcon::Ptr first, AbstractLauncherIcon::Ptr second)
00063 {
00064   if (first->GetIconType() < second->GetIconType())
00065     return true;
00066   else if (first->GetIconType() > second->GetIconType())
00067     return false;
00068 
00069   return first->SortPriority() < second->SortPriority();
00070 }
00071 
00072 bool
00073 LauncherModel::Populate()
00074 {
00075   Base copy = _inner;
00076 
00077   _inner.clear();
00078 
00079   iterator it, it2;
00080 
00081   int i = 0;
00082   for (it = main_begin(); it != main_end(); it++)
00083   {
00084     _inner.push_back(*it);
00085     (*it)->SetSortPriority(i);
00086     ++i;
00087   }
00088 
00089   for (it = shelf_begin(); it != shelf_end(); it++)
00090   {
00091     _inner.push_back(*it);
00092     (*it)->SetSortPriority(i);
00093     ++i;
00094   }
00095 
00096   return copy.size() == _inner.size() && !std::equal(begin(), end(), copy.begin());
00097 }
00098 
00099 void
00100 LauncherModel::AddIcon(AbstractLauncherIcon::Ptr icon)
00101 {
00102   if (IconShouldShelf(icon))
00103     _inner_shelf.push_back(icon);
00104   else
00105     _inner_main.push_back(icon);
00106 
00107   Sort();
00108 
00109   icon_added.emit(icon);
00110 
00111   if (icon->on_icon_removed_connection.connected())
00112     icon->on_icon_removed_connection.disconnect();
00113   icon->on_icon_removed_connection = icon->remove.connect(sigc::mem_fun(this, &LauncherModel::OnIconRemove));
00114 }
00115 
00116 void
00117 LauncherModel::RemoveIcon(AbstractLauncherIcon::Ptr icon)
00118 {
00119   size_t size;
00120 
00121   _inner_shelf.erase(std::remove(_inner_shelf.begin(), _inner_shelf.end(), icon), _inner_shelf.end());
00122   _inner_main.erase(std::remove(_inner_main.begin(), _inner_main.end(), icon), _inner_main.end());
00123 
00124   size = _inner.size();
00125   _inner.erase(std::remove(_inner.begin(), _inner.end(), icon), _inner.end());
00126 
00127   if (size != _inner.size())
00128   {
00129     icon_removed.emit(icon);
00130   }
00131 }
00132 
00133 void
00134 LauncherModel::OnIconRemove(AbstractLauncherIcon::Ptr icon)
00135 {
00136   auto timeout = std::make_shared<glib::Timeout>(1000);
00137   timeouts_.Add(timeout);
00138 
00139   timeout->Run([&, icon] {
00140     RemoveIcon(icon);
00141     return false;
00142   });
00143 }
00144 
00145 void
00146 LauncherModel::Save()
00147 {
00148   saved.emit();
00149 }
00150 
00151 void
00152 LauncherModel::Sort()
00153 {
00154   std::stable_sort(_inner_shelf.begin(), _inner_shelf.end(), &LauncherModel::CompareIcons);
00155   std::stable_sort(_inner_main.begin(), _inner_main.end(), &LauncherModel::CompareIcons);
00156 
00157   if (Populate())
00158     order_changed.emit();
00159 }
00160 
00161 bool
00162 LauncherModel::IconHasSister(AbstractLauncherIcon::Ptr icon) const
00163 {
00164   const_iterator it;
00165   const_iterator end;
00166 
00167   if (icon && icon->GetIconType() == AbstractLauncherIcon::TYPE_DEVICE)
00168     return true;
00169 
00170   if (IconShouldShelf(icon))
00171   {
00172     it = _inner_shelf.begin();
00173     end = _inner_shelf.end();
00174   }
00175   else
00176   {
00177     it = _inner_main.begin();
00178     end = _inner_main.end();
00179   }
00180 
00181   for (; it != end; ++it)
00182   {
00183     AbstractLauncherIcon::Ptr iter_icon = *it;
00184     if ((iter_icon  != icon)
00185         && iter_icon->GetIconType() == icon->GetIconType())
00186       return true;
00187   }
00188 
00189   return false;
00190 }
00191 
00192 void
00193 LauncherModel::ReorderAfter(AbstractLauncherIcon::Ptr icon, AbstractLauncherIcon::Ptr other)
00194 {
00195   if (icon == other || icon.IsNull() || other.IsNull())
00196     return;
00197 
00198   if (icon->GetIconType() != other->GetIconType())
00199     return;
00200 
00201   int i = 0;
00202   for (LauncherModel::iterator it = begin(); it != end(); ++it)
00203   {
00204     if ((*it) == icon)
00205       continue;
00206 
00207     if ((*it) == other)
00208     {
00209       (*it)->SetSortPriority(i);
00210       ++i;
00211 
00212       icon->SetSortPriority(i);
00213       ++i;
00214     }
00215     else
00216     {
00217       (*it)->SetSortPriority(i);
00218       ++i;
00219     }
00220   }
00221 
00222   Sort();
00223 }
00224 
00225 void
00226 LauncherModel::ReorderBefore(AbstractLauncherIcon::Ptr icon, AbstractLauncherIcon::Ptr other, bool save)
00227 {
00228   if (icon == other || icon.IsNull() || other.IsNull())
00229     return;
00230 
00231   if (icon->GetIconType() != other->GetIconType())
00232     return;
00233 
00234   int i = 0;
00235   int j = 0;
00236   for (auto icon_it : _inner)
00237   {
00238     if (icon_it == icon)
00239     {
00240       j++;
00241       continue;
00242     }
00243 
00244     if (icon_it == other)
00245     {
00246       icon->SetSortPriority(i);
00247       if (i != j && save)
00248         icon_it->SaveCenter();
00249       i++;
00250 
00251       icon_it->SetSortPriority(i);
00252       if (i != j && save)
00253         icon_it->SaveCenter();
00254       i++;
00255     }
00256     else
00257     {
00258       icon_it->SetSortPriority(i);
00259       if (i != j && save)
00260         icon_it->SaveCenter();
00261       i++;
00262     }
00263     j++;
00264   }
00265 
00266   Sort();
00267 }
00268 
00269 void
00270 LauncherModel::ReorderSmart(AbstractLauncherIcon::Ptr icon, AbstractLauncherIcon::Ptr other, bool save)
00271 {
00272   if (icon == other || icon.IsNull() || other.IsNull())
00273     return;
00274 
00275   if (icon->GetIconType() != other->GetIconType())
00276     return;
00277 
00278   int i = 0;
00279   int j = 0;
00280   bool skipped = false;
00281   for (auto icon_it : _inner)
00282   {
00283     if (icon_it == icon)
00284     {
00285       skipped = true;
00286       j++;
00287       continue;
00288     }
00289 
00290     if (icon_it == other)
00291     {
00292       if (!skipped)
00293       {
00294         icon->SetSortPriority(i);
00295         if (i != j && save)
00296           icon_it->SaveCenter();
00297         i++;
00298       }
00299 
00300       icon_it->SetSortPriority(i);
00301       if (i != j && save)
00302         icon_it->SaveCenter();
00303       i++;
00304 
00305       if (skipped)
00306       {
00307         icon->SetSortPriority(i);
00308         if (i != j && save)
00309           icon_it->SaveCenter();
00310         i++;
00311       }
00312     }
00313     else
00314     {
00315       icon_it->SetSortPriority(i);
00316       if (i != j && save)
00317         icon_it->SaveCenter();
00318       i++;
00319     }
00320     j++;
00321   }
00322 
00323   Sort();
00324 }
00325 
00326 int
00327 LauncherModel::Size() const
00328 {
00329   return _inner.size();
00330 }
00331 
00332 AbstractLauncherIcon::Ptr LauncherModel::Selection () const
00333 {
00334   return _inner[selection_];
00335 }
00336 
00337 int LauncherModel::SelectionIndex() const
00338 {
00339   return selection_;
00340 }
00341 
00342 void LauncherModel::SetSelection(int selection)
00343 {
00344   int new_selection = std::min<int>(Size() - 1, std::max<int> (0, selection));
00345 
00346   if (new_selection == selection_)
00347     return;
00348 
00349   selection_ = new_selection;
00350   selection_changed.emit(Selection());
00351 }
00352 
00353 void LauncherModel::SelectNext()
00354 {
00355   int temp = selection_;
00356 
00357   temp++;
00358   while (temp != selection_)
00359   {
00360     if (temp >= Size())
00361       temp = 0;
00362 
00363     if (_inner[temp]->GetQuirk(AbstractLauncherIcon::QUIRK_VISIBLE))
00364     {
00365       selection_ = temp;
00366       selection_changed.emit(Selection());
00367       break;
00368     }
00369     temp++;
00370   }
00371 }
00372 
00373 void LauncherModel::SelectPrevious()
00374 {
00375   int temp = selection_;
00376 
00377   temp--;
00378   while (temp != selection_)
00379   {
00380     if (temp < 0)
00381       temp = Size() - 1;
00382 
00383     if (_inner[temp]->GetQuirk(AbstractLauncherIcon::QUIRK_VISIBLE))
00384     {
00385       selection_ = temp;
00386       selection_changed.emit(Selection());
00387       break;
00388     }
00389     temp--;
00390   }
00391 }
00392 
00393 
00394 /* iterators */
00395 
00396 LauncherModel::iterator
00397 LauncherModel::begin()
00398 {
00399   return _inner.begin();
00400 }
00401 
00402 LauncherModel::iterator
00403 LauncherModel::end()
00404 {
00405   return _inner.end();
00406 }
00407 
00408 LauncherModel::iterator
00409 LauncherModel::at(int index)
00410 {
00411   LauncherModel::iterator it;
00412   int i;
00413 
00414   // start currently selected icon
00415   for (it = _inner.begin(), i = 0; it != _inner.end(); it++, i++)
00416   {
00417     if (i == index)
00418       return it;
00419   }
00420 
00421   return (LauncherModel::iterator)NULL;
00422 }
00423 
00424 LauncherModel::reverse_iterator
00425 LauncherModel::rbegin()
00426 {
00427   return _inner.rbegin();
00428 }
00429 
00430 LauncherModel::reverse_iterator
00431 LauncherModel::rend()
00432 {
00433   return _inner.rend();
00434 }
00435 
00436 LauncherModel::iterator
00437 LauncherModel::main_begin()
00438 {
00439   return _inner_main.begin();
00440 }
00441 
00442 LauncherModel::iterator
00443 LauncherModel::main_end()
00444 {
00445   return _inner_main.end();
00446 }
00447 
00448 LauncherModel::reverse_iterator
00449 LauncherModel::main_rbegin()
00450 {
00451   return _inner_main.rbegin();
00452 }
00453 
00454 LauncherModel::reverse_iterator
00455 LauncherModel::main_rend()
00456 {
00457   return _inner_main.rend();
00458 }
00459 
00460 LauncherModel::iterator
00461 LauncherModel::shelf_begin()
00462 {
00463   return _inner_shelf.begin();
00464 }
00465 
00466 LauncherModel::iterator
00467 LauncherModel::shelf_end()
00468 {
00469   return _inner_shelf.end();
00470 }
00471 
00472 LauncherModel::reverse_iterator
00473 LauncherModel::shelf_rbegin()
00474 {
00475   return _inner_shelf.rbegin();
00476 }
00477 
00478 LauncherModel::reverse_iterator
00479 LauncherModel::shelf_rend()
00480 {
00481   return _inner_shelf.rend();
00482 }
00483 
00484 } // namespace launcher
00485 } // namespace unity